前言
本篇所講案例代碼全部由上篇《IdentityServer4實戰:快速入門》修改而來。
客戶端模式
客戶端模式只對客戶端進行授權,不涉及到用戶信息。如果你的api需要提供到第三方應用,第三方應用自己做用戶授權,不需要用到你的用戶資源,就可以用客戶端模式,只對客戶端進行授權訪問api資源。 這是一種最簡單的模式,只要client請求,我們就將AccessToken發送給它。這種模式是最方便但最不安全的模式。因此這就要求我們對client完全的信任,而client本身也是安全的
定義 Client
new Client { ClientId = "client1", // 沒有交互性用戶,使用 clientid/secret 實現認證。 AllowedGrantTypes = GrantTypes.ClientCredentials, // 用於認證的密碼 ClientSecrets = { new Secret("secret".Sha256()) }, // 客戶端有權訪問的范圍(Scopes) AllowedScopes = { "api1" } }
POSTMan 測試
用戶名密碼模式
需要客戶端提供用戶名和密碼,密碼模式相較於客戶端憑證模式。通過User的用戶名和密碼向Identity Server申請訪問令牌。 這種方式需要用戶給出自己的用戶名/密碼,顯然風險很大,因此只適用於其他授權方式都無法采用的情況,而且必須是用戶高度信任的應用。
定義 Client
new Client { ClientId = "client2", // 用戶名 密碼 模式 AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, // 用於認證的密碼 ClientSecrets = { new Secret("secret".Sha256()) }, // 客戶端有權訪問的范圍(Scopes) AllowedScopes = { "api1" } }
定義 用戶資源
public static List<TestUser> GetTestUsers() { return new List<TestUser> { new TestUser { SubjectId="1", Username="admin", Password="123456" } }; }
注冊 用戶資源
public void ConfigureServices(IServiceCollection services) { services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryClients(Startup.GetClients()) .AddInMemoryApiScopes(Startup.GetApiScopes()) .AddTestUsers(Startup.GetTestUsers()) ; }
POSTMan 測試
隱藏式 (implicit)
有些 Web 應用是前后端分離的純前端應用,沒有后端。這時就必須將令牌儲存在前端。 這種方式沒有授權碼這個中間步驟,所以稱為(授權碼)"隱藏式"(implicit)。
隱藏式的認證步驟為:
第一步,A 網站提供一個鏈接,要求用戶跳轉到 認證中心,授權用戶數據給 A 網站使用。
第二步,用戶跳轉到 認證中心,登錄后同意給予 A 網站授權。這時,認證中心就會跳回redirect_uri參數指定的跳轉網址,並且把令牌作為 URL 參數,傳給 A 網站。
注意,令牌的位置是 URL 錨點(fragment),而不是查詢字符串(querystring),這是因為 OAuth 2.0 允許跳轉網址是 HTTP 協議,因此存在"中間人攻擊"的風險,而瀏覽器跳轉時,錨點不會發到服務器,就減少了泄漏令牌的風險。
安裝 登錄界面
隱藏式 需要用戶在 認證中心 登錄並授權數據給 A 網站,所以需要一個登錄界面。這里我們使用 官網提供的 Quickstart.UI,它提供了一個完善的登錄和登出的UI。
進入到 MicroShell.IdentityServer4.Server 項目根目錄,執行如下命令:
dotnet new -i identityserver4.templates dotnet new is4ui
安裝成功后,項目中多了 wwwroot、Quickstart、views 等文件夾。
注入 UI 的依賴服務 和 路由規則
ConfigureServices 方法中添加如下代碼:
services.AddControllersWithViews();
Configure 方法中路由改為:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); });
定義 Client
new Client { ClientId = "client4", // 授權碼 模式 AllowedGrantTypes = GrantTypes.Implicit, RedirectUris = { "http://localhost:5001/test/index"}, // 認證成功后允許的回調地址 // 是否需要確認授權,這個配置我們會在后面介紹,這里設置為 false RequireConsent = false, // 用於認證的密碼 ClientSecrets = { new Secret("secret".Sha256()) }, //AlwaysIncludeUserClaimsInIdToken=true, //允許token通過瀏覽器 (必須 true) AllowAccessTokensViaBrowser=true, // 客戶端有權訪問的范圍(Scopes) AllowedScopes = { "api1", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile } }
修改注入的 用戶資源
瀏覽器測試
瀏覽器輸入:http://localhost:5000/connect/authorize?response_type=id_token token&client_id=client4&scope=openid profile api1&redirect_uri=http://localhost:5001/test/index&nonce=11111111111111111111111
授權碼模式
授權碼(authorization code)方式,指的是第三方應用先申請一個授權碼,然后再用該碼獲取令牌。 這種方式是最常用的流程,安全性也最高,它適用於那些有后端的 Web 應用。授權碼通過前端傳送,令牌則是儲存在后端,而且所有與資源服務器的通信都在后端完成。這樣的前后端分離,可以避免令牌泄漏。
定義 Client
new Client { ClientId = "client3", // 授權碼 模式 AllowedGrantTypes = GrantTypes.Code, RedirectUris = { "http://localhost:5001/test/index"}, // 是否需要確認授權,這個配置我們會在后面介紹,這里設置為 false RequireConsent = false, // 這個參數必須設置 為 false RequirePkce= false, // 用於認證的密碼 ClientSecrets = { new Secret("secret".Sha256()) }, // 客戶端有權訪問的范圍(Scopes) AllowedScopes = { "api1", IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile } }
瀏覽器測試
瀏覽器輸入:http://localhost:5000/connect/authorize?response_type=code&client_id=client3&state=xyz&redirect_uri=http%3A%2F%2Flocalhost%3A5001%2FTest%2Findex&scope=openid profile api1
尾言
授權碼模式中我們只拿到了 Code,並沒有通過 Code 換取 Token,后面的操作筆友可以自己實現。
本文轉載自:https://limitcode.com/detail/606d61e8d9118c3cd416878c.html