設定 Cloud Service Mesh 使用者驗證
如果您使用該實作方式,即使使用快速以外的管道,也必須在istio-asm-managed-rapid
configmap 中進行變更。
如果您有TRAFFIC_DIRECTOR
控制層實作,這項功能僅支援許可清單。請與支援團隊聯絡,要求將這項功能加入貴機構的允許清單
Cloud Service Mesh 使用者驗證是一項整合式解決方案,可為已部署的工作負載提供瀏覽器型使用者驗證和存取權控管功能。您可透過這項功能與現有的身分識別提供者 (IDP) 整合,進行使用者驗證,並使用 Istio API 和授權政策管理存取權。這是 Istio JSON Web Token (JWT) 驗證的替代方案,使用起來更簡單。
一般用途是機構使用 Cloud Service Mesh 託管網路應用程式,供員工透過網路瀏覽器存取。此外,機構必須使用現有的身分識別提供者來管理使用者身分。Cloud Service Mesh 使用者驗證功能可讓使用者透過標準的網頁式 OpenID Connect (OIDC) 登入和同意流程輕鬆完成驗證。使用者通過驗證後,Cloud Service Mesh 會強制執行 Istio 授權政策,並在授權成功後,以安全憑證格式將身分傳輸至工作負載。
運作方式
Cloud Service Mesh 使用者驗證功能導入了新元件 authservice
。
這個元件會與以 Envoy 為基礎的輸入內容整合,做為外部授權服務,攔截所有傳入的要求以進行驗證。authservice
實作 OIDC 通訊協定的用戶端,並允許使用者透過瀏覽器存取應用程式,使用者可在瀏覽器中完成互動式驗證和同意流程,建立短期工作階段。authservice
實作業界標準通訊協定,可與任何身分識別提供者整合,做為 OIDC 授權伺服器。使用者通過驗證後,主體資訊會封裝在 JWT 格式的 RCToken
中,並由 authservice
簽署,然後轉送至 Ingress 中的 Istio 授權層。這個模型可為網格中的流量提供周邊存取權控管。如果使用者有權存取資源,這個 RCToken 也會轉送至微服務,以取得主體資訊並強制執行精細的存取權控管。
下圖顯示網格中的 authservice
位置,以及與網格其他部分的關係,例如 Ingress、工作負載、使用者瀏覽器和任何現有的 IDP。
管理員可以在 Cloud Service Mesh 安裝中,將 authservice
安裝為外掛程式。安裝後,authservice
會讀取 UserAuth
自訂資源中定義的 OIDC 端點設定和其他相關設定。管理員可以使用 Cloud Service Mesh ExternalAuthorization
API,將 auth_server
設定為 Ingress 的篩選器。
安裝使用者驗證服務
下列步驟說明如何設定 authservice
。
必要條件
按照「安裝依附工具並驗證叢集」一文中的步驟操作,以便:- 如果您在私人叢集上使用代管 Cloud Service Mesh,請確保叢集能夠將輸出流量傳送至 IDP。
此外,請按照下列步驟操作,確認您符合必要條件。
自訂安裝使用者驗證疊加畫面
如要安裝使用者驗證服務,您必須自訂 Cloud Service Mesh 安裝作業,新增網格層級的外部授權提供者。所需步驟取決於您使用的是代管或叢內 Cloud Service Mesh。
受管理
更新 ConfigMap,加入使用者驗證 MeshConfig。在下列指令中,請使用佈建代管 Cloud Service Mesh 時使用的相同
REVISION_LABEL
(例如asm-managed
、asm-managed-rapid
或asm-managed-stable
):kubectl edit configmap istio-REVISION_LABEL -n istio-system
在 MeshConfig 的
mesh
欄位下方新增下列文字:mesh: |- ... extensionProviders: - name: "asm-userauth-grpc" envoyExtAuthzGrpc: service: "authservice.asm-user-auth.svc.cluster.local" port: "10003"
建立
asm-user-auth
命名空間。kubectl create namespace asm-user-auth
啟用要用於注入的命名空間。步驟取決於控制層實作。
代管 (TD)
將預設插入標籤套用至命名空間:
kubectl label namespace asm-user-auth \ istio.io/rev- istio-injection=enabled --overwrite
受管理 (Istiod)
建議:執行下列指令,將預設插入標籤套用至命名空間:
```sh kubectl label namespace asm-user-auth \ istio.io/rev- istio-injection=enabled --overwrite ```
如果您是使用受管理 Istiod 控制平面的現有使用者: 建議您使用預設注入,但系統也支援以修訂版本為準的注入。請按照下列指示操作:
- 執行下列指令,找出可用的發布管道:
kubectl -n istio-system get controlplanerevision
輸出結果會與下列內容相似:
NAME AGE asm-managed-rapid 6d7h
在輸出內容中,「
NAME
」欄下方的值是與 Cloud Service Mesh 版本可用發布管道對應的修訂版本標籤。將修訂版本標籤套用至命名空間:
kubectl label namespace asm-user-auth \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite
在
asm-user-auth
命名空間中安裝 Istio 閘道。kubectl apply -n asm-user-auth -f DIR_PATH/samples/gateways/istio-ingressgateway
叢集內
取得使用者驗證疊加層範例,並在網格中進行任何自訂時更新。建議您在來源控制項中維護這個疊加檔案,這是最佳做法。
curl https://raw.githubusercontent.com/GoogleCloudPlatform/asm-user-auth/v1.2.5/overlay/user-auth-overlay.yaml > user-auth-overlay.yaml
請按照這篇文章的說明,使用 Google 提供的指令碼安裝 Cloud Service Mesh,並啟用使用者驗證疊加層。例如:
./asmcli install \ --project_id PROJECT_ID \ --cluster_name CLUSTER_NAME \ --cluster_location CLUSTER_LOCATION \ --fleet_id FLEET_PROJECT_ID \ --output_dir DIR_PATH \ --enable_all \ --custom_overlay user-auth-overlay.yaml
使用者驗證
kpt
套件會建立AuthorizationPolicy
,以參照pkg/ext-authz.yaml
指定的外部授權提供者。建立
asm-user-auth
命名空間。kubectl create namespace asm-user-auth
啟用要用於插入的命名空間。
建議:執行下列指令,將預設插入標籤套用至命名空間:
kubectl label namespace asm-user-auth \ istio.io/rev- istio-injection=enabled --overwrite
建議您使用預設插入方式,但系統也支援以修訂版本為準的插入方式: 請按照下列操作說明進行:
使用下列指令在
istiod
上找出修訂版本標籤:kubectl get deploy -n istio-system -l app=istiod -o \ jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
將修訂版本標籤套用至命名空間。在下列指令中,
REVISION_LABEL
是您在上一步記下的istiod
修訂版本標籤值。kubectl label namespace asm-user-auth \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite
在
asm-user-auth
命名空間中安裝 Istio 閘道。kubectl apply -n asm-user-auth -f DIR_PATH/samples/gateways/istio-ingressgateway
準備 OIDC 用戶端設定
請按照下列步驟設定 OIDC 用戶端設定。本指南使用 Google 做為 IDP,但您可以使用任何支援 OIDC 驗證的 IDP。
在 Google Cloud 控制台中,依序前往「API 和服務」>「憑證」。
前往「建立憑證」,然後選擇「OAuth 用戶端 ID」。視需要設定 OAuth 同意畫面選項,然後設定下列選項:
- 將「應用程式類型」設為「網頁應用程式」。
- 將「已授權的重新導向 URI」設為
https://REDIRECT_HOST/REDIRECT_PATH
。 舉例來說,您可以將 localhost 設為https://localhost:8443/_gcp_asm_authenticate
。
點選「儲存」。
此外,請儲存 OIDC 用戶端設定,以供日後使用。
export OIDC_CLIENT_ID=CLIENT_ID export OIDC_CLIENT_SECRET=CLIENT_SECRET export OIDC_ISSUER_URI=ISSUER_URI export OIDC_REDIRECT_HOST=REDIRECT_HOST export OIDC_REDIRECT_PATH=REDIRECT_PATH
取得 kpt
套件
請按照下列步驟,從公開存放區安裝建議的 authservice
設定。這些指令會擷取最新的 authservice
容器,並在 asm-user-auth
命名空間中啟動該容器做為 Pod。並設定 Ingress 攔截所有要求。
取得 kpt 套件:
kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth.git/@v1.2.5 .
cd asm-user-auth/
設定輸入閘道的重新導向網址和密鑰
OAuth2
需要託管在 HTTPS 保護端點上的重新導向網址。這些指令僅供參考,會為 Istio 輸入閘道產生自我簽署憑證,簡化設定程序。
產生自行簽署的憑證:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \ -days 365 -nodes -subj '/CN=localhost'
建立 Ingress 閘道的密鑰,用於代管 HTTPS 流量:
kubectl create -n asm-user-auth secret tls userauth-tls-cert --key=key.pem \ --cert=cert.pem
套用加密和簽署金鑰
authservice
需要兩組金鑰才能順利運作。第一種是加密和解密的對稱金鑰。這個金鑰用於加密工作階段狀態,然後將該狀態設為 Cookie。
第二組金鑰是公開/私密金鑰組。這個金鑰可用來以 JWT 格式簽署通過驗證的使用者資訊,做為 RCToken。這組金鑰的公開金鑰會發布在預先定義的端點,可供 Sidecar 用來驗證 JWT。
使用者驗證 kpt
套件包含兩個範例金鑰,可供快速設定。
不過,您也可以使用偏好的金鑰管理系統產生這些金鑰。
請準備採用下列格式的工作階段加密金鑰,或使用 pkg 中的範例 (可透過
cat ./samples/cookie_encryption_key.json
查看)。{ "keys":[ { "kty":"oct", "kid":"key-0", "K":"YOUR_KEY", "useAfter": 1612813735 } ] }
您可以使用下列指令產生測試用 AES 金鑰:
openssl enc -aes-256-cbc -k mycustomkey -P -md sha1 | grep key
請準備 RCToken 簽署金鑰,格式如下,或使用 pkg 中的範例 (可透過
cat ./samples/rctoken_signing_key.json
查看)。{ "keys":[ { "kty":"RSA", "kid":"rsa-signing-key", "K":"YOUR_KEY", # k contains a Base64 encoded PEM format RSA signing key. "useAfter": 1612813735 # unix timestamp } ] }
你可以使用下列指令產生 512 位元的測試用 RSA 私密金鑰:
openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:512
建立 Kubernetes 密鑰,這項密鑰會掛接到自己的檔案系統中。
authservice
kubectl create secret generic secret-key \ --from-file="session_cookie.key"="./samples/cookie_encryption_key.json" \ --from-file="rctoken.key"="./samples/rctoken_signing_key.json" \ --namespace=asm-user-auth
部署使用者驗證服務
下列指令會在 asm-user-auth
命名空間中建立使用者驗證服務和部署作業。
設定使用者驗證設定的必要值。用戶端 ID 和密碼會儲存為 Kubernetes 密碼,因此我們使用 Base64 將其編碼。請前往公開存放區,查看所有可用的設定器。
kpt fn eval pkg --image gcr.io/kpt-fn/apply-setters:v0.2 --truncate-output=false -- \
client-id="$(echo -n ${OIDC_CLIENT_ID} | base64 -w0)" \
client-secret="$(echo -n ${OIDC_CLIENT_SECRET} | base64 -w0)" \
issuer-uri="${OIDC_ISSUER_URI}" \
redirect-host="${OIDC_REDIRECT_HOST}" \
redirect-path="${OIDC_REDIRECT_PATH}"
套用 kpt
套件:
# Remove the potential alpha version CRD if exists.
kubectl delete crd userauthconfigs.security.anthos.io
kubectl apply -f ./pkg/asm_user_auth_config_v1beta1.yaml
kubectl apply -f ./pkg
authservice
會使用 UserAuthConfig
CRD 進行使用者驗證。UserAuthConfig
可在執行階段設定,您可以更新此物件來變更 authservice
行為,並使用任何 OIDC 授權伺服器的端點進行設定。
您可以查看 cat pkg/user_auth_config.yaml
檔案,其中包含下列欄位:
apiVersion: security.anthos.io/v1beta1
kind: UserAuthConfig
metadata:
name: user-auth-config
namespace: asm-user-auth
spec:
authentication:
oidc:
certificateAuthorityData: "" # kpt-set: ${ca-cert}
issuerURI: "<your issuer uri>" # kpt-set: ${issuer-uri}
proxy: "" # kpt-set: ${proxy}
oauthCredentialsSecret:
name: "oauth-secret" # kpt-set: ${secret-name}
namespace: "asm-user-auth" # kpt-set: ${secret-namespace}
redirectURIHost: "" # kpt-set: ${redirect-host}
redirectURIPath: "/_gcp_asm_authenticate" # kpt-set: ${redirect-path}
scopes: "" # kpt-set: ${scopes}
groupsClaim: "" # kpt-set: ${groups}
outputJWTAudience: "test_audience" # kpt-set: ${jwt-audience}
如要詳細瞭解 user_auth_config.yaml
欄位,請參閱使用者驗證設定詳細資料。
設定 API 要求 ID
API 要求 ID 是一組通用運算式語言 (CEL) 運算式,Cloud Service Mesh 使用者驗證會用來識別 API 要求。定義這些 ID 後,Cloud Service Mesh 使用者驗證就能以語意方式處理 API 要求驗證失敗。
具體來說,當您提供可識別 API 要求的 CEL 運算式時,您允許 Cloud Service Mesh 使用 401-Unauthorized 狀態碼,讓未經驗證的 API 要求驗證失敗。對於 CLI 和服務帳戶等用戶端而言,這點至關重要,因為這些用戶端會針對未經驗證的 API 要求預期這個狀態碼。
如果沒有 API 要求 ID,Cloud Service Mesh 使用者驗證會將所有未經驗證的要求重新導向至已設定的 OpenID Connect (OIDC) 提供者,並傳回 302-Found 狀態碼。一般來說,API 要求不應重新導向,因為失敗時應傳回 401-Unauthorized。
如要定義 API 要求 ID,請在 UserAuthConfig CR
中新增 apiRequestIdentifier
區段。這樣一來,您就能新增多個 CEL 運算式。如果提供多個 CEL 運算式,只要要求符合其中至少一個運算式,就會視為 API 要求。
以下範例說明如何將任何含有 example-api-header
標頭的要求、導向主機 api.example.com
的要求,或以 /v1/api/
底下路徑為目標的要求,指定為 API 要求。
apiVersion: security.anthos.io/v1beta1
kind: UserAuthConfig
metadata:
name: user-auth-config
namespace: asm-user-auth
spec:
authentication:
oidc:
certificateAuthorityData: "" # kpt-set: ${ca-cert}
issuerURI: "<your issuer uri>" # kpt-set: ${issuer-uri}
proxy: "" # kpt-set: ${proxy}
oauthCredentialsSecret:
name: "oauth-secret" # kpt-set: ${secret-name}
namespace: "asm-user-auth" # kpt-set: ${secret-namespace}
redirectURIHost: "" # kpt-set: ${redirect-host}
redirectURIPath: "/_gcp_asm_authenticate" # kpt-set: ${redirect-path}
scopes: "" # kpt-set: ${scopes}
groupsClaim: "" # kpt-set: ${groups}
outputJWTAudience: "test_audience" # kpt-set: ${jwt-audience}
apiRequestIdentifier:
name: "api-request-identifiers"
expressions:
- "'example-api-header' in http_request.headers"
- "http_request.host == api.example.com"
- "matches(http_request.path, '/v1/api/(.*)')"
# other expressions go here
您可以根據下列欄位,建構 Cloud Service Mesh 使用者驗證 CEL 運算式:
http_request.headers
:HTTP 要求標頭的地圖,其中鍵為小寫字串,值為字串向量。在 CEL 運算式中使用這個欄位,將含有特定標頭的要求指定為 API 要求。
http_request.host
:要求的 HTTP 網址主機 (例如api.example.com
)。在 CEL 運算式中使用這個欄位,將對特定主機的要求指定為 API 要求。
http_request.path
:要求的 HTTP 網址路徑 (例如/example-api-path
)。 開頭一律為「/」,且不含要求網址的查詢元件。在 CEL 運算式中使用這個欄位,將具有特定路徑的要求指定為 API 要求。
下一節將顯示範例 CEL 運算式,用於檢查及比對這些欄位的部分內容,以告知 Cloud Service Mesh 使用者驗證如何判斷哪些要求是 API 要求。
運算式範例
比對並找出包含 X-API-Key
標頭的所有要求:
"'x-api-key' in http_request.headers"
將標頭 X-API-Key
設為特定值,比對所有要求:
"'x-api-key' in http_request.headers && http_request.headers['x-api-key'].values == ['example-value ']"
比對傳送至主機 api.example.com
的所有要求:
"http_request.host == api.example.com"
比對並找出路徑為 /api/query
的所有要求:
"http_request.path == /api/query"
比對 /api/
底下任何路徑的所有要求:
"matches(http_request.path, '/api/(.*)')"
執行安裝後工作
完成先前的安裝步驟後,您必須執行下列工作。
為應用程式啟用使用者驗證
本節以 httpbin
為例,說明如何啟用使用者驗證。
Cloud Service Mesh 使用者驗證會使用CUSTOM
型別的授權政策,觸發 OIDC 流程。
安裝 Istio 閘道後,請設定閘道,使用您先前建立的 TLS 憑證 userauth-tls-cert
提供 HTTPS 流量。以下是您剛安裝的 pkg/gateway.yaml
設定。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: userauth
namespace: asm-user-auth
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: userauth-tls-cert
---
# This ensures the OIDC endpoint has at least some route defined.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: userauth-oidc
namespace: asm-user-auth
spec:
gateways:
- userauth
hosts:
- '*'
http:
- match:
- uri:
prefix: /status
- uri:
prefix: "your-oidc-redirect-path"
name: user-auth-route
route:
- destination:
host: authservice
port:
number: 10004
標籤
default
命名空間,即可為部署作業啟用istio-proxy
自動插入功能。kubectl label namespace default istio.io/rev=REVISION --overwrite
將
httpbin
部署至default
命名空間。kubectl apply -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/httpbin.yaml -n default
更新
httpbin
,使用這個閘道提供 HTTPS 流量,並使用通訊埠轉送功能在本機存取應用程式:kubectl apply -f./samples/httpbin-route.yaml -n default kubectl port-forward service/istio-ingressgateway 8443:443 -n asm-user-auth
通訊埠 8443 上的 Ingress 閘道會轉送至
localhost
,讓應用程式可在本機存取。部署
samples/rctoken-authz.yaml
,啟用 RequestAuthentication 和 AuthorizationPolicy,驗證要求中的 RCToken。kubectl apply -f ./samples/rctoken-authz.yaml -n asm-user-auth
samples/rctoken-authz.yaml
範例:apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: require-rc-token spec: selector: matchLabels: istio: ingressgateway jwtRules: - issuer: "authservice.asm-user-auth.svc.cluster.local" audiences: - "test_audience" jwksUri: "http://authservice.asm-user-auth.svc.cluster.local:10004/_gcp_user_auth/jwks" fromHeaders: - name: X-ASM-RCTOKEN forwardOriginalToken: true --- apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-rc-token spec: selector: matchLabels: istio: ingressgateway action: ALLOW rules: - when: - key: request.auth.claims[iss] values: - authservice.asm-user-auth.svc.cluster.local - key: request.auth.claims[aud] values: - test_audience
驗證使用者驗證
httpbin
會提供兩個路徑,/ip
可公開存取,而 /headers
則需要使用者透過設定的 IDP 登入。
請前往
https://localhost:8443/ip
,確認您是否能直接存取/ip
。前往
https://localhost:8443/headers
,確認是否看到 OIDC 登入頁面。登入後,按一下「下一步」,確認系統將您重新導向至
/headers
頁面。
設定授權政策
完成前幾個步驟的設定後,每位使用者都會透過網頁式驗證流程重新導向。流程完成後,authservice
會產生 JWT 格式的 RCToken
,並用來傳輸通過驗證的使用者資訊。
在 Ingress 新增 Istio 授權政策,確保系統會對每位通過驗證的使用者執行授權檢查:
kubectl apply -f ./samples/httpbin-authz.yaml -n asm-user-auth
httpbin-authz.yaml
檔案會設定 Ingress 閘道,以驗證 authservice 發出的 RC 符記,並僅在 JWT 包含目標欄位 (例如對象和簽發者) 時授權。請參閱以下授權政策範例:
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-rc-token spec: selector: matchLabels: istio: ingressgateway action: ALLOW rules: - to: - operation: paths: ["/ip"] - to: when: - key: request.auth.claims[iss] values: - authservice.asm-user-auth.svc.cluster.local - key: request.auth.claims[aud] values: - test_audience - key: request.auth.claims[sub] values: - allowed_user_sub_1 # Change this with the "sub" claim in the RC token. Wildcard '*' will match everything.
設定特定環境的設定
先前的步驟使用 localhost
和自行簽署的 HTTPS 憑證,以便快速設定。如要實際用於正式版,請使用自己的網域,例如 example.com
。
此外,請確認 certificateAuthorityData
具有預期的根憑證內容。舉例來說,如果系統的根憑證信任 IDP,您可以將這個欄位留空。如有 HTTPS Proxy 終止 HTTPS 連線,則應設為 Proxy 的根憑證。
管理及輪替金鑰
authservice
使用兩組金鑰。您可以獨立輪替每個金鑰。不過,輪替金鑰前,請務必瞭解輪替作業的運作方式。
這兩個金鑰都採用 JSON 格式。useAfter
欄位會指定金鑰開始使用的時間戳記。在金鑰輪替期間,您應在 JSON 中同時加入舊金鑰和新金鑰。舉例來說,在以下範例中,new-key
只會在時間戳記 1712813735
之後使用。
{
"keys":[
{
"kty":"RSA",
"kid":"old-key",
"K":"...", # k contains a Base64 encoded PEM format RSA signing key.
"useAfter": 1612813735, # unix timestamp
}
{
"kty":"RSA",
"kid":"new-key",
"K":"...", # k contains a Base64 encoded PEM format RSA signing key.
"useAfter": 1712813735, # unix timestamp
}
]
}
Cloud Service Mesh 會使用對稱金鑰,加密儲存在瀏覽器 Cookie 中的工作階段資料。為確保現有工作階段的有效性,authservice
會嘗試使用金鑰集中的所有金鑰解密。輪替時,authservice
會使用新金鑰加密新工作階段,並繼續嘗試使用舊金鑰解密。
公開/私密金鑰組用於簽署 RCToken
。公開金鑰會由 istiod
傳輸至 Sidecar,用於驗證 JWT。側車必須先收到新的公開金鑰,authservice
才能開始使用新的私密金鑰簽署 RCToken
。為此,authservice
會在新增金鑰後立即發布公開金鑰,但會等待一段時間,才開始使用該金鑰簽署 RCToken
。
總而言之,執行金鑰輪替時,建議您採取下列做法:
- 定期執行金鑰輪替,或視需要執行。
- 請以 JSON 格式同時提供目前和新的金鑰。新金鑰應與未來的時間戳記建立關聯。建議您指定的時間戳記至少要比目前時間早幾小時。
- 使用新金鑰後,請監控並確認服務仍正常運作。使用新金鑰後,請至少等待一天再進行下一個步驟。
- 從 JSON 項目中移除舊金鑰。因為不再需要使用。
多叢集部署作業
Cloud Service Mesh 使用者驗證支援多叢集部署。您需要在每個叢集中部署使用者驗證,如上所述。使用者授權設定 (例如 UserAuth 自訂資源、OIDC 用戶端密鑰、加密金鑰) 都必須在每個叢集中複製。
根據預設,輸入閘道會將驗證要求負載平衡至任一 authservice
執行個體。您可以使用目的地規則,將 Ingress 閘道設定為將要求傳送至同一叢集中的 authservice
,並僅容錯移轉至其他叢集的 authservice
。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: authservice-fail-over
namespace: asm-user-auth
spec:
host: authservice.asm-user-auth.svc.cluster.local
trafficPolicy:
loadBalancer:
localityLbSetting:
enabled: true
failover:
- from: us-east
to: us-west
- from: us-west
to: us-east
與其他設定相同,這項設定也必須在每個叢集中進行。
自訂聲明對應
如要設定自訂聲明對應,請設定 spec.authentication.oidc.attributeMapping
,從原始識別資訊提供者的 IDToken 定義任何對應。索引鍵是 RCToken 中的聲明名稱,值則是關於如何從 IDToken 剖析聲明的 CEL 運算式,請使用 assertion
參照 IDToken。
範例:
spec:
authentication:
oidc:
attributeMapping:
aud_copy: assertion.aud
decision: 'assertion.sub.startsWith("123") ? "success" : "fail"'
在 RCToken 中,巢狀憑證 attributes
包含已設定的憑證:
"attributes": {
"aud_copy": "foo.googleusercontent.com",
"decision": "success"
}
如果 CEL 運算式無法剖析 IDToken 中的值,系統會忽略該聲明,但不會導致驗證流程失敗。
使用者驗證升級
重新安裝使用者驗證套件,因為其中包含新版使用者驗證的更新二進位檔:
kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth.git/@v1.2.5 . cd asm-user-auth/
儲存 OIDC 用戶端設定:
export OIDC_CLIENT_ID=CLIENT_ID export OIDC_CLIENT_SECRET=CLIENT_SECRET export OIDC_ISSUER_URI=ISSUER_URI export OIDC_REDIRECT_HOST=REDIRECT_HOST export OIDC_REDIRECT_PATH=REDIRECT_PATH
部署使用者驗證服務,升級至新版本。
使用者驗證設定詳細資料
下表說明 CRD 中的每個欄位:
欄位名稱 | 說明 |
---|---|
authentication.oidc |
本節包含 OIDC 端點設定,以及 OIDC 流程中使用的參數。 |
authentication.oidc.certificateAuthorityData |
這是 OIDC 授權伺服器網域的 SSL 根憑證,或 HTTPS Proxy (如有)。 |
authentication.oidc.oauthCredentialsSecret |
Kubernetes Opaque 型別密鑰的密鑰參照,其中包含 JSON 酬載中的 OAuth2 OIDC client_id 和 client_secret。 |
authentication.oidc.issuerURI |
要在輸出 RCToken 中做為發行者的 URI。 |
authentication.oidc.proxy |
OIDC IDP 的 Proxy 伺服器 (如適用),格式為 http://user:password@10.10.10.10:8888。 |
authentication.oidc.redirectURIHost |
OAuth 終止 URI 使用的主機。如果將這個欄位留空,系統會使用目標網址的主機,並動態組裝重新導向 URI。 如果要在較高層級的網域中進行使用者驗證 SSO 工作階段,可以使用這個值。舉例來說,如要在 profile.example.com/ 和 admin.example.com/ 之間啟用 SSO,這個值可以設為 example.com。這樣一來,系統會在 example.com 建立使用者驗證工作階段,並在所有子網域之間共用。注意:如果多個網域 (例如 example1.com 和 example2.com) 是從同一個網格提供服務,則無法使用這項功能,建議將此欄位留空。 |
authentication.oidc.redirectURIPath |
authservice 終止 OAuth 流程的端點路徑。您應在 authentication.oidc.clientID 的授權伺服器中,將這個 URI 路徑和主機註冊為已授權的重新導向 URI。此外,這個 URI 應從啟用 authservice 的相同服務網格和 Ingress 提供。 |
authentication.oidc.scopes |
驗證要求中應要求的 OAuth 範圍。以逗號分隔的 ID 清單,用於指定除了「openid」範圍外,還要求哪些存取權,例如 「groups,allatclaim」。 |
authentication.oidc.groupsClaim |
如果 idtoken 包含群組聲明,請使用這個欄位指出其名稱。如果指定,服務會將這項憑證中的資料傳遞至輸出 RCToken 中的 groups 憑證。這項聲明應包含以半形逗號分隔的字串清單,例如 ["group1", "group2"]。 |
authentication.oidc.attributeMapping |
包含一或多個來自 idtoken 後接 CEL 運算式的宣告對應。所有聲明都應以 assertion.X 參照,assertion 則參照原始 IDToken,例如 aud_copy: assertion.aud |
authentication.outputJWTAudience |
authservice 產生的 RCToken 目標對象。Sidecar 可以根據這個目標對象值驗證傳入的 RCToken。 |
疑難排解
可存取 IDP 的網路。
可能的記錄:
error: TLS handshake failed.
。從附加至
istio-proxy
的暫時性容器執行curl
,藉此呼叫 IDP 簽發者 URI,進行驗證。例如請參閱「收集 Cloud Service Mesh 記錄」。如果無法連線,請檢查叢集的防火牆規則或其他網路設定。
根 CA 憑證。
可能的記錄:
error: The server's TLS certificate did not match expectations.
或error: TLS handshake failed.
。確認
certificateAuthorityData
包含正確的根 CA 憑證。 如果沒有終止 HTTPS 流量的 HTTPS Proxy,這項設定應保留 IDP 的根 CA 憑證。如果有的話,這個值應改為保留 Proxy。重新導向路徑設定。
可能觀察到的現象:在 OIDC 驗證流程中收到 404 錯誤頁面。
使用者驗證會傳回「Set-Cookie」標頭,但不使用路徑屬性。根據預設,瀏覽器會將要求網址的目錄做為 Cookie 路徑 (與路徑相關的 Cookie 範圍)。因此,除非您有意為之,否則建議不要在重新導向路徑中加入「/」。
Sidecar 無法擷取 jwksUri。
在某些情況下,Sidecar 限制可能會導致擷取 jwksUri 失敗。如果命名空間未使用萬用字元 (例如
./*
或istio-system/*
),則無法使用這項功能。您必須在輸出端輔助容器中手動新增命名空間。
常見問題
如何升級已啟用使用者驗證的 Cloud Service Mesh?
按照 Cloud Service Mesh 升級程序操作,並在指令列中加入
--custom_overlay user-auth-overlay.yaml
至asmcli install
,指定疊加檔案。我們應該為
authservice
佈建多少資源?每秒可處理多少要求?根據預設,
authservice
會設定為 2.0 個 vCPU 和 256Mi 的記憶體。在這種設定下,authservice
每秒可處理 500 個要求。如要處理大量要求,請佈建更多 CPU,這與要求處理容量大致成正比。您也可以設定多個 authservice 副本,提高水平擴充性。