目錄
- OAuth 2.0
- OpenID Connect
- QuickStart
OAuth 2.0
- 概念
- 過程
- 通訊
- 元件
- 示例程式碼
概念
OAuth 2.0 是一個授權協議,它允許軟體應用代表(而不是充當)資源擁有者去訪問資源擁有者的資源(如何讓一個系統元件獲取另一個系統元件的訪問許可權)
- 受保護的資源:是資源擁有者有許可權訪問的元件
- 資源擁有者:有權訪問 API,並能將 API 訪問許可權委託出去
- 客戶端:凡是使用了受保護資源上的 API,都是客戶端
過程
通訊
元件
- 訪問令牌 token
- 許可權範圍 scope
- 重新整理令牌 refresh token
- 授權許可 grant_type
grant_type | 授權方式 | 授權前置條件 | 使用通訊通道 | 說明 |
---|---|---|---|---|
authorization_code/PKCE | 授權碼模式 | 授權碼 | 前端/後端 | 客戶端通過code在後端與授權伺服器進行互動獲取令牌 |
implict(不建議使用) | 簡化模式 | |||
password(不建議使用) | 密碼模式 | 使用者名稱/密碼 | 後端 | 在客戶端輸入使用者名稱和密碼,由客戶端向授權伺服器獲取令牌 |
client_credentials | 客戶端模式 | 無 | 後端 | |
device_code | 裝置碼 | |||
refresh_token | 重新整理token | 用refresh_token來換取新的token |
授權碼模式
-
第三方應用首先向服務提供商申請 client_id 應用唯一標識、Client_secret 金鑰,用於後續獲取令牌時提供身份校驗
-
申請授權碼:此時要提供預分配好的 client_id 標識來源,提供 scope 標識要申請的許可權,提供 redirect_uri 標識授權完畢後要回跳的第三方應用連結
-
第一次 302 重定向:認證伺服器展示登入授權頁
-
第二次 302 重定向:在使用者提交授權,認證伺服器認證成功後,會分配授權碼 code,並重定向回第三方應用的 redirect_uri
-
(建議第三方應用要根據當前使用者會話生成隨機且唯一的 state 引數,並且收到授權碼時先進行校驗,避免 CSRF 攻擊)最後,第三方應用會向認證伺服器申請令牌 access_token,此時要提供預分配好的 code、client_id、client_secret 以便認證。這一步是在後端之間完成的,對使用者不可見。access_token 是有有效期的,過期後需要重新整理
-
拿到令牌 access_token 後,第三方應用就可以訪問資源方,獲取所需資源 access_token 相當於使用者的 session id
選擇正確的許可型別
示例程式碼
地址:https://github.com/skoruba/IdentityServer4.Admin
OpenID Connect
- OAuth2.0 的不足之處
- OIDC 概念
OAuth2.0 的不足之處
OAuth2.0 中的 access_token 就是酒店的房卡,誰都可以擁有房卡,有房卡就可以開啟酒店的門,但是房卡上並沒有當前使用房卡的使用者資訊,如果需要知道當前房卡所有人的資訊需要單獨再向酒店的前臺去詢問
OIDC 概念
Open ID Connect 1.0 是建立在 OAuth 2.0 之上的一個身份層
https://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthorizationEndpoint
QuickStart
安裝模板
dotnet new -i IdentityServer4.Templates
檢視模板
dotnet new
使用模板建立
dotnet new is4inmem -n QuickStart
已成功建立模板“IdentityServer4 with In-Memory Stores and Test Users”。
開啟專案,啟動
點選進入登入頁面,使用預設使用者登入
登入結果
根據配置檔案通過ClientCredentials的方式獲取token
// m2m client credentials flow client
new Client
{
ClientId = "m2m.client",
ClientName = "Client Credentials Client",
AllowedGrantTypes = GrantTypes.ClientCredentials,
ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
AllowedScopes = { "scope1" }
},
根據配置檔案通過Code的方式獲取token
// interactive client using code flow + pkce
new Client
{
ClientId = "interactive",
ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },
AllowedGrantTypes = GrantTypes.Code,
RequirePkce = false,
AllowPlainTextPkce = true,
RedirectUris = { "https://localhost:44300/signin-oidc" },
FrontChannelLogoutUri = "https://localhost:44300/signout-oidc",
PostLogoutRedirectUris = { "https://localhost:44300/signout-callback-oidc" },
AllowOfflineAccess = true,
AllowedScopes = { "openid", "profile", "scope2" }
},
訪問認證介面獲取授權碼
https://localhost:5001/connect/authorize?client_id=interactive&scope=openid&response_type=code&redirect_uri=https://localhost:44300/signin-oidc&nonce=xyz
返回授權碼
https://localhost:44300/signin-oidc?code=BC56FE53D39BD46A5D55D43F485E23D7FF6583FEDD7A2A0B7A2A3DFDF5C52935&scope=openid&session_state=SwfB-jWoQ16C67cm5c_ANqbVE1R50Krj55GuJuArEQ0.BE30A11CD461DC430C5121AEFB4A4E82
本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。
歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含連結: http://www.cnblogs.com/MingsonZheng/ ),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。
如有任何疑問,請與我聯絡 (MingsonZheng@outlook.com) 。