前言
互聯網時代,對信息和資源的保護越發苛刻,在所有應用中授權和認證是必不可少缺少的一部分。如果一個應用沒有授權和認證那么這個應用就是不完整或者說不安全的應用。在.Net平台給我們提供了一套完整的授權認證框架,那就是IdentityServer4。它實現了OpenId Connect和OAuth2.0協議的認證授權。
授權認證
很多人喜歡把授權和認證混為一談,但是其實授權(Authorization)和認證(Authentication)是有區別的。
Authorization(授權) - 側重點是用戶能干嘛,而不關心用戶是誰。
Authentication(認證) - 側重點是用戶是誰,而不是用戶能干嘛。
OpenId
OpenID 是一個以用戶為中心的數字身份識別框架,是一個以URL為身份標識的分散式身份驗證解決方案,它具有開放、分散、自由等特性。
OpenID相關基本術語:
用戶 - 想要向某個網站表明身份的人。
標識 - 用戶用以標識其身份的URL。
身份提供者 - 提供OpenID URL注冊和驗證服務的服務提供者。
依賴方 - 想要對最終用戶的openId進行驗證的網站應用。
舉個例子, 我使用QQ(身份提供者)登陸京東(依賴方),我打開京東主頁點擊QQ登陸並不會要我輸入我的QQ賬號和密碼,會先跳轉到QQ授權登陸頁面,當你掃碼或者密碼登陸的時候QQ會返回給京東一個OpenId,京東就會拿着這個OpenId來問QQ你這里是不是有這么一個用戶。
OpenId關注的是Authentication(認證)。
OAuth2
OAuth是當下比較流行的授權第三方應用讀取用戶的資源的機制。OAuth能在不涉及到用戶的賬號信息的情況下,讀取用戶的一些資源信息。
舉個例子,每周都會有保潔阿姨來家里打掃,但是保潔阿姨並不知道我家大門的密碼,所以每次保潔阿姨在要上門的時候會在app上申請獲取一個臨時密碼,當我收到保潔阿姨的申請后,確認給予臨時密碼后保潔阿姨就能通過這個密碼進入房子啦。
我就是用戶,家,和房間就是我的資源,臨時密碼是token。阿姨是第三方應用。阿姨申請臨時密碼需要進入我的家(第三方應用申請讀取我的數據),我(用戶)收到申請后給予臨時密碼(用戶確認授權讀取數據)。阿姨收到臨時密碼進入房間(獲取到相應的token讀取數據)。
但是臨時密碼(token)還是有很多局限性的,比如時效性(規定時間內使用才有效),局限性(只能開一次門,不能進去我私人房間),我還可以在中途撤銷授權,使臨時密碼(token)無法進去我的房間(無法讀取我的數據)。
授權過程
(A)用戶打開客戶端以后,客戶端要求用戶給予授權。(阿姨打開某公寓App申請臨時密碼)
(B)用戶同意給予客戶端授權。 (我同意給予臨時密碼)
(C)客戶端使用上一步獲得的授權,向認證服務器申請令牌。 (同意后,向某某公寓后台申請臨時密碼)
(D)認證服務器對客戶端進行認證以后,確認無誤,同意發放令牌。(某某公寓后台確認我同意給予臨時密碼后,給阿姨發放臨時密碼)
(E)客戶端使用令牌,向資源服務器申請獲取資源。(阿姨使用臨時密碼來開門)
(F)資源服務器確認令牌無誤,同意向客戶端開放資源。(密碼鎖收到臨時密碼驗證后開門)
OAuth關注的是Authorization(授權)。
OpenId Connect
OpenID Connect簡稱OIDC。因為OAuth2是一個授權協議,它無法提供完善的身份認證功能。所以它在OAuth2上構建了一個身份層,是一個基於OAuth2協議的身份認證標准協議。OIDC使用OAuth2的授權來為第三方客戶端提供用戶的身份認證,並把對應的身份認證信息傳遞給客戶端,且可以適用於各種類型的客戶端,並且完全兼容OAuth2,也就是說你搭建了一個OIDC的服務后,也可以當作一個OAuth2的服務來用。
術語介紹
User - 用戶。
Client - 客戶端。
IdentityServer - 授權認證服務器。
Resources - 需要保護的資源。
Access Token - 訪問令牌,允許用戶哪些資源。
Identity Token - 身份令牌,用戶確認用戶身份。
JWT
Json web token (JWT), 是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標准((RFC 7519).該token被設計為緊湊且安全的,特別適用於分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。
JWT是由三段字符串拼接而成的,使用 .
分割的。
eyJhbGciOiJSUzI1NiIsImtpZCI6IjIxNmd3ZUVTZTA3d29hSDhpWHAzMUEiLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE1NzY2NTYwOTMsImV4cCI6MTU3NjY1OTY5MywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAzIiwiYXVkIjoiQXBpX0EiLCJjbGllbnRfaWQiOiJjbGllbnRfYSIsInNjb3BlIjpbIkFwaV9BIl19.kdszQIZFTS8aURbF5lIL1-qFzkJ79plH0seM4TsrTPdZoWakJVTH76-qmRpu6H6eaQt7U10R-Y8fn5N2FFh6XHRuDufEsDL8R2Tv7Cu0qbHKHTi-LgZcU2CxM22RyL6Df7Z0IpG5uEQqJ2LyxHJg3W-D3TgSNXUA8ge87ghGrhLRQ8hywH5gM4EZy9lKO7vMZml1IIfuyXTC8FU-HUn6-ZmvC1mADlAQJv84WHyg7fzzgNXqztvSyXA2p6jJG5FDgAjA9-yWnqJPxlZe7-Qi5Dj67lEF9kSII0tblV8JpxxJTpUvM2iPMLKWw77HDGaZkfAUu9WsbpQv-zWXPBBpbw
我們通過jwt.io解析出來。
第一部分Hrader
alg - 簽名算法
kid - 密鑰的Id
typ - token類型
這三個參數是最常見的。d
第二部分PayLoad
nbf - 生效時間
exp - 過期時間
iss - 令牌發放者
chlien_Id - 發放客戶端id
aud - 令牌接收方
scope - 可訪問資源
在PayLoad中可以放置任何你想要的參數。
第三部分Signature
Signature 是對前兩部分的簽名,防止數據篡改。
JWT的認證過程
1.用戶使用賬號密碼或別的方式登陸
2.服務器接受到登陸請求后生成一個jwt token
3.服務器把jwt token返回給客戶端
4.客戶端在請求資源在Header中的authorization帶上jwt token
5.服務器對jwt進行驗簽,驗簽成功后根據PayLoad中的信息判斷認證是否通過
6.響應客戶端結果
授權方式-后面有實現的傳送門
Client Credentials - 客戶端授權模式。 - 實現傳送門
Resource Owner Password Credentials - 密碼模式。 - 實現傳送門
Implicit - 授權碼簡化模式。
Authorization Code - 授權碼模式。
總結
都是自己一邊學習IdentityServer4一邊寫,每種模式后都有實現傳的送門,文中如果有神馬錯誤請大佬們在評論區指出。