日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
細說API–認證、授權(quán)和憑證

 在一些互聯(lián)網(wǎng)公司的面試中,面試官往往會問這樣一個問題:

創(chuàng)新互聯(lián)公司專注于懷仁企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),商城建設(shè)。懷仁網(wǎng)站建設(shè)公司,為懷仁等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站設(shè)計,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)

“如果禁用瀏覽器 cookie,如何實現(xiàn)用戶追蹤和認證?”

遺憾的是依然有大量候選人答非所問,無法搞清楚 cookie 和 session 之間的區(qū)別。而在工作中也有讓人驚訝的真實案例:把 user ID 存儲到 local storage 中當做 token 使用,原因是他們聲稱棄用了 cookie 這種落后的東西;一個移動端項目,服務(wù)器給出的 API 中需要客戶端模擬一個 cookie,從而像瀏覽器中 ajax 那樣消費 API。

互聯(lián)網(wǎng)是基于 HTTP 協(xié)議構(gòu)建的,而 HTTP 協(xié)議因為簡單流行開來,但是 HTTP 協(xié)議是無狀態(tài)(通信層面上虛電路比數(shù)據(jù)報昂貴太多)的,為此人們?yōu)榱俗粉櫽脩粝氤隽烁鞣N辦法,包括 cookie/session 機制、token、flash 跨瀏覽器 cookie 甚至瀏覽器指紋等。

 

把用戶身份藏在每一個地方(瀏覽器指紋技術(shù)甚至不需要存儲介質(zhì))

講使用 spring security 等具體技術(shù)的資料已經(jīng)很多了,這篇文章不打算寫框架和代碼的具體實現(xiàn)。我們會討論認證和授權(quán)的區(qū)別,然后會介紹一些被業(yè)界廣泛采用的技術(shù),下面會聊聊怎么為 API 構(gòu)建選擇合適的認證方式。

認證、授權(quán)、憑證

首先,認證和授權(quán)是兩個不同的概念,為了讓我們的 API 更加安全和具有清晰的設(shè)計,理解認證和授權(quán)的不同就非常有必要了,它們在英文中也是不同的單詞。

 

認證是 authentication,指的是當前用戶的身份,當用戶登陸過后系統(tǒng)便能追蹤到他的身份做出符合相應(yīng)業(yè)務(wù)邏輯的操作。即使用戶沒有登錄,大多數(shù)系統(tǒng)也會追蹤他的身份,只是當做來賓或者匿名用戶來處理。認證技術(shù)解決的是 “我是誰?”的問題。

授權(quán)則不同,授權(quán)是 authorization,指的是什么樣的身份被允許訪問某些資源,在獲取到用戶身份后繼續(xù)檢查用戶的權(quán)限。單一的系統(tǒng)授權(quán)往往是伴隨認證來完成的,但是在開放 API 的多系統(tǒng)結(jié)構(gòu)下,授權(quán)可以由不同的系統(tǒng)來完成,例如 OAuth。授權(quán)技術(shù)是解決“我能做什么?”的問題。

實現(xiàn)認證和授權(quán)的基礎(chǔ)是需要一種媒介(credentials)來標記訪問者的身份或權(quán)利,在現(xiàn)實生活中每個人都需要一張證明身份的證件才能訪問自己的銀行賬戶、結(jié)婚和辦理養(yǎng)老保險等,這就是認證的憑證;在古代軍事活動中,皇帝會給出戰(zhàn)的將軍頒發(fā)兵符,下級將領(lǐng)不關(guān)心持有兵符的人,只需要執(zhí)行兵符對應(yīng)的命令即可。在互聯(lián)網(wǎng)世界中,服務(wù)器為每一個訪問者頒發(fā) session ID 存放到 cookie,這就是一種憑證技術(shù)。數(shù)字憑證還表現(xiàn)在方方面面,SSH 登錄的密匙、JWT 令牌、一次性密碼等。

用戶賬戶也不一定是存放在數(shù)據(jù)庫中的一張表,在一些企業(yè) IT 系統(tǒng)中,對賬戶管理和權(quán)限有了更多的要求。所以賬戶技術(shù) (accounting)可以幫助我們使用不同的方式管理用戶賬戶,同時具有不同系統(tǒng)之間共享賬戶的能力。例如微軟的活動目錄(AD),以及簡單目錄訪問協(xié)議(LDAP),甚至區(qū)塊鏈技術(shù)。

