Spring Cloud 系列之 Config 配置中心(三)
本篇文章為系列文章,未讀前幾集的同學請猛戳這裡:
Spring Cloud 系列之 Config 配置中心(一) Spring Cloud 系列之 Config 配置中心(二)
本篇文章講解 Config 如何實現配置中心加解密,配置中心使用者安全認證。
配置中心加解密
考慮這樣一個問題:所有的配置檔案都儲存在 Git 遠端倉庫,配置檔案中的一些資訊又是比較敏感的。所以,我們需要對這些敏感資訊進行加密處理。主要的加密方法分為兩種:一種是共享金鑰加密(對稱金鑰加密),一種是公開金鑰加密(非對稱金鑰加密)。
對稱加解密 Symmetric encryption
對稱加密是最快速、最簡單的一種加密方式,加密(encryption)與解密(decryption)用的是同樣的金鑰(secret key)。
檢查加密環境
點選連結觀看:檢查加密環境視訊(獲取更多請關注公眾號「哈嘍沃德先生」)
版本問題
訪問 Config Server:http://localhost:8888/encrypt/status
檢查結果如果是:{"description":"No key was installed for encryption service","status":"NO_KEY"}
說明沒有為加密服務安裝金鑰,也說明你使用的是較低的 JDK 版本。
比較簡單的解決辦法:更換高版本 JDK,比如使用最新版的 LTS 版本 JDK-11.0.6。
複雜的解決辦法:從 Oracle 官網下載對應 JCE,下載連結:https://www.oracle.com/java/technologies/javase-jce-all-downloads.html
下圖紅色框中內容已經足夠說明原因:JDK 9 以及更高版本已附帶策略檔案,並在預設情況下啟用。
如果你的當前環境必須使用低版本 JDK,那麼請下載對應 JCE 壓縮包,下載解壓後把 local_policy.jar
和 US_export_policy.jar
檔案安裝到需要安裝 JCE 機器上的 JDK 或 JRE 的 security
目錄下即可。
配置問題
檢查結果如果是:{"description":"The encryption algorithm is not strong enough","status":"INVALID"}
說明服務端未配置加密。
Config Server 建立配置檔案,注意必須叫 bootstrap.yml
# 金鑰
encrypt:
key: example
重啟 Config Server 訪問:http://localhost:8888/encrypt/status 結果如下:
加解密演示
點選連結觀看:對稱加解密視訊(獲取更多請關注公眾號「哈嘍沃德先生」)
配置中心服務端
使用 curl
命令訪問 /encrypt
端點對屬性值 root 進行加密。反向操作 /decrypt
可解密。
curl http://localhost:8888/encrypt -d root
加密結果:bfb5cf8d7cab63e4b770b76d4e96c3a57d40f7c9df13612cb3134e2f7ed26123
解密
Git 倉庫
把加密後的資料更新到 Git 遠端倉庫的配置檔案中。值得注意的是需要在加密結果前新增 {cipher}
串,如果遠端屬性源包含加密的內容(以開頭的值{cipher}
),則將其解密,然後再通過HTTP傳送給客戶端。
配置中心客戶端
Config Client 控制層新增獲取配置資訊程式碼。
package com.example.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RefreshScope
@RestController
public class ConfigController {
@Value("${name}")
private String name;
@Value("${password}")
private String password;
@GetMapping("/name")
public String getName() {
return name;
}
@GetMapping("/password")
public String getPassword() {
return password;
}
}
修改 Config Client 配置檔案,重啟測試。
spring:
cloud:
config:
name: order-service # 配置檔名稱,對應 git 倉庫中配置檔案前半部分
label: master # git 分支
profile: prod # 指定環境
discovery:
enabled: true # 開啟
service-id: config-server # 指定配置中心服務端的 service-id
# 度量指標監控與健康檢查
management:
endpoints:
web:
base-path: /actuator # 訪問端點根路徑,預設為 /actuator
exposure:
include: '*' # 需要開啟的端點,這裡主要用到的是 refresh 這個端點
#exclude: # 不需要開啟的端點
訪問:http://localhost:9091/password 返回解密後的結果。
非對稱加解密 Asymmetric encryption
對稱加密和非對稱加密的區別
對稱加密演算法在加密和解密時使用的是同一個金鑰。只要拿到金鑰,任何人都能破jie。
非對稱加密演算法需要兩個金鑰來進行加密和解密,這兩個金鑰分別是公開金鑰(public key 簡稱公鑰)和私有金鑰(private key 簡稱私鑰)。在傳輸過程中,即使攻擊者截獲了傳輸的密文,並得到了公鑰,也無法破 jie密文,因為使用專用金鑰才能破jie密文。
圖片取自圖解HTTP一書。
Java-keytool 使用說明
Keytool 用來管理私鑰倉庫(keystore)和與之相關的X.509證書鏈(用以驗證與私鑰對應的公鑰),也可以用來管理其他信任實體。
預設大家都配置了 Java 的環境變數,開啟 CMD 視窗執行以下命令。
# 生成名為 config.keystore 的 keystore 檔案,別名為 config,加密演算法型別使用 RSA,金鑰庫口令和金鑰口令均為:config
keytool -genkeypair -keystore config.keystore -alias config -keyalg RSA -keypass config -storepass config
此時在我的 D 盤下會生成一個 config.keystore
檔案。
加解密演示
點選連結觀看:非對稱加解密視訊(獲取更多請關注公眾號「哈嘍沃德先生」)
配置中心服務端
將 config.keystore
檔案新增至 Config Server 專案 resources 目錄中。
建立 bootstrap.yml
新增非對稱加解密配置。注意:值要跟 CMD 裡輸入的值對應不然會出錯。
# 非對稱加解密
encrypt:
key-store:
location: classpath:config.keystore # keystore 檔案儲存路徑
alias: config # 金鑰對別名
password: config # storepass 金鑰倉庫
secret: config # keypass 用來保護所生成金鑰對中的私鑰
pom.xml 新增避免 maven 過濾檔案的配置。
<!-- build標籤 常用於新增外掛及編譯配置 -->
<build>
<!-- 讀取配置檔案 -->
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.tld</include>
<include>**/*.keystore</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
檢查加密環境,訪問:http://localhost:8889/encrypt/status 結果如下:
使用 curl
命令訪問 /encrypt
端點對屬性值 root 進行加密。反向操作 /decrypt
可解密。
curl http://localhost:8889/encrypt -d root
加密結果:
解密
Git 倉庫
把加密後的資料更新到 Git 遠端倉庫的配置檔案中。值得注意的是需要在加密結果前新增 {cipher}
串,如果遠端屬性源包含加密的內容(以開頭的值{cipher}
),則將其解密,然後再通過HTTP傳送給客戶端。
配置中心客戶端
Config Client 配置檔案如下。
spring:
cloud:
config:
name: order-service # 配置檔名稱,對應 git 倉庫中配置檔案前半部分
label: master # git 分支
profile: prod # 指定環境
discovery:
enabled: true # 開啟
service-id: config-server # 指定配置中心服務端的 service-id
# 度量指標監控與健康檢查
management:
endpoints:
web:
base-path: /actuator # 訪問端點根路徑,預設為 /actuator
exposure:
include: '*' # 需要開啟的端點,這裡主要用到的是 refresh 這個端點
#exclude: # 不需要開啟的端點
訪問:http://localhost:9091/password 返回解密後的結果。
配置中心使用者安全認證
折騰了大半天終於給大家把加解密講完了,但是如果你夠仔細,你會發現此時的 Config Server 誰都可以訪問,而且直接通過 Config Server 訪問配置檔案資訊,加密的內容就會解密後直接顯示在瀏覽器中,這豈不是又白折騰了?當然不是,我們只需要新增使用者安全認證即可。
新增依賴
Config Server 新增 security 依賴。
<!-- spring boot security 依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
配置檔案
Config Server 的 application.yml 新增安全認證配置。
spring:
# 安全認證
security:
user:
name: user
password: 123456
Config Client 的 bootstrap.yml 新增安全認證配置。
spring:
cloud:
config:
# 安全認證
username: user
password: 123456
測試
服務端
Config Server 訪問:http://localhost:8889/order-service-prod.yml 被重定向至登入頁。
輸入使用者名稱和密碼後,結果如下:
客戶端
Config Client 訪問:http://localhost:9091/password 結果如下:
至此 Config 配置中心所有的知識點就講解結束了。
本文采用 知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議
。
大家可以通過 分類
檢視更多關於 Spring Cloud
的文章。