Spring Security 與 OAuth2(資源服務(wù)器)

個人 OAuth2 全部文章

resource-server(資源服務(wù)器)

資源服務(wù)器

  • 要訪問資源服務(wù)器受保護的資源需要攜帶令牌(從授權(quán)服務(wù)器獲得)
  • 客戶端往往同時也是一個資源服務(wù)器,各個服務(wù)之間的通信(訪問需要權(quán)限的資源)時需攜帶訪問令牌
  • 資源服務(wù)器通過 @EnableResourceServer 注解來開啟一個 OAuth2AuthenticationProcessingFilter 類型的過濾器
  • 通過繼承 ResourceServerConfigurerAdapter 類來配置資源服務(wù)器

ResourceServerProperties

  • OAuth2 為資源服務(wù)器配置提供了 ResourceServerProperties 類,該類會讀取配置文件中對資源服務(wù)器得配置信息(如授權(quán)服務(wù)器公鑰訪問地址)

ResourceServerSecurityConfigurer 可配置屬性

  • tokenServices:ResourceServerTokenServices 類的實例,用來實現(xiàn)令牌業(yè)務(wù)邏輯服務(wù)
  • resourceId:這個資源服務(wù)的ID,這個屬性是可選的,但是推薦設(shè)置并在授權(quán)服務(wù)中進行驗證
  • tokenExtractor 令牌提取器用來提取請求中的令牌
  • 請求匹配器,用來設(shè)置需要進行保護的資源路徑,默認的情況下是受保護資源服務(wù)的全部路徑
  • 受保護資源的訪問規(guī)則,默認的規(guī)則是簡單的身份驗證(plain authenticated)
  • 其他的自定義權(quán)限保護規(guī)則通過 HttpSecurity 來進行配置

解析令牌方法:

  • 使用 DefaultTokenServices 在資源服務(wù)器本地配置令牌存儲、解碼、解析方式
  • 使用 RemoteTokenServices 資源服務(wù)器通過 HTTP 請求來解碼令牌,每次都請求授權(quán)服務(wù)器端點 /oauth/check_token
  • 若授權(quán)服務(wù)器是 JWT 非對稱加密,則需要請求授權(quán)服務(wù)器的 /oauth/token_key 來獲取公鑰 key 進行解碼

代碼案例

令牌解析(JWT 對稱加密)

資源服務(wù)器和授權(quán)服務(wù)器不在同一個應(yīng)用,則需告訴資源服務(wù)器令牌如何存儲與解析,并與授權(quán)服務(wù)器使用相同的密鑰進行解密

@Configuration
@EnableResourceServer
public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter{
    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    //與授權(quán)服務(wù)器使用共同的密鑰進行解析
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("123");
        return converter;
    }
}

令牌解析(JWT 非對稱加密)

  • 非對稱加密需要公鑰,可以從本地獲取,也可以從授權(quán)服務(wù)器提供的公鑰端點獲取
  • 若本地獲取不到公鑰資源文件 pubkey.txt 則從授權(quán)服務(wù)器端點獲取
@Configuration
@EnableResourceServer
public class OAuth2ResourceConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private ResourceServerProperties resourceServerProperties;

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        //設(shè)置用于解碼的非對稱加密的公鑰
        converter.setVerifierKey(getPubKey());
        return converter;
    }

    private String getPubKey() {
        Resource resource = new ClassPathResource("pubkey.txt");
        try (BufferedReader br = new BufferedReader(new InputStreamReader(resource.getInputStream()))) {
            System.out.println("本地公鑰");
            return br.lines().collect(Collectors.joining("\n"));
        } catch (IOException ioe) {
            return getKeyFromAuthorizationServer();
        }
    }

    private String getKeyFromAuthorizationServer() {
        ObjectMapper objectMapper = new ObjectMapper();
        String pubKey = new RestTemplate().getForObject(resourceServerProperties.getJwt().getKeyUri(), String.class);
        try {
            Map map = objectMapper.readValue(pubKey, Map.class);
            System.out.println("聯(lián)網(wǎng)公鑰");
            return map.get("value").toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    
}

令牌解析(通過訪問授權(quán)服務(wù)器解析令牌-適用 JDBC、內(nèi)存存儲)

  • 資源服務(wù)器通過訪問授權(quán)服務(wù)器 /oauth/check_token 端點解析令牌需要使用 RemoteTokenServices
  • 并且使用 DefaultAccessTokenConverter 來實現(xiàn)令牌數(shù)據(jù)的存儲
    @Autowired
    private OAuth2ClientProperties oAuth2ClientProperties;

    @Autowired
    private AuthorizationServerProperties authorizationServerProperties;

    @Bean
    public ResourceServerTokenServices tokenServices() {
        RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
        remoteTokenServices.setCheckTokenEndpointUrl(authorizationServerProperties.getCheckTokenAccess());
        remoteTokenServices.setClientId(oAuth2ClientProperties.getClientId());
        remoteTokenServices.setClientSecret(oAuth2ClientProperties.getClientSecret());
        remoteTokenServices.setAccessTokenConverter(accessTokenConverter());
        return remoteTokenServices;
    }

    @Bean
    public AccessTokenConverter accessTokenConverter() {
        return new DefaultAccessTokenConverter();
    }

  • 修改配置文件
security:
  oauth2:
    client:
      clientId: resource1
      clientSecret: secret
      userAuthorizationUri: http://localhost:9005/oauth/authorize
      grant-type: password
      scope: read
      access-token-uri: http://localhost:9005/oauth/token
    resource:
      userInfoUri: http://localhost:9005/user
    authorization:
      check-token-access: http://localhost:9005/oauth/check_token
  basic:
    enabled: false
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,316評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,481評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,241評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,939評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,697評論 6 409
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,182評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,247評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,406評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,933評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,772評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,973評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,516評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,638評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,866評論 1 285
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,644評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,953評論 2 373