還有一個重要的概念是訪問控制策略(AC)。如果我們需要把資源的權(quán)限劃分到一個很細的粒度,就不得不考慮用戶以何種身份來訪問受限的資源,選擇基于訪問控制列表(ACL)還是基于用戶角色的訪問控制(RBAC)或者其他訪問控制策略。

在流行的技術(shù)和框架中,這些概念都無法孤立的被實現(xiàn),因此在現(xiàn)實中使用這些技術(shù)時,大家往往為一個 OAuth2 是認證還是授權(quán)這種概念爭論不休。為了容易理解,我在文末附上了一份常見技術(shù)和概念的術(shù)語表。下面我會介紹在API開發(fā)中常常使用的幾種認證和授權(quán)技術(shù):HTTP Basic AUthentication、HAMC、OAuth2,以及憑證技術(shù)JWT token。

HTTP Basic Authentication

你一定用過這種方式,但不一定知道它是什么,在不久之前,當你訪問一臺家用路由器的管理界面,往往會看到一個瀏覽器彈出表單,要求你輸入用戶密碼。

 

在這背后,當用戶輸入完用戶名密碼后,瀏覽器幫你做了一個非常簡單的操作:

  1. 組合用戶名和密碼然后 Base64 編碼
  2. 給編碼后的字符串添加 Basic 前綴,然后設(shè)置名稱為 Authorization 的 header 頭部

 

API 也可以非常簡單的提供 HTTP Basic Authentication 認證方式,那么客戶端可以很簡單通過 Base64 傳輸用戶名和密碼即可:

  • 將用戶名和密碼使用冒號連接,例如 username:abc123456
  • 為了防止用戶名或者密碼中存在超出 ASCII 碼范圍的字符,推薦使用UTF-8編碼
  • 將上面的字符串使用 Base 64 編碼,例如 dXNlcm5hbWU6YWJjMTIzNDU2
  • 在 HTTP 請求頭中加入 “Basic + 編碼后的字符串”,即:Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

這種方式實現(xiàn)起來非常簡單,在大量場景下被采用。當然缺點也很明顯,Base64 只能稱為編碼,而不是加密 (實際上無需配置密匙的客戶端并沒有任何可靠地加密方式,我們都依賴 TSL 協(xié)議)。這種方式的致命弱點是編碼后的密碼如果明文傳輸則容易在網(wǎng)絡(luò)傳輸中泄露,在密碼不會過期的情況下,密碼一旦泄露,只能通過修改密碼的方式。

HMAC(AK/SK)認證

在我們對接一些 PASS 平臺和支付平臺時,會要求我們預先生成一個 access key(AK) 和 安全key(SK),然后通過簽名的方式完成認證請求,這種方式可以避免傳輸安全 key,且大多數(shù)情況下簽名只允許使用一次。

這種基于 AK/SK 的認證方式主要是利用散列的消息認證碼 (Hash-based MessageAuthentication Code) 來實現(xiàn)的,因此有很多地方叫 HMAC 認證,實際上不是非常準確。HMAC 只是利用帶有 key 值的哈希算法生成消息摘要,在設(shè)計 API 時有具體不同的實現(xiàn)。

 

HMAC 在作為網(wǎng)絡(luò)通信的認證設(shè)計中作為憑證生成算法使用,避免了口令等敏感信息在網(wǎng)絡(luò)中傳輸?;具^程如下:

  1. 客戶端需要在認證服務(wù)器中預先設(shè)置 access key(AK 或叫 app ID) 和 SK
  2. 在調(diào)用 API 時,客戶端需要對參數(shù)和 access key 進行自然排序后并使用安全 key 進行簽名生成一個額外的參數(shù) digest
  3. 服務(wù)器根據(jù)預先設(shè)置的安全key 進行同樣的摘要計算,并要求結(jié)果完全一致
  4. 注意 SK不能在網(wǎng)絡(luò)中傳輸,以及在不受信任的位置存放(瀏覽器等)

