保護微服務(Spring Cloud Security和OAuth2.0)

源碼:Securing your Microservices

一、使用Spring和OAuth2來保護單個端點

1.建立驗證服務

構建依賴項:
在這裏插入圖片描述
在這裏插入圖片描述

2.使用OAuth2.0服務註冊客戶端應用程序

小筆記:驗證與授權,驗證是看他是誰,授權是可以讓他幹些什麼,所以授權之前肯定是要先驗證的。
在這裏插入圖片描述

3.配置用戶

在這裏插入圖片描述
上面兩個返回的bean,就是在這裏注入的:
在這裏插入圖片描述

4.驗證用戶

先把配置服務搞一下。
在這裏插入圖片描述
新建User表。
在這裏插入圖片描述
啓動順序:Eureka->配置服務->驗證服務(端口號設一下:8901)
需要注意的幾點:
在這裏插入圖片描述
在這裏插入圖片描述
返回的結果是:

{
    "access_token": "96040f35-8b10-491d-a82b-1c1a835ba632",
    "token_type": "bearer",
    "refresh_token": "f933f8b1-cace-4a1a-bc75-ff7b58b37d3d",
    "expires_in": 43199,
    "scope": "webclient"
}

然後拿着token去驗證這個用戶:
在這裏插入圖片描述
返回的結果:

{
    "user": {
        "password": null,
        "username": "john.carnell",
        "authorities": [
            {
                "authority": "ROLE_USER"
            }
        ],
        "accountNonExpired": true,
        "accountNonLocked": true,
        "credentialsNonExpired": true,
        "enabled": true
    },
    "authorities": [
        "ROLE_USER"
    ]
}

二、使用Oauth2保護組織服務

1.POM依賴

<dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-security</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.security.oauth</groupId>
          <artifactId>spring-security-oauth2</artifactId>
      </dependency>

2.配置服務以指向OAuth2驗證服務

在這裏插入圖片描述
然後將引導類設爲受保護資源:
在這裏插入圖片描述
它會強制執行一個過濾器,該過濾器就是來檢查調用的HTTP首部中是否存在OAuth2訪問令牌,然後調用剛纔填寫的回調地址驗證它是不是有效的。得知它是有效的之後,還會應用定義好的任何訪問控制規則,以控制什麼人可以訪問什麼服務。

3.定義誰可以訪問服務

訪問規則可以按照標準設置的非常細,這裏只討論兩個。

  • 只有通過驗證的用戶才能訪問服務URL
  • 只有具有特定角色的用戶才能訪問服務URL
(1)通過驗證用戶保護服務

在這裏插入圖片描述
組織服務定爲8085。先運行一下,如果訪問的時候不帶令牌的話,會直接收到401錯誤。
在這裏插入圖片描述
然後我們把令牌帶上,發現就可以了。
在這裏插入圖片描述
把Zuul開起來再試試:
在這裏插入圖片描述
沒毛病。

(2)通過特定角色保護服務

接下來會鎖定組織服務的DELETE調用,只讓有ADMIN訪問權限的人使用。注意這條以及下面的hasRole(“ADMIN”):
在這裏插入圖片描述
最後兩句還是定義了其他端點都需要被授權。
如果我們用普通用戶登錄的令牌去刪除的話,就會收到403
在這裏插入圖片描述
而如果用admin的話,則收到204成功。
在這裏插入圖片描述
數據庫裏看一下,果然被刪了。
在這裏插入圖片描述

4.傳播OAuth2訪問令牌

像上一章一樣,微服務是在調用微服務的,如果我訪問了微服務A,帶着令牌,微服務A自己又調用了微服務B,如果B也受資源保護的話,那麼這個令牌也是要自動帶上的。這一小節就是爲了解決這個問題。
在開啓了Zuul網關的情況下,實現這些要做兩件事:

(1)修改Zuul服務網關

在配置服務裏對Zuul做以下配置:

zuul.sensitiveHeaders: Cookie,Set-Cookie

這個配置是黑名單的意思,沒在這個上面的,都會傳播到下一層服務,Authorition不再這個上面,所以會傳播。

(2)許可證服務配置以及更改

我們就倆主要服務,而且傳播都是許可證到組織的,這個很好理解。
基本的授權就不說了,直接說怎麼傳播令牌:
在這裏插入圖片描述
在這裏插入圖片描述

