微服務架構之「 訪問安全 」


應用程序的訪問安全又是我們每一個研發團隊都必須關注的重點問題。尤其是在我們采用了微服務架構之后,項目的復雜度提升了N個級別,相應的,微服務的安全工作也就更難更復雜了。並且我們以往擅長的單體應用的安全方案對於微服務來說已經不再適用了。我們必須有一套新的方案來保障微服務架構的安全。

在探索微服務訪問安全之前,我們還是先來回顧一下單體應用的安全是如何實現的。

一、傳統單體應用如何實現「訪問安全」?

下圖就是一個傳統單體應用的訪問示意圖:

(圖片來自WillTran在slideshare分享)

在應用服務器里面,我們有一個auth模塊(一般采用過濾來實現),當有客戶端請求進來時,所有的請求都必須首先經過這個auth來做身份驗證,驗證通過后,才將請求發到后面的業務邏輯。

通常客戶端在第一次請求的時候會帶上身份校驗信息(用戶名和密碼),auth模塊在驗證信息無誤后,就會返回Cookie存到客戶端,之后每次客戶端只需要在請求中攜帶Cookie來訪問,而auth模塊也只需要校驗Cookie的合法性后決定是否放行。

可見,在傳統單體應用中的安全架構還是蠻簡單的,對外也只有一個入口,通過auth校驗后,內部的用戶信息都是內存/線程傳遞,邏輯並不是復雜,所以風險也在可控范圍內。

那么,當我們的項目改為微服務之后,「訪問安全」又該怎么做呢。

二、微服務如何實現「訪問安全」?

在微服務架構下,有以下三種方案可以選擇,當然,用的最多的肯定還是OAuth模式。

  • 網關鑒權模式(API Gateway)

  • 服務自主鑒權模式

  • API Token模式(OAuth2.0)

下面分別來講一下這三種模式:

  1. 網關鑒權模式(API Gateway)

    (圖片來自WillTran在slideshare分享)

    通過上圖可見,因為在微服務的最前端一般會有一個API網關模塊(API Gateway),所有的外部請求訪問微服務集群時,都會首先通過這個API Gateway,所以我們可以在這個模塊里部署auth邏輯,實現統一集中鑒權,鑒權通過后,再把請求轉發給后端各個服務。

    這種模式的優點就是,由API Gateway集中處理了鑒權的邏輯,使得后端各微服務節點自身邏輯就簡單了,只需要關注業務邏輯,無需關注安全性事宜。

    這個模式的問題就是,API Gateway適用於身份驗證和簡單的路徑授權(基於URL的),對於復雜數據/角色的授權訪問權限,通過API Gateway很難去靈活的控制,畢竟這些邏輯都是存在后端服務上的,並非存儲在API Gateway里。

  2. 服務自主鑒權模式

    (圖片來自WillTran在slideshare分享)

    服務自主鑒權就是指不通過前端的API Gateway來控制,而是由后端的每一個微服務節點自己去鑒權。

    它的優點就是可以由更為靈活的訪問授權策略,並且相當於微服務節點完全無狀態化了。同時還可以避免API Gateway 中 auth 模塊的性能瓶頸。

    缺點就是由於每一個微服務都自主鑒權,當一個請求要經過多個微服務節點時,會進行重復鑒權,增加了很多額外的性能開銷。

  3. API Token模式(OAuth2.0)

    (圖片來自網絡)

    如圖,這是一種采用基於令牌Token的授權方式。在這個模式下,是由授權服務器(圖中Authorization Server)、API網關(圖中API Gateway)、內部的微服務節點幾個模塊組成。

    流程如下:

    第一步:客戶端應用首先使用賬號密碼或者其它身份信息去訪問授權服務器(Authorization Server)獲取 訪問令牌(Access Token)。

    第二步:拿到訪問令牌(Access Token)后帶着它再去訪問API網關(圖中API Gateway),API Gateway自己是無法判斷這個Access Token是否合法的,所以走第三步。

    第三步:API Gateway去調用Authorization Server校驗一下Access Token的合法性。

    第四步:如果驗證完Access Token是合法的,那API Gateway就將Access Token換成JWT令牌返回。

    (注意:此處也可以不換成JWT而是直接返回原Access Token。但是換成JWT更好,因為Access Token是一串不可讀無意義的字符串,每次驗證Access Token是否合法都需要去訪問Authorization Server才知道。但是JWT令牌是一個包含JOSN對象,有用戶信息和其它數據的一個字符串,后面微服務節點拿到JWT之后,自己就可以做校驗,減少了交互次數)。

    第五步:API Gateway有了JWT之后,就將請求向后端微服務節點進行轉發,同時會帶上這個JWT。

    第六步:微服務節點收到請求后,讀取里面的JWT,然后通過加密算法驗證這個JWT,驗證通過后,就處理請求邏輯。

    這里面就使用到了OAuth2.0的原理,不過這只是OAuth2.0各類模式中的一種。