為了讓每一次請求的簽名變得僅此一個,我們需要在簽名時放入一些干擾信息。

在業(yè)界標準中有兩種典型的做法,質(zhì)疑/應(yīng)答算法(OCRA: OATH Challenge-Response Algorithm)、基于時間的一次性密碼算法(TOTP:Time-based One-time Password Algorithm)。

質(zhì)疑/應(yīng)答算法

質(zhì)疑/應(yīng)答算法需要客戶端先請求一次服務(wù)器,獲得一個 401 未認證的返回,并得到一個隨機字符串(nonce)。將 nonce 附加到按照上面說到的方法進行 HMAC 簽名,服務(wù)器使用預先分配的 nonce 同樣進行簽名校驗,這個 nonce 在服務(wù)器只會被使用一次,因此可以提供僅此一個摘要。

 

基于時間的一次性密碼認證

為了避免額外的請求來獲取 nonce,還有一種算法是使用時間戳,并且通過同步時間的方式協(xié)商到一致,在一定的時間窗口內(nèi)有效(1分鐘左右)。

 

這里的只是利用時間戳作為驗證的時間窗口,并不能嚴格的算作基于時間的一次性密碼算法。標準的基于時間的一次性密碼算法在兩步驗證中被大量使用,例如 Google 身份驗證器不需要網(wǎng)絡(luò)通信也能實現(xiàn)驗證(但依賴準確的授時服務(wù))。原理是客戶端服務(wù)器共享密鑰然后根據(jù)時間窗口能通過 HMAC 算法計算出一個相同的驗證碼。

 

TOTP 基本原理和常見廠商

OAuth2 和 Open ID

OAuth(開放授權(quán))是一個開放標準,允許用戶授權(quán)第三方網(wǎng)站訪問他們存儲在另外的服務(wù)提供者上的信息,而不需要將用戶名和密碼提供給第三方網(wǎng)站或分享他們數(shù)據(jù)的所有內(nèi)容。

OAuth 是一個授權(quán)標準,而不是認證標準。提供資源的服務(wù)器不需要知道確切的用戶身份(session),只需要驗證授權(quán)服務(wù)器授予的權(quán)限(token)即可。

 

上圖只是 OAuth 的一個簡化流程,OAuth 的基本思路就是通過授權(quán)服務(wù)器獲取 access token 和 refresh token(refresh token 用于重新刷新access token),然后通過 access token 從資源服務(wù)器獲取數(shù)據(jù) 。在特定的場景下還有下面幾種模式:

  1. 授權(quán)碼模式(authorization code)
  2. 簡化模式(implicit)
  3. 密碼模式(resource owner password credentials)
  4. 客戶端模式(client credentials)

如果需要獲取用戶的認證信息,OAuth 本身沒有定義這部分內(nèi)容,如果需要識別用戶信息,則需要借助另外的認證層,例如 OpenID Connect。

驗證 access token

在一些介紹OAuth 的博客中很少講到資源服務(wù)器是怎么驗證 access token 的。OAuth core 標準并沒有定義這部分,不過在 OAuth 其他標準文件中提到兩種驗證 access token的方式。

在完成授權(quán)流程后,資源服務(wù)器可以使用 OAuth 服務(wù)器提供的 Introspection 接口來驗證access token,OAuth服務(wù)器會返回 access token 的狀態(tài)以及過期時間。在OAuth標準中驗證 token 的術(shù)語是 Introspection。同時也需要注意 access token 是用戶和資源服務(wù)器之間的憑證,不是資源服務(wù)器和授權(quán)服務(wù)器之間的憑證。資源服務(wù)器和授權(quán)服務(wù)器之間應(yīng)該使用額外的認證(例如 Basic 認證)。

使用 JWT 驗證。授權(quán)服務(wù)器使用私鑰簽發(fā) JWT 形式的 access token,資源服務(wù)器需要使用預先配置的公鑰校驗 JWT token,并得到 token 狀態(tài)和一些被包含在 access token 中信息。因此在 JWT 的方案下,資源服務(wù)器和授權(quán)服務(wù)器不再需要通信,在一些場景下帶來巨大的優(yōu)勢。同時 JWT 也有一些弱點,我會在JWT 的部分解釋。

refresh token 和 access token

幾乎所有人剛開始了解 OAuth 時都有一個一疑問,為什么已經(jīng)有了 access token 還需要 refresh token 呢?

授權(quán)服務(wù)器會在初次授權(quán)請求時一起返回 access token 和refresh token,在后面刷新 access token 時只需要 refresh token。 access token 和 refresh token 的設(shè)計意圖是不一樣的,access token 被設(shè)計用來客戶端和資源服務(wù)器之間交互,而 refresh token 是被設(shè)計用來客戶端和授權(quán)服務(wù)器之間交互。

某些授權(quán)模式下 access token 需要暴露給瀏覽器,充當一個資源服務(wù)器和瀏覽器之間的臨時會話,瀏覽器和資源服務(wù)器之間不存在簽名機制,access token 成為僅有憑證,因此 access token 的過期時間(TTL)應(yīng)該盡量短,從而避免用戶的 access token 遭遇威脅。

由于要求 access token 時間很短,refresh token 可以幫助用戶維護一個較長時間的狀態(tài),避免頻繁重新授權(quán)。大家會覺得讓 access token 保持一個長的過期時間不就可以了嗎?實際上 refresh token 和 access token 的不同之處在于即使 refresh token 被截獲,系統(tǒng)依然是安全的,客戶端拿著 refresh token 去獲取 access token 時同時需要預先配置的安全 key,客戶端和授權(quán)服務(wù)器之前始終存在安全的認證。

OAuth、Open ID、OpenID Connect

認證方面的術(shù)語實在太多,我在搭建自己的認證服務(wù)器或接入第三方認證平臺時,有時候到完成開發(fā)工作結(jié)束的一刻都無法理解這些術(shù)語。

OAuth 負責解決分布式系統(tǒng)之間的授權(quán)問題,即使有時候客戶端和資源服務(wù)器或者認證服務(wù)器存在同一臺機器上。OAuth 沒有解決認證的問題,但提供了良好的設(shè)計利于和現(xiàn)有的認證系統(tǒng)對接。

Open ID 解決的問題是分布式系統(tǒng)之間身份認證問題,使用Open ID token 能在多個系統(tǒng)之間驗證用戶,以及返回用戶信息,可以獨立使用,與 OAuth 沒有關(guān)聯(lián)。

OpenID Connect 解決的是在 OAuth 這套體系下的用戶認證問題,實現(xiàn)的基本原理是將用戶的認證信息(ID token)當做資源處理。在 OAuth 框架下完成授權(quán)后,再通過 access token 獲取用戶的身份。

這三個概念之間的關(guān)系有點難以理解,用現(xiàn)實場景來說,如果系統(tǒng)中需要一套獨立的認證系統(tǒng),并不需要多系統(tǒng)之間的授權(quán)可以直接采用 Open ID。如果使用了 OAuth 作為授權(quán)標準,可以再通過 OpenID Connect 來完成用戶的認證。

JWT

在 OAuth 等分布式的認證、授權(quán)體系下,對憑證技術(shù)有了更多的要求,比如包含用戶 ID、過期等信息,不需要再外部存儲中關(guān)聯(lián)。因此業(yè)界對 token 做了進一步優(yōu)化,設(shè)計了一種自包含令牌,令牌簽發(fā)后無需從服務(wù)器存儲中檢查是否合法,通過解析令牌就能獲取令牌的過期、有效等信息,這就是JWT (JSON Web Token)。

JWT 是一種包含令牌(self-contained token),或者叫值令牌 (value token),我們以前使用關(guān)聯(lián)到 session 上的 hash 值被叫做引用令牌(reference token)。

 

簡而言之,一個基本的JWT令牌為一段點分3段式結(jié)構(gòu)。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

生成JWT 令牌的流程為

 

  1. header json 的 base64 編碼為令牌前面那一部分
  2. payload json 的 base64 編碼為令牌第二部分
  3. 拼裝兩部分編碼后的 json 以及 secret 進行簽名的令牌的第三部分

