前文的示例中,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
,可跳轉至類似如下的登錄頁面: -
輸入賬號
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的某個地方能直接切換環境,例如一鍵切換開發、測試、生產環境等。
思路已經給出,實現也就是工作量的事情了。
相信聰明的看官們,對是放棄擴展,抑或追求完美一事,心裏一定有了一些計較。
配套代碼
- GitHub:
- microservice-discovery-eureka-authenticating:https://github.com/eacdy/spring-cloud-study/tree/master/2018-Finchley/microservice-discovery-eureka-authenticating
- Gitee:
- microservice-discovery-eureka-authenticating:https://gitee.com/itmuch/spring-cloud-study/tree/master/2018-Finchley/microservice-discovery-eureka-authenticating