由於OAuth2.0目前最為常用,所以接下來我再來詳細講解一下OAuth2.0的原理和各類用法。

三、詳解 OAuth2.0 的「 訪問安全 」?

OAuth2.0是一種訪問授權協議框架。它是基於Token令牌的授權方式,在不暴露用戶密碼的情況下,使 應用方 能夠獲取到用戶數據的訪問權限。

例如:你開發了一個視頻網站,可以采用第三方微信登陸,那么只要用戶在微信上對這個網站授權了,那這個網站就可以在無需用戶密碼的情況下獲取用戶在微信上的頭像。

OAuth2.0 的流程如下圖:

OAuth2.0 里的主要名詞有:

  • 資源服務器:用戶數據/資源存放的地方,在微服務架構中,服務就是資源服務器。在上面的例子中,微信頭像存放的服務就是資源服務器。

  • 資源擁有者:是指用戶,資源的擁有人。在上面的例子中某個微信頭像的用戶就是資源擁有者。

  • 授權服務器:是一個用來驗證用戶身份並頒發令牌的服務器。

  • 客戶端應用:想要訪問用戶受保護資源的客戶端/Web應用。在上面的例子中的視頻網站就是客戶端應用。

  • 訪問令牌:Access Token,授予對資源服務器的訪問權限額度令牌。

  • 刷新令牌:客戶端應用用於獲取新的 Access Token 的一種令牌。

  • 客戶憑證:用戶的賬號密碼,用於在 授權服務器 進行驗證用戶身份的憑證。

OAuth2.0有四種授權模式,也就是四種獲取令牌的方式:授權碼、簡化式、用戶名密碼、客戶端憑證。

下面來分別講解一下:

  1. 授權碼(Authorization Code)

    授權碼模式是指:客戶端應用先去申請一個授權碼,然后再拿着這個授權碼去獲取令牌的模式。這也是目前最為常用的一種模式,安全性比較高,適用於我們常用的前后端分離項目。通過前端跳轉的方式去訪問 授權服務器 獲取授權碼,然后后端再用這個授權碼訪問 授權服務器 以獲取 訪問令牌。

    流程如上圖。

    第一步,客戶端的前端頁面(圖中UserAgent)將用戶跳轉到 授權服務器(Authorization Server)里進行授權,授權完成后,返回 授權碼(Authorization Code)

    第二步,客戶端的后端服務(圖中Client)攜帶授權碼(Authorization Code)去訪問 授權服務器,然后獲得正式的 訪問令牌(Access Token)

    頁面的前端和后端分別做不同的邏輯,前端接觸不到Access Token,保證了Access Token的安全性。

  2. 簡化式(Implicit)

    簡化模式是在項目是一個純前端應用,在沒有后端的情況下,采用的一種模式。

    因為這種方式令牌是直接存在前端的,所以非常不安全,因此令牌的有限期設置就不能太長。

    其流程就是:

    第一步:應用(純前端的應用)將用戶跳轉到 授權服務器(Authorization Server)里進行授權,授權完成后,授權服務器 直接將 Access Token 返回給 前端應用,令牌存儲在前端頁面。

    第二步:應用(純前端的應用)攜帶 訪問令牌(Access Token) 去訪問資源,獲取資源。

    在整個過程中,雖然令牌是在前端URL中直接傳遞,但注意,令牌在HTTP協議中不是放在URL參數字段中的,而是放在URL錨點里。因為錨點數據不會被瀏覽器發到服務器,因此有一定的安全保障。

  3. 用戶名密碼(Resource Owner Credentials)

    這種方式最容易理解了,直接使用用戶的用戶名/密碼作為授權方式去訪問 授權服務器,從而獲取Access Token,這個方式因為需要用戶給出自己的密碼,所以非常的不安全性。一般僅在客戶端應用與授權服務器、資源服務器是歸屬統一公司/團隊,互相非常信任的情況下采用。

  4. 客戶端憑證(Client Credentials)

    這是適用於服務器間通信的場景。客戶端應用拿一個用戶憑證去找授權服務器獲取Access Token。

以上,就是對微服務架構中「訪問安全」的一些思考。

在微服務架構的系列文章中,前面已經通過文章介紹過了「服務注冊 」、「服務網關 」、「配置中心 」、「 監控系統 」、「調用鏈監控」、「容錯隔離」,大家可以翻閱歷史文章查看。

碼字不易啊,喜歡的話不妨轉發朋友,或點擊文章右下角的“在看”吧。😊

本文原創發布於微信公眾號「 不止思考 」,歡迎關注。涉及 思維認知、個人成長、架構、大數據、Web技術 等。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM