SpringCloud中怎么使用OAuth2.0實(shí)現(xiàn)鑒權(quán)

本篇文章給大家分享的是有關(guān)SpringCloud中怎么使用OAuth2.0實(shí)現(xiàn)鑒權(quán),小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

10年積累的成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先建設(shè)網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有龍馬潭免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

SpringSecurity

Spring Security是一個(gè)功能強(qiáng)大、高度可定制的身份驗(yàn)證和訪問控制框架。它用于保護(hù)基于Spring的應(yīng)用程序。Spring Security是一個(gè)專注于向Java應(yīng)用程序提供身份驗(yàn)證和授權(quán)的框架。 與所有Spring項(xiàng)目一樣,Spring安全的真正威力在于它可以很容易地?cái)U(kuò)展以滿足定制需求。

OAuth3.0

OAuth 2.0是用于授權(quán)的行業(yè)標(biāo)準(zhǔn)協(xié)議。OAuth3.0注重客戶端開發(fā)人員的簡單性,同時(shí)為Web應(yīng)用程序、桌面應(yīng)用程序、移動(dòng)電話和客廳設(shè)備提供特定的授權(quán)流。 更多請(qǐng)參考 OAuth3.0

OAuth3.0模式

模式應(yīng)用場(chǎng)景描述
授權(quán)碼(Auth Code)成功后跳轉(zhuǎn)其他頁面,如第三方微信登錄等
簡化模式(implicit)不通過第三方應(yīng)用程序的服務(wù)器,直接在瀏覽器中向認(rèn)證服務(wù)器申請(qǐng)令牌
密碼模式(password credentials)web頁面用戶名密碼登錄
客戶端模式(client credentials)主要針對(duì)openapi,使用apikey和secretkey方式
JWT

JSON Web Token(縮寫 JWT)是目前最流行的跨域認(rèn)證解決方案。更多請(qǐng)參考 JWT入門教程

2、前期必備

核心pom依賴如下:

<!-- 注意是starter,自動(dòng)配置 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- 不是starter,手動(dòng)配置 -->
<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth3</artifactId>
    <version>2.3.6.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 將token存儲(chǔ)在redis中 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

創(chuàng)建一個(gè)rest接口用于后面測(cè)試資源

@Slf4j
@RestController
public class TestSecurityController {
    @GetMapping("/product/{id}")
    public String getProduct(@PathVariable String id) {
        //for debug
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "product id : " + id;
    }

    @GetMapping("/order/{id}")
    public String getOrder(@PathVariable String id) {
        //for debug
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "order id : " + id;
    }
}

3、操作步驟

很多文章寫的特別復(fù)雜,其實(shí)主要的內(nèi)容也就分為下面幾步

3.1、授權(quán)服務(wù)器AuthorizationServerConfigurerAdapter

需要自定義授權(quán)服務(wù)器,繼承AuthorizationServerConfigurerAdapter,詳細(xì)代碼如下

@Configuration
@EnableAuthorizationServer
public   class AuthServerConfiguration extends AuthorizationServerConfigurerAdapter {
    private static final String DEMO_RESOURCE_ID = "order";

    @Autowired
    AuthenticationManager authenticationManager;
    @Autowired
    RedisConnectionFactory redisConnectionFactory;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //配置兩個(gè)客戶端,一個(gè)用于password認(rèn)證一個(gè)用于client認(rèn)證
        String secret = new BCryptPasswordEncoder().encode("123456");////對(duì)密碼進(jìn)行加密
        clients.inMemory().withClient("client_1")
                .resourceIds(DEMO_RESOURCE_ID)
                .authorizedGrantTypes("client_credentials", "refresh_token")
                .scopes("select")
                .authorities("client")
                .secret(secret)
                .and().withClient("client_2")
                .resourceIds(DEMO_RESOURCE_ID)
                .authorizedGrantTypes("password", "refresh_token")
                .scopes("select")
                .authorities("client")
                .secret(secret);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .tokenStore(new RedisTokenStore(redisConnectionFactory))
                .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        //允許表單認(rèn)證
        oauthServer.allowFormAuthenticationForClients();
    }

}

