做者;Rinor Maloku 前端
譯者:殷龍飛 web
審校:邱世達 docker
原文:medium.com/google-clou…json
的第二部分,若是沒有看第一篇的話,請先看第一部份內容,由於這篇博客是以第一篇博客爲基礎進行進一步深刻的。api
在第一篇文章中,咱們創建了一個Kubernetes集羣,而且在上面部署了 Istio 和示例微服務應用程序「Sentiment Analysis」,用來展現Istio的功能。緩存
使用Istio後,咱們能夠把應用層中的重試、超時、斷路器、跟蹤、監控內容拋棄,以保持咱們的服務應用保持在一個簡單專一的微型狀態,(如圖1所示)。此外,咱們還啓用了高級測試和部署技術,如A/B測試,鏡像和金絲雀部署。安全
在本文中,咱們將帶領讀者使用Istio來處理身份驗證和受權!bash
我永遠不會相信認證和受權會讓我感到興奮!可是Istio可讓這個話題變得有趣,這種狀況下難道你不感到興奮麼?服務器
答案很簡單: Istio將這些職責從咱們的服務下沉到Envoy代理,當請求到達咱們的服務時,它們已經通過身份驗證和受權,咱們只需編寫提供業務價值的代碼。併發
聽起來不錯? 讓咱們去瞧瞧吧!
做爲身份和訪問管理服務器,咱們將使用Auth0,它有一個試用選項,直觀易用,我只是喜歡它! 也就是說,相同的原則能夠用於任何 OpenID Connect實現, 如KeyCloak、IdentityServer等等。
要開始使用,請使用您的賬戶導航到Auth0 Portal,在Applications> Default App下建立租戶並選擇Domain,以下圖所示:
更新文件 resource-manifests/istio/security/auth-policy.yaml
以使用您的域名:
apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata: name: auth-policy spec: targets: - name: sa-web-app - name: sa-feedback origins: - jwt: issuer: "https://{YOUR_DOMAIN}/" jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json" principalBinding: USE_ORIGIN複製代碼
有了這個資源,pilot會配置envoy在將請求轉發給服務sa-web-app
和 sa-feedback
以前對其進行身份驗證。同時,這個策略不會應用到運行sa-frontend
服務的envoy上,這使得咱們可以未經認證就訪問前端服務。要應用這些策略,請執行如下命令:
$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml policy.authentication.istio.io "auth-policy" created複製代碼
返回頁面併發出請求,您將看到它將以401 Unauthorized結束,如今讓咱們從前端轉發用戶以使用Auth0進行身份驗證。
要驗證最終用戶的請求,咱們須要在Auth0中建立一個API,表示通過身份驗證的服務,即:評論,詳細信息和評級。要建立API,請導航到 Auth0 Portal > API > Create API ,以下圖所示。
這裏的重要信息是稍後在腳本中使用的標識符:
觀衆: {YOUR_AUDIENCE}
其他所需的詳細信息位於Auth0 Portal中的 Applications 下 ,而後選擇自動建立的與API同名的 Test Application。
請記下:
域名: {YOUR_DOMAIN}
客戶ID: {YOUR_CLIENT_ID}
在Test Application中向下滾動到Allowed Callback URLs文本位置,在此字段中咱們指定請求在完成身份驗證後應被轉發到的目的URL。在咱們的示例中,它是:
[http://{EXTERNAL_IP}/callback](http://%7BEXTERNAL_IP%7D/callback)
向Allowed Logout URLs添加如下URL:
[http://{EXTERNAL_IP}/logout](http://%7BEXTERNAL_IP%7D/logout)
接下來讓咱們開始處理前端。
檢出 [istio-mastery]
存儲庫中的auth0 分支。在此分支中,前端包含代碼更改以將用戶轉發到Auth0進行身份驗證,並在對其餘服務的請求中使用JWT令牌,以下所示:
analyzeSentence() { fetch('/sentiment', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token }, body: JSON.stringify({ sentence: this.textField.getValue() }) }) .then(response => response.json()) .then(data => this.setState(data)); }複製代碼
爲了更新前端以使用你的租戶的詳細信息,請導航到該文件 sa-frontend/src/services/Auth.js
並使用咱們以前記下的值替換如下值:
const Config = { clientID: '{YOUR_CLIENT_ID}', domain:'{YOUR_DOMAIN}', audience: '{YOUR_AUDIENCE}', ingressIP: '{EXTERNAL_IP}' // Used to redirect after authentication }複製代碼
應用程序已準備就緒,請在下面的命令中指定docker用戶ID,而後構建並部署:
$ docker build -f sa-frontend/Dockerfile \ -t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 \ sa-frontend $ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 $ kubectl set image deployment/sa-frontend \ sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0複製代碼
試一試應用吧! 您將被轉發到Auth0,在那裏您必須登陸(或註冊),而後跳轉回原頁面,之後就能夠發出通過身份驗證的請求了。同時,若是您嘗試使用早期的curl命令,您將得到401狀態代碼,代表該請求是未受權的。
讓咱們進行下一步,受權請求。
身份驗證使咱們可以知道用戶是誰,但咱們須要受權才能知道他們能夠訪問的內容。Istio也爲此提供了工具!
做爲示例,咱們將建立兩組用戶(如圖24所示):
用戶 :只能訪問SA-WebApp和SA-Frontend服務。
版主 :能夠訪問全部三項服務。
要建立用戶組,咱們將使用Auth0受權擴展,而後使用Istio,咱們將爲他們提供不一樣級別的訪問權限。
在Auth0門戶中,導航到Extensions並安裝「Auth0 Authorization」擴展。安裝完成後,導航到受權擴展並經過單擊右上角的租戶並選擇菜單選項「配置」進行配置。啓用組,而後單擊 發佈規則 按鈕。
在受權擴展中,導航到 Groups 並建立Moderators
組。同時,咱們會將全部通過身份驗證的用戶視爲常規用戶,所以無需建立其餘組。
選擇Moderators組,而後單擊添加成員,添加您的主賬戶。保留一些沒有任何組的用戶,以驗證是否禁止訪問。(您能夠在Auth0 Portal>用戶>建立用戶中手動註冊新用戶)
用戶將添加到組中,但此信息不會反映在訪問令牌中。爲了保持OpenID Connect符合要求並同時返回組,咱們須要向令牌添加自定義命名空間聲明。這可使用Auth0規則來完成。
要在Auth0 Portal中建立規則,請導航到規則,單擊「建立規則」並 從模板中 選擇一個 空規則。
粘貼下面的代碼並保存名爲「添加組聲明」的新規則。
function (user, context, callback) { context.accessToken['https://sa.io/group'] = user.groups[0]; return callback(null, user, context); }複製代碼
注意: 此代碼選擇受權擴展中定義的第一個用戶組,並將其做爲自定義命名空間聲明添加到訪問令牌中。
返回 規則頁面 ,確認您按此順序擁有兩個角色:
auth0受權擴展
添加組聲明
順序很重要,由於 **auth0-authorization-extension**
規則會異步檢索組字段 ,而後由第二個規則將其添加爲命名空間聲明,從而產生如下訪問令牌:
{ "https://sa.io/group": "Moderators", "iss": "https://sentiment-analysis.eu.auth0.com/", "sub": "google-oauth2|196405271625531691872" // [shortened for brevity] }複製代碼
如今,咱們必須經過從https://sa.io/group
返回的訪問令牌中的聲明中提取組來配置Envoy代理以驗證用戶訪問權限。這是下一節的主題,讓咱們繼續前進。
要得到受權,咱們須要爲Istio啓用RBAC。爲此,請將如下配置應用於Mesh:
apiVersion: "rbac.istio.io/v1alpha1" kind: RbacConfig metadata: name: default spec: mode: 'ON_WITH_INCLUSION' # 1 inclusion: services: # 2 - "sa-frontend.default.svc.cluster.local" - "sa-web-app.default.svc.cluster.local" - "sa-feedback.default.svc.cluster.local" 複製代碼
僅爲「包含」字段中指定的服務和/或命名空間啓用RBAC。
包括指定的服務列表。
經過執行如下命令應用配置:
$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml rbacconfig.rbac.istio.io/default created複製代碼
如今,全部服務都須要基於角色的訪問控制,換句話說,對全部服務的訪問都會被拒絕,並響應「RBAC: access denied」。啓用對受權用戶的訪問權限將成爲下一節的主題。
全部用戶都應該可以訪問 SA-Frontend 和 SA-WebApp 服務,這是經過如下Istio的資源實現的:
ServiceRole: 指定用戶擁有的權限
ServiceRoleBinding: 指定ServiceRole應用於誰。
對於普通用戶,咱們將容許訪問指定的服務:
apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRole metadata: name: regular-user namespace: default spec: rules: - services: - "sa-frontend.default.svc.cluster.local" - "sa-web-app.default.svc.cluster.local" paths: ["*"] methods: ["*"]複製代碼
使用 常規用戶綁定, 咱們將ServiceRole應用於咱們頁面的全部訪問者:
哦! 全部用戶這意味着未經身份驗證的用戶可使用SA WebApp嗎? 不,該策略仍將檢查JWT令牌的有效性。😉
應用配置:
$ kubectl apply -f resource-manifests/istio/security/user-role.yaml servicerole.rbac.istio.io/regular-user created servicerolebinding.rbac.istio.io/regular-user-binding created複製代碼
對於咱們的版主,咱們但願啓用對全部服務的訪問:
apiVersion: "rbac.istio.io/v1alpha1" kind: ServiceRole metadata: name: mod-user namespace: default spec: rules: - services: ["*"] paths: ["*"] methods: ["*"]複製代碼
但咱們只想將其綁定到Access Token聲明 https://sa.io/group
等於Moderators值的用戶。
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: mod-user-binding
namespace: default
spec:
subjects:
- properties:
request.auth.claims[https://sa.io/group]: "Moderators"
roleRef:
kind: ServiceRole
name: "mod-user"
複製代碼
要應用配置,請執行:
$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml servicerole.rbac.istio.io/mod-user created servicerolebinding.rbac.istio.io/mod-user-binding created複製代碼
因爲Envoy中的緩存,受權規則可能須要幾分鐘才能生效,但在此以後,您將可以驗證用戶和版主具備不一樣的訪問級別。
您是否真的見過任何更簡單,零工做的可擴展和安全的身份驗證和受權概念?
僅使用三個Istio資源(RbacConfig,ServiceRole和ServiceRoleBinding),咱們能夠經過細粒度控制對最終用戶訪問咱們服務進行身份驗證和受權。
此外,咱們將這些問題從咱們的服務中轉移到咱們的Envoy:
減小可能出現安全問題和漏洞的樣板代碼,
減小由於忘記標記註解而暴露服務端點的愚蠢情況。
每次添加新角色或權限時,都會消除更新全部服務的連鎖效應。
保持簡單,安全和快速地添加新服務。
Istio 使您的團隊可以再次將資源集中在提供商業價值上,而不須要爲服務的周邊任務進行處理,讓微服務迴歸「微型」的本質。
本文爲您提供了在實際項目中開始使用Istio的知識和實踐。
藉此機會,我很感謝你加入個人此次Istio探索之旅,這確定不容易,你堅持下去就已經很棒了。我十分但願在下面的評論中看到您的想法,你能夠隨時在 Twitter 或個人主頁 rinormaloku.com 上與我聯繫。