Spring Security + OAuth2.0 構建微服務統一認證解決方案(三)


搭建過程可以分為以下幾步

  1. 構建簡單的Spring Security + OAuth2.0 認證服務
  2. 優化認證服務(使用JWT技術加強token,自定義auth接口以及返回結果)
  3. 配置gateway服務完成簡單鑒權功能
  4. 優化gateway配置(添加復雜鑒權邏輯等等)

(三)配置gateway服務完成JWT簡單鑒權功能

之前的網關服務僅僅用做請求的路由轉發。現在對網關服務進行,對請求中攜帶的token進行鑒權。

一. 配置相關依賴

導入spring security和oauth相關依賴,以及JWT相關依賴

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
 
<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>9.10.1</version>
</dependency>

要注意的是導入 nimbus-jose-jwt 這個包時,在啟動時可能會出現沖突的奇怪問題,詳情如下(當時用的是8.17版本)

更新包版本,換成9.10.1就沒這個問題了

二. 配置JWT解碼需要的公鑰獲取接口

之前在Auth服務中用私鑰在JWT中創建了簽名,由此我們在驗證時需要用公鑰對Token進行驗證,防止偽造Token。

Auth服務提供公鑰接口

在Auth服務中,由於之前創建好了RSA 密鑰的 KeyPair 的 Bean,可以很方便地創建一個接口返回公鑰信息

@RestController
public class RSAController {
 
    @Autowired
    private KeyPair keyPair;
 
    @GetMapping("/rsa/publicKey")
    public Map<String, Object> getKey() {
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAKey key = new RSAKey.Builder(publicKey).build();
        return new JWKSet(key).toJSONObject();
    }
}

也要記得在spring security的配置中放開權限

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 放開接口權限
                .antMatchers("/rsa/publicKey").permitAll()
                .anyRequest().authenticated();
    }
    ......
}

gateway服務配置公鑰獲取url

在yaml中進行配置即可,之后配置好JWT解碼,框架會自動去請求公鑰驗證

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: 'http://localhost:8401/rsa/publicKey'

三. 啟用JWT驗證

使用 @EnableWebFluxSecurity 注解開啟 WebFlux
在config中啟用jwt驗證

@Configuration
@EnableWebFluxSecurity
public class ResourceServerConfig {
 
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        // 開啟jwt驗證
        http.oauth2ResourceServer().jwt();
        return http.build();
    }
}

四. 測試結果

1) 放入之前過期的accessToken請求某接口
這里的Token前綴加上了“Bearer ”,用於定義該Authorization的規范。可以看到結果返回401,錯誤信息是因為token過期

2)放入錯誤token
從之前Token中刪去一些字符使其失效,再次請求
可以看到返回401,錯誤信息是token無效,解析失敗。

3)放入正確Token
新生成一個token,放入Authorization字段中進行請求,看到通過了校驗,可以正常路由並返回結果

五. 后續工作

這只是一個超級簡單的gateway鑒權,且只有Authorization字段前綴為“Bearer ”時才開啟校驗,否則不校驗。
如下,隨便輸入字符串也可以得到結果。

由此,后續可以將鑒權邏輯進行優化

  • 增加篩選,將Authorization字段前綴非“Bearer ”開頭的請求攔截
  • OPTIONS(預檢)請求和白名單路徑直接放行
  • 給URL設置用戶訪問權限並校驗
  • 添加自定義gateway filter

Spring Security + OAuth2.0 構建微服務統一認證解決方案(一)
Spring Security + OAuth2.0 構建微服務統一認證解決方案(二)
Spring Security + OAuth2.0 構建微服務統一認證解決方案(四)
github 倉庫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM