IdentityServer4實戰:四種授權模式


前言

本篇所講案例代碼全部由上篇《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


免責聲明!

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



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