3.2、資源服務(wù)器ResourceServerConfigurerAdapter

同上,需要實(shí)現(xiàn)自己的資源服務(wù)器,繼承ResourceServerConfigurerAdapter,詳細(xì)代碼如下

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    private static final String DEMO_RESOURCE_ID = "order";
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(DEMO_RESOURCE_ID).stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                // Since we want the protected resources to be accessible in the UI as well we need
                // session creation to be allowed (it's disabled by default in 2.0.6)
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and()
                .requestMatchers().anyRequest()
                .and()
                .anonymous()
                .and()
                .authorizeRequests()
//                    .antMatchers("/product/**").access("#oauth3.hasScope('select') and hasRole('ROLE_USER')")
                .antMatchers("/order/**").authenticated();//配置order訪問控制,必須認(rèn)證過后才可以訪問
        // @formatter:on
    }
}

3.3、配置SpringSecurity

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        String pwd = new BCryptPasswordEncoder().encode("123456");//對(duì)密碼進(jìn)行加密
        manager.createUser(User.withUsername("user_1").password(pwd).authorities("USER").build());
        manager.createUser(User.withUsername("user_2").password(pwd).authorities("USER").build());
        return manager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .requestMatchers().anyRequest()
                .and()
                .authorizeRequests()
                .antMatchers("/oauth/*").permitAll();
    }
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        AuthenticationManager manager = super.authenticationManagerBean();
        return manager;
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

4、測(cè)試

我們?cè)O(shè)計(jì)的是product服務(wù)可以匿名訪問,而order服務(wù)需要簽名才可以訪問,驗(yàn)證如下:

  • password模式 利用postman進(jìn)行post訪問http://localhost:8080/oauth/token?username=user_1&password=123456&grant_type=password&scope=select&client_id=client_2&client_secret=123456 獲取如下結(jié)果

{
    "access_token": "c2340190-48f3-4291-bb17-1e4d51bcb284",
    "token_type": "bearer",
    "refresh_token": "03ee113c-a942-452a-9918-7ffe24472a7f",
    "expires_in": 40399,
    "scope": "select"
}

SpringCloud中怎么使用OAuth2.0實(shí)現(xiàn)鑒權(quán)

  • client模式 同樣利用postman的POST方式訪問http://localhost:8080/oauth/token?grant_type=client_credentials&scope=select&client_id=client_1&client_secret=123456 結(jié)果如下

{
    "access_token": "05a4e614-f34b-4c83-9ec1-89ea55c0afd2",
    "token_type": "bearer",
    "expires_in": 40396,
    "scope": "select"
}

SpringCloud中怎么使用OAuth2.0實(shí)現(xiàn)鑒權(quán)

對(duì)資源進(jìn)行訪問
  • product服務(wù):訪問http://localhost:8080/product/1得到如下數(shù)據(jù)
    product id : 1

  • order服務(wù):訪問http://localhost:8080/order/1,返回?cái)?shù)據(jù)如下

<oauth>
<error_description>
Full authentication is required to access this resource
</error_description>
<error>unauthorized</error>
</oauth>

驗(yàn)證結(jié)果,說明order服務(wù)需要簽名才可以訪問,接下來,我們輸入簽名訪問order服務(wù)。 我們分別利用上面password模式獲取的token,訪問 http://localhost:8080/order/1?access_token=c2340190-48f3-4291-bb17-1e4d51bcb284 得到數(shù)據(jù) order id : 1

通用利用client模式獲取的token,訪問 http://localhost:8080/order/1?access_token=05a4e614-f34b-4c83-9ec1-89ea55c0afd2 同樣可以得到 order id : 1

以上就是SpringCloud中怎么使用OAuth2.0實(shí)現(xiàn)鑒權(quán),小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章名稱:SpringCloud中怎么使用OAuth2.0實(shí)現(xiàn)鑒權(quán)
標(biāo)題URL:http://muchs.cn/article42/jopgec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化定制開發(fā)、建站公司、小程序開發(fā)、網(wǎng)站內(nèi)鏈品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)