天天看點

SpringSecurity學習筆記之 入門 七 (oauth2.0整合【Security實作oauth2.0】)

SpringSecurity學習筆記之 入門 七 (oauth2.0整合【Security實作oauth2.0】)

授權碼模式:

1.需要提供appid和app密碼

2.配置回調位址

3.驗證token接口

實作流程:

1.引入必要依賴:

security
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
oauth2
<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>
jwt
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
           

2.修改security配置

完成這個部分(攔截+使用者校驗部分)

SpringSecurity學習筆記之 入門 七 (oauth2.0整合【Security實作oauth2.0】)

新增授權類

AuthorizationConfig

繼承

AuthorizationServerConfigurerAdapter

重寫他的兩個配置方法,

在類中注入我們配置好的加密類:

@Component
@EnableAuthorizationServer
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter{
	@Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    }
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    }
}
           

AuthorizationServerSecurityConfigurer

參數的方法中配置允許表單送出

@Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients().checkTokenAccess("permitAll()");
    }
           

ClientDetailsServiceConfigurer

參數的方法中配置

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
            //appid
            .withClient("gaga")
            //appsecret
            .secret(passwordEncoder.encode("gaga_test_security"))
            //授權碼
            .authorizedGrantTypes("authorization_code")
            //作用域
            .scopes("all")
            //資源id
            .resourceIds("employed_resource")
            //回調位址
            .redirectUris("127.0.0.1:18001/callback");
}
           

在實際開發中我們會将這些資料儲存于DB,當後端認證通過以後執行這個方法的時候我們動态的查詢資料庫,将資訊寫入,類似權限添加部分;

這就完成了;

認證:

當我們通路

http://127.0.0.1:18001/oauth/authorize?client_id=

employed

&response_type=code

SpringSecurity學習筆記之 入門 七 (oauth2.0整合【Security實作oauth2.0】)

client_id寫上自己的appid,type=code;

  1. 當我們通路的時候如果沒有登入會提示我們登入;當我們登入成功後就會提示我們是否願意讓上面我們配置的

    appid

    的用戶端擷取我們的

    資料資訊

  2. 當點選同意擷取的時候,頁面就會重定向到我們指定的回調函數,并且後面附帶一個參數,授權碼;
  3. 這時候我們背景就能通過回調位址擷取到授權碼,根據授權碼生成Token
  4. 根據授權碼擷取acccessToken;通路:

    http://127.0.0.1:18001/oauth/token?code=

    授權碼

    &grant_type=authorization_code&redirect_url=http://127.0.0.1:18001/callback&scope=all

    對應我們配置中的每一條配置;
  5. 這時候又會讓我們登入,但是這時候是需要用

    appid的賬戶和密碼

    進行登入,并

    不是使用者

    ;意思就是我們

    商家用戶端

    拿到了

    使用者的授權

    以後,用授權碼換取token,這時候需要我們

    商家

    亮明身份換取

    token

  6. 實際中就是我們拿到

    使用者授權碼

    ,以

    商家

    的身份換取

    使用者

    token

    ;注意需要

    post

    方法,認證方法選擇

    basic

    ,提供賬号密碼進行請求;就能擷取到token
{
    "access_token": "9455a88a-f6c7-4916-bf51-4d5c054153c4",
    "token_type": "bearer",
    "expires_in": 43050,
    "scope": "all"
}
           
  1. oauth伺服器

    拿到了token我們就可以去調用在我們這個中心注冊了的

    商家的接口

小結:大緻思路就是當

1.

第三方

軟體請求聯合登入的時候,會拉起

主應用

2.

主應用

向伺服器申請一個

特殊的token[

未登入提示登入],

3.然後

token

交給

第三方應用

4.

第三方應用

拿着

token

就可以向

主應用的伺服器

請求

使用者資源

;[第三方應用未登入也要提示登入,也就是提供合作時我們分發的

appid

密鑰

]

資源服務保護的配置:

在我們需要保護資源的服務中建立一個資源服務配置類

ResurceConifg

繼承

ResourceServerConfigurerAdapter

類;

注入兩個參數,appid以及密鑰;後續需要db查詢

,配置了這個的服務在被請求時必須帶上簽發的正确token才行;

@Configuration//啟用配置
@EnableResourceServer//啟用資源服務
public class ResurceConifg extends ResourceServerConfigurerAdapter {

    private String appid = "employed";//這裡後續需要從資料庫中查詢周遊用下面的方法填入記憶體
    private String appSecret = "employed_test_security";//這裡後續需要從資料庫中查詢周遊用下面的方法填入記憶體

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

    @Primary
    @Bean
    public RemoteTokenServices remoteTokenServices() {
        //這裡後續需要從資料庫中查詢周遊用下面的方法填入記憶體
        final RemoteTokenServices tokenServices = new RemoteTokenServices();
        //設定授權伺服器check_token的端點完整位址
        tokenServices.setCheckTokenEndpointUrl("http://127.0.0.1:18001/oauth/check_token");
        //設定用戶端id與secret,這裡的secret不能使用加密!
        tokenServices.setClientId(appid);
        tokenServices.setClientSecret(appSecret);
        return tokenServices;
    }


    @Override
    public void configure(HttpSecurity http) throws Exception {
        //設定建立session政策.設定請求後;
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
        //@formatter:off
        //設定所有請求都必須授權
        http.authorizeRequests()
                .anyRequest().authenticated();
        //@formatter:on

    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        //設定保護的資源,這個資源就是注冊在我們oauth伺服器記憶體中個各個商家的資源id,這個服務中要配置好這個才能保護; 
        resources.resourceId("employed_resource").stateless(true);
    }
}
           

http://127.0.0.1:18081/oauth/check_token?token=14d20998-864f-4eb7-9ca8-af1c86fbc1da

總結:

  1. 先向

    已登入

    使用者索取同意操作,使用者同意之後會以使用者的身份頒布一個授權碼;
  2. 第三方平台

    拿着

    授權碼

    ,向授權伺服器申請token;
  3. 第三方平台使用

    accessToken

    就可以向

    授權伺服器管轄的

    使用者

    個人資源伺服器

    請求資料,擷取使用者資訊
  4. 第三方平台就可以根據使用者資訊進行登入或者注冊操作;
  5. 補充:資源釋出的時候會給自己指定一個資源id,而第三方進行accsesToken申請的時候也會指定一個資源id(數組),是以隻能通路與之比對的對應資源

誤區:

之前一直以為是向授權伺服器拿到token以後就可以用token通路第三方的資源了,正覺得奇怪,豈不是每次token都需要授權伺服器來解密?

你要是頭鐵這麼做也能用 ,

原來資源伺服器并不是代表着第三方平台

,而是代表着

受開放平台管理

使用者資源

我開始還以為資源伺服器就是第三方,第三方token經過授權伺服器的驗證後就可以請求第三方的接口;昨天測試的時候直接就把這個token放到業務代碼裡去了

感謝這個老哥的圖解,一下就明白了,碰巧查資源id的時候看到的圖

Spring Security OAuth2之resource_id配置與驗證

想法:

由于一開始的不了解,是以也想了一些替代方法,這邊記錄一下,說不定會派上用場,第三方可以直接使用token進行替代使用者登入,隻是登入以後另外頒發一個使用者的專屬token然後就不用授權伺服器的token了。。token失效以後再重新擷取;