三、JSON Web Token 與OAuth2

OAuth2作爲驗證框架,沒有標準,比較搞笑,JWT是後來矯正OAuth2的標準,JWT具有以下特點:

  • 小巧-- base64,直接http傳遞
  • 密碼簽名–JWT令牌由頒發它的驗證服務器簽名,可以保證其沒有被篡改。
  • 自包含–由於JWT令牌是密碼簽名的,所以接受該服務的微服務可以保證令牌的內容是有效的(驗證就是爲了驗證其是否有效嘛~),因此,不需要調用驗證服務就可以來確認令牌的內容
  • 可擴展–當驗證服務生成一個令牌時,它可以在加密之前放入額外的信息。
    Spring cloud爲JWT提供了開箱即用的支持,就是驗證服務和受驗證服務的配置方式不同而已。
    我們拉取JWT版本的代碼:JWT版,記得改配置文件:
    在這裏插入圖片描述

1.修改驗證服務以頒發JWT令牌

pom依賴:

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

然後增加個配置類:

@Configuration
public class JWTTokenStoreConfig {
    @Autowired
    private ServiceConfig serviceConfig;
    @Bean
    public TokenStore tokenStore(){
        return  new JwtTokenStore(jwtAccessTokenConverter());
    }
    @Bean
    @Primary //告訴Spring這個是首選的,
    public DefaultTokenServices tokenServices(){
        DefaultTokenServices defaultTokenServices=new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }
    @Bean //在JWT和OAuth2服務器之間充當翻譯
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter converter=new JwtAccessTokenConverter();
        converter.setSigningKey(serviceConfig.getJwtSigningKey());//定義用於簽署令牌的簽名密鑰
        return converter;
    }
    @Bean
    public TokenEnhancer jwtTokenEnhancer(){
        return new JWTTokenEnhancer();
    }
}

小筆記:這裏是使用的對稱加密,密鑰在配置服務裏配置:

signing.key: "345345fsdfsf5345"

剛纔定義瞭如何創建和簽名JWT令牌。現在要將它掛鉤到OAuth2服務中。
剛纔定義的內容,將在這裏注入:
在這裏插入圖片描述
驗證:運行Eureka->配置服務->驗證服務
在這裏插入圖片描述
返回的token已經是Base64了,找個在線解密的網站解密一下:在線操作
在這裏插入圖片描述

2.在微服務中使用JWT

到目前爲止,已經有了驗證服務。接下來就是配置許可證和組織服務以使用JWT。要做兩件事:
(1)將Spring-security-jwt依賴項添加到pom文件。
(2)創建一個JWTTokenStoreConfig類。幾乎和之前的相同。這個沒必要再寫一遍,只需要把傳播搞定就行了。
在這裏插入圖片描述
在這裏插入圖片描述

3.擴展JWT令牌

注意剛纔的解密,發現有些字段不是JWT令牌字段,這些就是擴展進來的。
在這裏插入圖片描述
通過向驗證服務添加一個Spring OAuth2令牌增強器類,可以很輕鬆的擴展JWT令牌。
在這裏插入圖片描述
需要做的最後一件事就是告訴OAuth2服務使用這個類,首先爲這個類公開一個Bean。
在這裏插入圖片描述
公開之後就受IOC管理了,就可以自動裝配進相應的地方了:
在這裏插入圖片描述

4.從JWT令牌中解析自定義字段

這裏從Zuul網關開始說起:
pom增加依賴:

<dependency>
          <groupId>io.jsonwebtoken</groupId>
          <artifactId>jjwt</artifactId>
          <version>0.7.0</version>
      </dependency>

然後就可以使用這個庫解密了:
在這裏插入圖片描述

四、關於微服務安全的總結

(1)對所有服務通信使用HTTPS。
(2)所有服務調用都應通過API網關。
(3)將服務劃分到公共API和私有API。
這個值得討論,很多人覺得公網下加密,內網下相互調用就不用加密,但是一旦網絡被攻破,那就比較慘了,所以還是兩個地方都加密的好,雖然開發的時候麻煩了點兒,但是沒了後顧之憂。
(4)通過封鎖不需要的網絡端口來限制微服務的攻擊面。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章