-
1 # Java架構達人
-
2 # 程式設計師米兜
一.微服務架構回顧
那我們先回憶一下,常用4種架構之微服務架構。
微服務架構,主要是中間層分解,將系統拆分成很多小應用(微服務),微服務可以部署在不同的伺服器上,也可以部署在相同的伺服器不同的容器上。當應用的故障不會影響到其他應用,單應用的負載也不會影響到其他應用,其代表框架有Spring cloud、Dubbo等。其架構圖如下所示:
易於開發和維護:一個微服務只會關注一個特定的業務功能,所以它業務清晰、程式碼量較少。開發和維護單個微服務相對簡單。而整個應用是由若干個微服務構建而成的,所以整個應用也會被維持在一個可控狀態。
單個微服務啟動較快:單個微服務程式碼量較少, 所以啟動會比較快。
區域性修改容易部署:單體應用只要有修改,就得重新部署整個應用,微服務解決了這樣的問題。一般來說,對某個微服務進行修改,只需要重新部署這個服務即可。
技術棧不受限:在微服務架構中,可以結合專案業務及團隊的特點,合理地選擇技術棧。例如某些服務可使用關係型資料庫MySQL;某些微服務有圖形計算的需求,可以使用Neo4j。甚至可根據需要,部分微服務使用Java開發,部分微服務使用Node.js開發。微服務雖然有很多吸引人的地方,但它並不是免費的午餐,使用它是有代價的。使用微服務架構面臨的挑戰。
運維要求較高:更多的服務意味著更多的運維投入。在單體架構中,只需要保證一個應用的正常執行。而在微服務中,需要保證幾十甚至幾百個服務服務的正常執行與協作,這給運維帶來了很大的挑戰。
分散式固有的複雜性:使用微服務構建的是分散式系統。對於一個分散式系統,系統容錯、網路延遲、分散式事務等都會帶來巨大的挑戰。
介面調整成本高:微服務之間透過介面進行通訊。如果修改某一個微服務的API,可能所有使用了該介面的微服務都需要做調整。
重複勞動:很多服務可能都會使用到相同的功能,而這個功能並沒有達到分解為一個微服務的程度,這個時候,可能各個服務都會開發這一功能,從而導致程式碼重複。儘管可以使用共享庫來解決這個問題(例如可以將這個功能封裝成公共元件,需要該功能的微服務引用該元件),但共享庫在多語言環境下就不一定行得通了。
二.親身小經歷
上面扯皮了這麼多,還不到關鍵的地方,到底搞什麼鬼呀?我不是有意的,我就想讓大家再過過概念。好啦,現在我們開始吧!看看我當時的微服務架構(我那會用Sping Cloud,就根據Sping Cloud講一講),大家看安不安全?以下內容基本使用白話文扯皮子。
看不清楚的,大家可以點選圖片放大看一看。從中可以看出這是Spring Cloud微服務架構圖,至於Dubbo等微服務架構思路大體也是這樣。從中我們看出為了保證安全可靠性,我們用了gateway、oauth2.0。至於這兩項技術到底穩不穩,我們分開聊一聊。
三.gateway
1.gateway是什麼?
Spring Cloud Gateway是Spring官方基於Spring 5.0,Spring Boot 2.0和Project Reactor等技術開發的閘道器,Spring Cloud Gateway旨在為微服務架構提供一種簡單而有效的統一的API路由管理方式。Spring Cloud Gateway作為Spring Cloud生態系中的閘道器,目標是替代Netflix ZUUL,其不僅提供統一的路由方式,並且基於Filter鏈的方式提供了閘道器基本的功能,例如:安全,監控/埋點,和限流等。
2.gateway怎麼用?
Spring Cloud Gateway怎麼用,在這裡我主要是為了講述微服務的安全性,我就不上程式碼了,我就講講理論知識,具體細節等下我提供一些我之前的文章連結,供大家學習。
一個元件引入,無非就以下幾件事情:
引入依賴包。
相關yml配置(即檔案配置)。
上手方式:要麼使用檔案配置方式、要麼使用java api(如果有其它的再說,目前我知道就這兩種),然後就完事了。
3.gateway能為微服務提供什麼安全性保障?
Spring Cloud Gateway為我們提供了什麼服務?由上面微服務架構圖,我們可以看出移動客戶端、管理後臺訪問微服務1、2、3介面必須經過gateway。gateway作為中介軟體,它的核心方法是filter,它就可以做以下幾件事情:
按照自定的過濾方式進行攔截,符合約定的就可以透過或者被攔截。這樣亂七八糟的介面就不能訪問了嘛,這樣就可以保證服務微服務的安全性。
既然能攔截到一切介面,那就可以對一些熱點介面,做一些限流操作,比如a介面在一分鐘內訪問次數超過2萬次,我們就讓他降級,讓它響應其它事件。
容錯處理,請求有問題,就做一些特殊回撥。
其它呀,反正介面都流經過你這裡,你想怎麼玩就怎麼玩咯。
我曾經寫過的一些Spring Cloud Gateway文章:
Spring Cloud之Gateway(一):基本瞭解及謂詞詳解
Spring Cloud之Gateway(二):閘道器過濾器
Spring Cloud之Gateway(三):全域性過濾器
Spring Cloud之Gateway(四):TLS/SSL、配置、跨域訪問配置、執行器API、開發人員指南及MVC或Webflux搭建Gateway
四.oauth2.0
oauth2.0按照gateway方式,我們同樣從以下三個問題分析一下:
1.oauth2.0是什麼?
OAuth2.0協議為使用者資源的授權提供了一個安全又簡易的標準。與以往的授權方式不同之處是 OAuth的授權不會使第三方觸及到使用者的帳號資訊(如使用者名稱與密碼),即第三方無需使用使用者的使用者名稱與密碼就可以申請獲得該使用者資源的授權,因此 OAuth2.0是安全的。
2.oauth2.0怎麼用?
Spring Cloud可以使用OAuth2.0來實現多個微服務的統一認證授權,透過向OAuth2.0服務進行集中認證和授權,獲得access_token,而這個token是受其他微服務信任的,在後續的訪問中都把access_token帶過去,從而實現了微服務的統一認證授權。核心功能主要是以下兩點:
其一是認證與鑑權,對於請求的使用者身份的授權以及合法性鑑權;
其二是API級別的操作許可權控制,這個在第一點之後,當鑑定完使用者身份合法之後,對於該使用者的某個具體請求是否具有該操作執行許可權進行校驗。
OAuth 2.0定義了四種授權方式。
授權碼模式(authorization code)
簡化模式(implicit)
密碼模式(resource owner password credentials)
客戶端模式(client credentials)
3.oauth2.0能為微服務提供什麼安全性保障?
由上可知,只需在訪問服務前增加OAuth2.0服務就能保證使用者的相對安全了,一個使用者能不能訪問介面,oauth2.0來做最後一道關閘。這樣就能保證微服務架構的相對安全性了。
五.其它
1.使用nginx伺服器,作用如下:
反向代理:代理我們要訪問的目標伺服器。
2.中介軟體搭建叢集。
3.其它,你來補充
-
3 # luckybm
無論你使用的是單體還是微服務架構,大多數問題都是相同的。本文重點介紹微服務架構如何影響應用程式級別的安全性。
應用程式開發人員主要負責實現安全性的四個不同方面:
1、身份驗證
驗證嘗試訪問應用程式的應用程式或人員(安全的術語叫主體)的身份。例如,應用程式通常會驗證訪問的憑據,例如使用者的 ID 和密碼,或應用程式的 API 金鑰。
2、訪問授權
驗證是否允許訪問主體對指定資料完成請求的操作。應用程式通常使用基於角色的安全性和訪問控制列表(ACL)的組合。基於角色的安全性為每個使用者分配一個或多個角色,授予他們呼叫特定操作的許可權。ACL 授予使用者或角色對特定業務物件或聚合執行操作的許可權。
3、審計
跟蹤使用者在應用中執行的所有操作,以便檢測安全問題,幫助客戶實現並強制執行合規性。
4、安全的程序間通訊
理想情況下,所有進出服務的通訊都應該採用傳輸層安全性(TLS)加密。服務間通訊甚至可能需要使用身份驗證。
下面將重點介紹如何實現身份驗證和訪問授權。審計和安全的程序間通訊的更多詳細介紹請參閱Chris Richardson的《微服務架構設計模式》。
我首先描述如何在FTGO單體應用程式中實現安全性。然後介紹在微服務架構中實現安全性所面臨的挑戰,以及為何在單體架構中執行良好的技術不能在微服務架構中使用。之後,我將介紹如何在微服務架構中實現安全性。
讓我們首先回顧一下FTGO單體應用程式如何處理安全性。
一、傳統單體應用程式的安全性
FTGO應用程式有多種使用者,包括消費者、送餐員和餐館員工。他們使用基於瀏覽器的Web 應用程式和移動應用程式訪問FTGO。所有 FTGO 使用者都必須登入才能訪問該應用程式。圖 1顯示了單體FTGO 應用程式的客戶端如何驗證和發出請求。
圖1 FTGO 應用程式的客戶首先登入以獲取會話令牌,該令牌通常是 cookie。客戶在向FTGO 應用程式發出的每個後續請求中都會包括會話令牌
當用戶使用其使用者ID和密碼登入時,客戶端會向FTGO應用程式發出包含使用者憑據的POST 請求。FTGO 應用程式驗證憑據並將會話令牌返回給客戶端。客戶端在 FTGO 應用程式的每個後續請求中包含會話令牌。
圖2顯示了FTGO應用程式如何實現安全性。FTGO 應用程式是用 Java 編寫的,並使用 Spring Security 框架,但我將使用同樣也適用於其他框架(例如 Passport for Node.js)的一般性術語來描述這個設計。
圖2 當 FTGO 應用程式的客戶端發出登入請求時,登入處理程式會對使用者進行身份驗證,初始化會話使用者資訊,並返回會話令牌 cookie,以便安全地識別會話。接下來,當客戶端發出包含會話令牌的請求時,SessionBasedSecurityInterceptor 從指定的會話中檢索使用者資訊並建立安全上下文。請求處理程式(如OrderDetailsRequestHandler)從安全上下文中檢索使用者資訊
使用安全框架
正確實現身份驗證和訪問授權具有挑戰性。最好使用經過驗證的安全框架。使用哪個框架取決於你的應用程式的技術棧。流行的框架包括以下幾個:
1、SpringSecurity
適用於Java應用程式的流行框架。它是一個複雜的框架,可以處理身份驗證和訪問授權。
2、ApacheShiro
另一個 Java 安全框架。
3、Passport
在Node.js應用程式流行的一個專注於身份驗證的安全框架。
安全架構的一個關鍵部分是會話,它儲存主體的 ID 和角色。FTGO 應用程式是傳統的Java EE 應用程式,因此會話是 HttpSession 記憶體中會話。會話令牌代表著每一個具體的會話,客戶端在每個請求中包含會話令牌。
它通常是一串無法讀懂的數字標記,例如經過加密的強隨機數。FTGO 應用程式的會話令牌是一個名為JSESSIONID的HTTP cookie。
實現安全性的另一個關鍵是安全上下文,它儲存有關發出當前請求的使用者的資訊。Spring Security 框架使用標準的 Java EE 方法將安全上下文儲存在靜態的執行緒區域性變數中,任何被呼叫以處理請求的程式碼都可以訪問該變數。
請求處理程式可以呼叫 SecurityContextHolder. getContext().getAuthentication() 獲取有關當前使用者的資訊,例如他們的身份和角色。相反,Passport框架將安全上下文儲存為request物件的user屬性。
圖2 中顯示的事件序列如下:
1.客戶端向 FTGO 應用程式發出登入請求。
2.登入請求由 LoginHandler 處理,LoginHandler 驗證憑據,建立會話,並在會話中儲存有關主體的資訊。
3.Login Handler 將會話令牌返回給客戶端。
4.客戶端在後續每次呼叫請求中都包含會話令牌。
5.這些請求首先由 SessionBasedSecurityInterceptor 處理。攔截器透過驗證會話令牌來驗證每個請求並建立安全上下文。安全上下文描述了主體及其角色。
6.請求處理程式使用安全上下文來獲取其身份,並藉此確定是否允許使用者執行請求的操作。
FTGO 應用程式使用基於角色的授權。它定義了與不同型別使用者相對應的幾個角色,包括 CONSUMER、RESTAURANT、COURIER和ADMIN。它使用Spring Security的宣告性安全機制來限制對特定角色的 URL 和服務方法的訪問。角色也與業務邏輯交織在一起。例如,消費者只能訪問自己的訂單,而管理員可以訪問所有訂單。
單體FTGO應用程式使用的安全設計只是實現安全性的一種可能方式。例如,使用記憶體中會話的一個缺點是,它必須把特定會話的所有請求路由到同一個應用程式例項。這個要求使負載均衡和操作變複雜了。
例如,你必須實現會話耗盡機制,該機制在關閉應用程式例項之前等待所有會話到期(以免丟失記憶體中已有的會話)。避免這些問題的另一種方法是將會話儲存在資料庫中。
開發者可以完全不儲存伺服器端會話。例如,許多應用程式都有 API 客戶端,可以在每個請求中提供其憑據,例如 API 金鑰和私鑰。因此,無須維護伺服器端會話。
或者,應用程式可以將會話狀態儲存在會話令牌中。在本文的後面,我將介紹一種使用會話令牌儲存會話狀態的方法。但讓我們首先看一下在微服務架構中實現安全性的挑戰。
二、在微服務架構中實現安全性
微服務架構是分散式架構。每個外部請求都由API Gateway和至少一個服務處理。例如,考慮getOrderDetails()查詢。API Gateway 透過呼叫多個服務來處理此查詢,包括Order Service、Kitchen Service 和 Accounting Service。每項服務都必須實現安全性的某些方面。
例如,Order Service必須只允許消費者檢視他們自己的訂單,這需要結合身份驗證和訪問授權。為了在微服務架構中實現安全性,我們需要確定誰負責驗證使用者身份以及誰負責訪問授權。
在微服務應用程式中實現安全性的一個挑戰是我們不能僅僅從單體應用程式借鑑設計思路。這是因為單體應用程式的安全架構的一些方面對微服務架構來說是不可用的,例如:
1、記憶體中的安全上下文
使用記憶體中的安全上下文(如ThreadLocal)來傳遞使用者身份。服務無法共享記憶體,因此它們無法使用記憶體中的安全上下文(如ThreadLocal)來傳遞使用者身份。在微服務架構中,我們需要一種不同的機制來將使用者身份從一個服務傳遞到另一個服務。
2、集中會話
因為記憶體中的安全上下文沒有意義,記憶體會話也沒有意義。從理論上講,多種服務可以訪問基於資料庫的會話,但它會違反松耦合的原則。我們需要在微服務架構中使用不同的會話機制。
讓我們透過研究如何處理身份驗證來開始探索微服務架構中的安全性。
由 API Gateway 處理身份驗證
處理身份驗證有兩種不同的方法。一種選擇是讓各個服務分別對使用者進行身份驗證。這種方法的問題在於它允許未經身份驗證的請求進入內部網路。它依賴於每個開發團隊在所有服務中正確實現安全性。因此,出現安全漏洞的風險和機率都很大。
在服務中實現身份驗證的另一個問題是不同的客戶端以不同的方式進行身份驗證。純API客戶端使用基本身份驗證為每個請求提供憑據。其他客戶端可能首先登入,然後為每個請求提供會話令牌。但我們要避免在服務中處理多種不同的身份驗證機制。
更好的方法是讓API Gateway在將請求轉發給服務之前對其進行身份驗證。在API Gateway 中進行集中API身份驗證的優勢在於只需要確保這裡的驗證是正確的。因此,出現安全漏洞的可能性要小得多。另一個好處是隻有API Gateway需要處理各種不同的身份驗證機制。這使得其他服務的實現變得簡單了。
圖3 顯示了這種方法的工作原理。客戶端使用 API Gateway進行身份驗證。API 客戶端在每個請求中包含憑據。基於登入的客戶端將使用者的憑據傳送到API Gateway進行身份驗證,並接收會話令牌。一旦API Gateway驗證了請求,它就會呼叫一個或多個服務。
圖3 API Gateway 對來自客戶端的請求進行身份驗證,並在其對服務的請求中包含安全令牌。服務使用令牌獲取有關主體的資訊。API Gateway 還可以將安全令牌用作會話令牌
模式:訪問令牌
API Gateway 將包含使用者資訊(例如其身份和角色)的令牌傳遞給它呼叫的服務。請參閱:http://microservices.io/patterns/security/access-token.html。
API Gateway 呼叫的服務需要知道發出請求的主體(使用者的身份)。它還必須驗證請求是否已經過透過身份驗證。解決方案是讓 API Gateway 在每個服務請求中包含一個令牌。服務使用令牌驗證請求,並獲取有關主體的資訊。API Gateway 還可以為面向會話的客戶端提供相同的令牌,以用作會話令牌。
客戶端的事件序列如下:
1. 客戶端發出包含憑據的請求給 API Gateway。
2. API Gateway 對憑據進行身份驗證,建立安全令牌,並將其傳遞給服務。
基於登入的客戶端的事件序列如下:
1.客戶端發出包含憑據的登入請求。
2.API Gateway 返回安全令牌。
3.客戶端在呼叫操作的請求中包含安全令牌。
讓我們首先看一下安全性的另一個主要方面:訪問授權。
處理訪問授權
驗證客戶端的憑據很重要,但這還不夠。應用程式還必須實現訪問授權機制,以驗證是否允許客戶端執行所請求的操作。例如,在FTGO應用程式中,getOrderDetails()查詢只能由下此 Order 的消費者(基於例項的安全性的一個示例)和為所有消費者提供服務的客戶服務代表呼叫。
與身份驗證一樣,在API Gateway中集中實現訪問授權可降低安全漏洞的風險。你可以使用安全框架(如 Spring Security)在API Gateway中實現訪問授權。
在 API Gateway 中實現訪問授權的一個弊端是,它有可能產生API Gateway與服務之間的耦合,要求它們以同步的方式進行程式碼更新。而且,API Gateway通常只能實現對URL路徑的基於角色的訪問。由 API Gateway 實現對單個領域物件的訪問授權通常是不實際的,因為這需要詳細瞭解服務的領域邏輯。
另一個實現訪問授權的位置是服務。服務可以對URL和服務方法實現基於角色的訪問授權。它還可以實現 ACL 來管理對聚合的訪問。例如,在Order Service中可以實現基於角色和基於ACL的授權機制,以控制對 Order的訪問。FTGO應用程式中的其他服務也可以實現類似的訪問授權邏輯。
使用 JWT 傳遞使用者身份和角色
在微服務架構中實現安全性時,你需要確定 API Gateway應使用哪種型別的令牌來將使用者資訊傳遞給服務。有兩種型別的令牌可供選擇。一種選擇是使用不透明(無可讀性)的令牌,它們通常是一串UUID。
不透明令牌的缺點是它們會降低效能和可用性,並增加延遲。因為這種令牌的接收方必須對安全服務發起同步 RPC 呼叫,以驗證令牌並檢索使用者資訊。
另一種消除對安全服務呼叫的方法是使用包含有關使用者資訊的透明令牌。透明令牌的一個流行的標準是 JSON Web令牌(JWT)。JWT是在訪問雙方之間安全地傳遞資訊(例如使用者身份和角色)的標準方式。
JWT 的內容包含一個JSON物件,其中有使用者的資訊,例如其身份和角色,以及其他元資料,如到期日期等。它使用僅為JWT的建立者所知的數字簽名,例如 API Gateway和JWT的接收者(服務)。該簽名確保惡意第三方不能偽造或篡改JWT。
因為不需要再訪問安全服務進行驗證,JWT的一個問題是這個令牌是自包含的,也就是說它是不可撤消的。根據設計,服務將在驗證 JWT 的簽名和到期日期之後執行請求操作。
因此,沒有切實可行的方法來撤消落入惡意第三方手中的某個JWT令牌。解決方案是釋出具有較短到期時間的 JWT,這可以限制惡意方。但是,短期JWT的一個缺點是應用程式必須以某種方式不斷重新發布JWT以保持會話活動。幸運的是,這是 OAuth 2.0 安全標準旨在解決的眾多問題之一。讓我們來看看它是如何工作的。
在微服務架構中使用OAuth 2.0
假設你要為FTGO應用程式實現一個User Service,該應用程式管理包含使用者資訊(如憑據和角色)的資料庫。API Gateway 呼叫User Service 來驗證客戶端請求並獲取JWT。你可以設計User Service的API並使用你喜歡的Web框架實現它。但這不是FTGO應用程式特有的通用功能,自己開發此類服務往往是得不償失的。
幸運的是,你不需要開發這種安全基礎設施。你可以使用名為OAuth 2.0的標準的現成服務或框架。OAuth 2.0 是一種訪問授權協議,最初旨在使公共雲服務(如GitHub或Google)的使用者能夠授予第三方應用程式訪問其資訊的許可權,而不必向第三方應用透露他們的密碼。例如,OAuth 2.0使你能夠安全地授予第三方基於雲的持續整合(CI)服務,訪問你的GitHub儲存庫。
雖然 OAuth 2.0 最初的重點是授權訪問公共雲服務,但你也可以將其用於應用程式中的身份驗證和訪問授權。讓我們快速瞭解一下微服務架構如何使用 OAuth 2.0。
OAuth 2.0 中的關鍵概念如下:
1、授權伺服器:提供用於驗證使用者身份以及獲取訪問令牌和重新整理令牌的 API。Spring OAuth是一個很好的用來構建OAuth 2.0授權伺服器的框架。
2、訪問令牌:授予對資源伺服器的訪問許可權的令牌。訪問令牌的格式取決於具體的實現技術。Spring OAuth 的實現中採用了JWT格式的訪問令牌。
3、重新整理令牌:客戶端用於獲取新的AccessToken的長效但同時也可被可撤消的令牌。
4、資源伺服器:使用訪問令牌授權訪問的服務。在微服務架構中,服務是資源伺服器。
5、客戶端:想要訪問資源伺服器的客戶端。在微服務架構中,API Gateway 是OAuth 2.0客戶端。
首先,我們來談談如何驗證API客戶端,然後介紹如何支援基於登入的客戶端。
圖 4 顯示了API Gateway如何驗證來自API客戶端的請求。API Gateway透過向OAuth 2.0授權伺服器發出請求來驗證API客戶端,該伺服器返回訪問令牌。然後,API Gateway將包含訪問令牌的一個或多個請求傳送到服務。
圖4 API Gateway 透過向 OAuth 2.0 身份驗證伺服器發出請求來驗證 API 客戶端。身份驗證伺服器返回訪問令牌,API Gateway 將其傳遞給服務。服務驗證令牌的簽名,並提取有關使用者的資訊,包括其身份和角色
圖4 所示的事件順序如下:
1、客戶端發出請求,使用基本身份驗證提供它的憑據。
2、API Gateway 向 OAuth 2.0 身份驗證伺服器發出 OAuth 2.0 密碼授予(Password Grant)請求(http://www.oauth.com/oauth2-servers/access-tokens/password-grant/)。
3、身份驗證伺服器驗證 API 客戶端的憑據,並返回訪問令牌和重新整理令牌。
4、API Gateway 在其對服務的請求中包含訪問令牌。服務驗證訪問令牌並使用它來授權請求。
基於 OAuth 2.0 的API Gateway可以使用OAuth 2.0訪問令牌作為會話令牌來驗證面向會話的客戶端。而且,當訪問令牌到期時,它可以使用重新整理令牌獲得新的訪問令牌。
圖5顯示了API Gateway如何使用OAuth 2.0來處理面向會話的客戶端。API客戶端透過將其憑據(傳送 POST)到API Gateway的/login 端點來啟動會話。API Gateway 向客戶端返回訪問令牌和重新整理令牌。然後,API客戶端在向API Gateway發出請求時提供這兩個令牌。
圖5 客戶端透過將其憑據傳送到 API Gateway 來登入。API Gateway 使用 OAuth 2.0 身份驗證伺服器對憑據進行身份驗證,並將訪問令牌和重新整理令牌作為 cookie 返回。客戶端在其對 API Gateway 的請求中包括這些令牌
事件順序如下:
1. 基於登入的客戶端將其憑據傳送到 API Gateway。
2. API Gateway的LoginHandler向OAuth 2.0身份驗證伺服器發出密碼授予請求(www. http://oauth.com/oauth2-servers/access-tokens/password-grant/)。
3. 身份驗證伺服器驗證客戶端的憑據,並返回訪問令牌和重新整理令牌。
4. API Gateway 將訪問令牌和重新整理令牌返回給客戶端,通常是採用 cookie 的形式。
5. 客戶端在向 API Gateway 發出的請求中包含訪問令牌和重新整理令牌。
6. API Gateway 的 Session Authentication Interceptor 驗證訪問令牌,並將其包含在對服務的請求中。
如果訪問令牌已經過期或即將過期,API Gateway 將透過發出 OAuth 2.0 重新整理授權請求來獲取新的訪問令牌(http://www.oauth.com/oauth2-servers/access-tokens/refresh-access-tokens/),重新整理授權請求傳送給授權伺服器,請求中包含重新整理令牌。如果重新整理令牌尚未過期或未被撤消,則授權伺服器將返回新的訪問令牌。API Gateway 將新的訪問令牌傳遞給服務並將其返回給客戶端。
使用 OAuth 2.0 的一個重要好處是它是經過驗證的安全標準。使用現成的 OAuth 2.0 身份驗證伺服器意味著你不必浪費時間重新發明輪子或者是沒有開發不安全的設計的風險。
但OAuth 2.0 不是在微服務架構中實現安全性的唯一方法。無論你使用哪種方法,三個關鍵思想如下:
1、API Gateway 負責驗證客戶端的身份。
2、API Gateway 和服務使用透明令牌(如 JWT)來傳遞有關主體的資訊。
3、服務使用令牌獲取主體的身份和角色。
回覆列表
保護微服務
實現一個微服務很難。部署一個微服務應用程式複雜性也很高。保護微服務的安全就更難更復雜。從哪裡開始呢?腦海中首先出現的一些詞是身份驗證和授權、防火牆、授信、會話、令牌。我們需要保護應用程式的安全,也需要保護容器的安全。
保護應用程式
一種方法是構建一個單點登入(SSO)閘道器,像普通的閘道器一樣,它位於應用程式的前端,但需要考慮到其與SSO伺服器的握手,並執行URL重定向操作。可以用http報文頭傳送授權和認證資訊給服務。但是除非使用https,否則這樣做是不安全的。但是我們知道https有證書,維護多個微服務的證書可能會成為問題,尤其是需要補發或撤銷這些證書的時候,複雜性將進一步增加,我們儘量避免這種情況。
另一種方法是用HMAC(基於雜湊的訊息程式碼)。這個請求的主體帶有雜湊私鑰,結果是隨著請求傳送的。然後,伺服器透過使用其私鑰和請求主體的副本重新建立雜湊,並將其與接收到的雜湊進行比較。如果一切都匹配,那就意味著訊息沒有被篡改,請求可以透過。這種模式由JWT(Json Web Tokens)實現。但是,事實上網路偵聽器仍然可以看到資料。
Twitter,Google等使用API金鑰。使用API金鑰,服務可以識別誰在呼叫,並可以對其設定限制。金鑰是成對的(公鑰和私鑰),它們必須集中管理。
假定一切都準備就緒了,但是還是有一個問題,如何確保使用者無法訪問其他使用者的資料呢?那就需要做更多的限制,可以透過限定使用者只能訪問他自己的資料來保護我們的服務,但是將導致在許多地方產生大量的樣板程式碼。不幸的是,沒有更好的辦法。微服務意味著複雜性和一些重複預期會被減少。
還是沒有解決嗅探器(sniffer,也叫資料抓包軟體)的問題。怎樣才能確保sniffer看不到資料呢。答案是加密。先加密,然後根據需要進行解密。這就是微服務複雜系統的另一個元件:金鑰服務。
有很多庫可以用,最好的選擇是使用成熟的庫,如OAuth或SAML。
服務可以有狀態引數。為閘道器中初始化的所有服務保持一個全域性會話,並將其傳播到所有其它服務。會話可以從像KeyCloak這樣的中央認證和授權伺服器(SSO)獲得。
我們更希望服務沒有狀態引數。這意味著需要將狀態從伺服器轉移到客戶端。Json的 Web令牌(JWT)非常符合這種需求。這是一種在雙方之間轉移宣告的安全方式。基本上它的一個json作為Json Web簽名(JWS)的主體或Json Web加密(JWE)的明文傳遞。宣告可以進行數字簽名,幷包含發行者,使用者的身份,到期時間,還可以包含自定義屬性。
舉一個例子,流程看起來如下圖:
客戶端應用程式將與UAA(使用者認證和授權)伺服器進行互動。它為包含一個JWT令牌的重定向URL交換其證書。令牌將提交到閘道器,在UAA伺服器進行驗證。如果一切正常,它會將該JWT令牌轉發到所請求的服務,將會解碼它並授予其對所請求資源的訪問許可權。
保護容器
現在已經知道如何保護應用程式了,是時候關注容器的安全了。Docker是一個廣泛使用的容器。可以做些什麼來保護它們呢?
答案是深度防禦。這意味著需要防火牆;這意味著需要小心記錄在日誌中的資訊(被攻擊後,日誌有助於快速恢復系統);這意味著需要監視叢集的可疑行為(入侵檢測系統和入侵防禦系統);這意味著需要將服務分開並將它們放在不同的位置(虛擬私有云),並建立一組規則,確保它們仍然能夠相互通訊;這意味著保持作業系統更新(特別是安全更新)。
Aaron Grattafiori在Docker Con 2016年的演講中談到三個原則:
最小許可權原則,這意味著不以root身份執行應用程式最小意外原則最小訪問原則,這意味著每個模組只能訪問與其相關的資料這裡有篇文章有更多的相關細節。假設已經遵循了上述三原則,想到的下一個問題是:使用的Docker影象安全嗎?怎麼知道它們沒有包含惡意程式碼呢?幸運的是,在Docker 1.8中引入了Docker Content Trust ,與此同時,Docker影象的釋出者在將其推送到登錄檔之前進行了驗證。
保護Docker安全的一個有用的工具是Calico。每個Docker網路都有Calico配置檔案,必須設定規則和策略以控制流量。更多相關內容看這裡。
現在你應該有足夠的資訊來啟動你的微服務安全保護了。