因此只需要簽名的 secret key 就能校驗 JWT 令牌,如果在消息體中加入用戶 ID、過期信息就可以實現(xiàn)驗證令牌是否有效、過期了,無需從數(shù)據(jù)庫/緩存中讀取信息。因為使用了加密算法,所以兩部分即使被修改(包括過期信息)也無法通過驗證。JWT 優(yōu)點是不僅可以作為 token 使用,同時也可以承載一些必要信息,省去多次查詢。

注意:

  1. JWT token 的兩部分只是 base64 編碼,肉眼不可讀,不應(yīng)當存放敏感信息
  2. JWT token 的自包含特性,導致了無法被撤回
  3. JWT 的簽名算法可以自己擬定,為了便于調(diào)試,本地環(huán)境可以使用對稱加密算法,生產(chǎn)環(huán)境建議使用非對稱加密算法

JWT token 在微服務(wù)的系統(tǒng)中優(yōu)勢特別突出。多層調(diào)用的 API 中可以直接傳遞 JWT token,利用自包含的能力,可以減少用戶信息查詢次數(shù);更重要的是,使用非對稱的加密方式可以通過在系統(tǒng)中分發(fā)密匙的方式驗證 JWT token。

當然 OAuth 對 access token 等憑證所選用的技術(shù)并沒有做出限制,OAuth 并不強制使用 JWT,在使用 JWT 自包含特性的優(yōu)勢時,必須考慮到 JWT 撤回困難的問題。在一些對撤回 token 要求很高的項目中不適合使用JWT,即使采用了一些方案實現(xiàn)(whitelist 和 blacklist)也違背了設(shè)計 JWT 的初衷。

Cookie 、Token in Cookie、Session Token 依然被使用

在構(gòu)建 API 時,開發(fā)者會發(fā)現(xiàn)我們的認證方式和網(wǎng)頁應(yīng)用有一些不同,除了像 ajax 這種典型的 web 技術(shù)外,如果我們希望 API 是無狀態(tài)的,不推薦使用 Cookie。

使用 Cookie 的本質(zhì)是用戶初次訪問時服務(wù)器會分配一個 Session ID,后面的請求中客戶端都會帶上這個 ID 作為當前用戶的標志,因為 HTTP 本身是無狀態(tài)的,Cookie 屬于一種內(nèi)建于瀏覽器中實現(xiàn)狀態(tài)的方式。如果我們的 API 是用來給客戶端使用的,強行要求 API 的調(diào)用者管理Cookie 也可以完成任務(wù)。

在一些遺留或者不是標準的認證實現(xiàn)的項目中,我們依然可以看到這些做法,快速地實現(xiàn)認證。

使用 cookie,例如 web 項目中 ajax 的方式

使用 session ID 或 hash 作為 token,但將 token 放入 header 中傳遞

將生成的 token (可能是JWT)放入 cookie 傳遞,利用 HTTPonly 和 安全標簽保護 token

選擇合適的認證方式

隨著微服務(wù)的發(fā)展,API 的設(shè)計不僅僅是面向 WEB 或者 Mobile APP,還有BFF(Backend for Frontend)和 Domain API 的認證,以及第三方服務(wù)的集成。

客戶端到服務(wù)器之間認證和服務(wù)器到服務(wù)器之間認證是不同的。

我們把終端用戶(Human)參與的通信,叫做 Human-to-machine (H2M),服務(wù)器與服務(wù)器之間的通信叫做 Machine-to-machine (M2M)。

H2M 的通信需要更高的安全性,M2M 的通信天然比 H2M 安全,因此更多的強調(diào)性能,在不同的場合下選擇合適的認證技術(shù)就顯得特別重要。例如 HTTP Basic Authentication 用來作為 H2M 認證顯得有些落后,但是在 M2M 中被大量使用。

另外值得一提的是,H2M 這種通信方式下,客戶端不受控制,由于無法自主分發(fā)密匙,認證通信的安全高度依賴 HTTPS。

從一個宏觀的角度看待他們的關(guān)系,對我們技術(shù)選型非常有幫助。


新聞標題:細說API–認證、授權(quán)和憑證
鏈接地址:http://www.dlmjj.cn/article/djdeoej.html