跟我學Spring Cloud(Finchley版)番外-01-Eureka安全詳解

前文的示例中,Eureka Server都是允許匿名訪問的,該方式一般無法滿足公司在安全性上的訴求。

本節來構建一個需要登錄才能訪問的Eureka Server。Eureka本身不具備安全認證的能力,Spring Cloud使用Spring Security爲Eureka Server進行了增強。

Eureka Server端

改造

  • 加依賴

    1
    2
    3
    4
    
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
  • 加配置

    1
    2
    3
    4
    5
    
    spring:
      security:
        user:
          name: user                # 配置登錄的賬號是user
          password: password123     # 配置登錄的密碼是password123
    

    不設置這段內容,賬號默認是user,密碼是一個隨機值,該值會在啓動時打印出來

  • 改配置

    將Eureka Server中的 eureka.client.service-url.defaultZone 修改爲爲http://{user}:{password}@EUREKA_HOST:EUREKA_PORT/eureka/ 的形式:

    1
    2
    3
    4
    
    eureka:
      client:
        service-url:
          defaultZone: http://user:password123@localhost:8761/eureka/
    
  • 寫代碼

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    /**
     * Spring Cloud Finchley及更高版本,必須添加如下代碼,部分關閉掉Spring Security
     * 的CSRF保護功能,否則應用無法正常註冊!
     * ref: http://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#_securing_the_eureka_server
     * @author zhouli
     */
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
      @Override
      protected void configure(HttpSecurity http) throws Exception {
        http.csrf().ignoringAntMatchers("/eureka/**");
        super.configure(http);
      }
    }
    

    Spring Cloud Finchley及更高版本必須添加這一段,在Edgware以及更早的版本中無需這一步驟。

測試

  • 啓動Eureka Server並訪問http://localhost:8761 ,可跳轉至類似如下的登錄頁面:

    圖-Eureka Server登錄頁

  • 輸入賬號user ,密碼password123 後,即可正常訪問Eureka Server首頁。

Eureka Client端

如何將微服務註冊到需認證的Eureka Server上呢——和Eureka Server端一樣,只須將eureka.client.service-url.defaultZone 配置爲http://{user}:{password}@EUREKA_HOST:EUREKA_PORT/eureka/ 的形式即可:

1
2
3
4
eureka:
  client:
    serviceUrl:
      defaultZone: http://user:password123@localhost:8761/eureka/

數據權限·吐槽·拓展

實際項目中,出於安全考慮,往往還需實現數據權限。

舉個例子:

  • 團隊1維護微服務A、B、C
  • 團隊2維護微服務D、E、F

從安全的角度,我們希望:

  • 團隊1中的開發人員只能操作微服務A、B、C在Eureka Server上的信息;
  • 團隊1中的開發人員只能訪問其他團隊授權給該團隊的微服務的信息(例如團隊2將微服務D授權給微服務A訪問);

此時該怎麼辦呢?

TIPS

有人可能會想:Eureka Server上哪有什麼操作啊!整個Eureka Server的界面上,明明只有查看的能力!

如果只是查看,那當然沒有問題,但要知道Eureka Server是有RESTful API的(詳見 跟我學Spring Cloud(Finchley版)-06-服務註冊與服務發現-Eureka深入 一節 )——舉個例子,只需發送DELETE請求到http://{username}:{password}@EUREKA_HOST:EUREKA_PORT/eureka/apps/{appId}/{instanceID} ,即可下線服務。如果線上微服務被惡意下線,那後果是不堪設想的。君不見,前兩年攜程刪庫事件造成股票大跌?

Spring Cloud抑或原生Eureka Server並未提供這一功能,只能由開發人員基於Spring Security或其他權限框架自行擴展。

這個擴展的成本還是比較高的,於是目前業界大多企業都放棄了擴展,轉而採用管理手段防止無數據權限帶來的風險。例如,生產環境中:

  • 將Eureka Server的賬號密碼管控起來,只有核心成員才知曉。

    TIPS

    有人可能會想:這TM扯淡吧?我翻一下配置屬性不知道賬號密碼了?後面會講配置中心,配置中心可將賬號密碼等敏感數據加密存儲。

  • 將Eureka Server部署在一個隔離的網絡中,人們無法直接訪問到Eureka Server首頁,必須藉助跳板機等工具才能訪問。

但不管怎麼樣,以上方式都會增加運維成本,同時也會帶來不少溝通問題。

在筆者看來,體驗最好、最直觀、最完美的做法如下:

  • 有完備的數據權限機制;
  • 開發人員在一個Dashboard上可以查看、管理所有他有權管理的微服務(這裏的Dashboard並不是指Eureka Server的界面,而是自己另外做的界面);
  • 在Dashboard的某個地方能直接切換環境,例如一鍵切換開發、測試、生產環境等。

思路已經給出,實現也就是工作量的事情了。

相信聰明的看官們,對是放棄擴展,抑或追求完美一事,心裏一定有了一些計較。

配套代碼

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