IdentityServer4(9)- 使用OpenID Connect添加用戶身份驗證(implicit)


本文為 OpenID Connect 簡化模式(implicit)

已更新至.NET Core 2.2

在本快速入門中,我們希望通過 OpenID Connect 協議向我們的 IdentityServer 添加對用戶認證交互的支持。

我們將創建一個將使用 IdentityServer 進行身份認證的MVC應用程序。

添加UI

OpenID Connect 所需的所有協議支持都已內置到 IdentityServer 中。您需要為提供必要的UI部件:登錄,注銷,同意授權和錯誤頁面。

根據業務場景的不同對 IdentityServer 的實現也有所不同,但我們提供了一個基於 MVC 的示例UI,您可以將其用作起步。

可以在快速入門UI倉庫中找到此UI。 您可以克隆或下載此repo,並將Controller,View,Model和CSS放入IdentityServer Web 應用程序中。

或者,您可以使用.NET CLI(從 src/IdentityServer 文件夾中運行命令):

dotnet new is4ui

添加 MVC UI 后,您還需要在 DI 系統和管道中啟用 MVC。 當您查看Startup.cs時,您將在 ConfigureServices 和 Configure 方法中找到有關如何啟用MVC的注釋。

運行IdentityServer應用程序,您現在應該看到一個主頁。

花一些時間檢查控制器和模型,您越了解它們,就越容易掌握以便修改。 大多數代碼使用“feature folder”樣式存在於“Quickstart”文件夾中。 如果此樣式不適合您,請隨意以您想要的任何方式組織代碼。

創建 MVC 客戶端

接下來,您將向您的解決方案添加MVC應用程序。 使用 ASP.NET Core “Web Application” (即 MVC) 模板。 不要在向導中配置“Authentication"設置 - 您將在此快速入門中手動執行此操作。 創建項目后,將應用程序配置為在端口5002上運行。

要將對 OpenID Connect 身份認證的支持添加到MVC應用程序,請在Startup中將以下內容添加到ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie("Cookies")
        .AddOpenIdConnect("oidc", options =>
        {
            options.Authority = "http://localhost:5000";
            options.RequireHttpsMetadata = false;

            options.ClientId = "mvc";
            options.SaveTokens = true;
        });
}

AddAuthentication將身份認證服務添加到 DI。 我們使用 cookie 來本地登錄用戶(通過“Cookies”作為DefaultScheme),我們將 DefaultChallengeScheme 設置為“oidc”,因為當我們需要用戶登錄時,我們將使用OpenID Connect 協議。

然后,我們使用 AddCookie 添加可以處理 cookie 的處理程序。

最后,AddOpenIdConnect用於配置執行 OpenID Connect 協議的處理程序。Authority表明我們信任的 IdentityServer 地址。然后我們通過ClientId。識別這個客戶端。 SaveTokens用於在 cookie 中保留來自IdentityServer 的令牌(稍后將需要它們)。

同樣,我們已經關閉了 JWT Claim類型映射,以允許常用的Claim(例如'sub'和'idp')。

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

然后要確保認證服務執行對每個請求的驗證,加入UseAuthenticationConfigure中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseAuthentication();

    app.UseStaticFiles();
    app.UseMvcWithDefaultRoute();
}

應在管道中的MVC之前添加認證中間件。

最后一步是觸發身份認證。為此,請轉到 Controller 並添加[Authorize]特性到其中一個Action。還要修改主視圖以顯示用戶的Claim以及cookie屬性:

@using Microsoft.AspNetCore.Authentication

<h2>Claims</h2>

<dl>
    @foreach (var claim in User.Claims)
    {
        <dt>@claim.Type</dt>
        <dd>@claim.Value</dd>
    }
</dl>

<h2>Properties</h2>

<dl>
    @foreach (var prop in (await Context.AuthenticateAsync()).Properties.Items)
    {
        <dt>@prop.Key</dt>
        <dd>@prop.Value</dd>
    }
</dl>

如果您現在使用瀏覽器訪問該控制器,將會被重定向到IdentityServer - 這將導致錯誤,因為MVC客戶端尚未注冊。

添加 OpenID Connect Identity Scope

與OAuth 2.0類似,OpenID Connect也使用Scope概念。同樣,Scope代表您想要保護的內容以及客戶端想要訪問的內容。與OAuth相比,OIDC中的Scope不僅代表API資源,還代表用戶ID,姓名或電子郵件地址等身份資源

通過修改 Config.cs 中的 GetIdentityResources 方法,添加對標准 openid(subject id)和profile (名字,姓氏等)Scope的支持:

public static IEnumerable<IdentityResource> GetIdentityResources()
{
    return new List<IdentityResource>
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile(),
    };
}

所有標准Scope及其相應的Claim都可以在OpenID Connect規范中找到。

添加OpenID Connect簡化流程客戶端

最后一步是將MVC客戶端的配置信息添加到 IdentityServer。

基於OpenID Connect的客戶端與我們目前添加的OAuth 2.0客戶端非常相似。但由於OIDC中的流程始終是交互式的,因此我們需要在配置中添加一些重定向URL。

將以下內容添加到客戶端配置中:

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        // other clients omitted...

        // OpenID Connect implicit flow client (MVC)
        new Client
        {
            ClientId = "mvc",
            ClientName = "MVC Client",
            AllowedGrantTypes = GrantTypes.Implicit,

            // 登錄成功回調處理地址,處理回調返回的數據
            RedirectUris = { "http://localhost:5002/signin-oidc" },

            // where to redirect to after logout
            PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

            AllowedScopes = new List<string>
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile
            }
        }
    };
}

測試客戶端

通過訪問到受保護的Controller操作來觸發身份認證。您應該會看到重定向到IdentityServer的登錄頁面。

../_images/3_login.png

成功登錄后,將向用戶顯示同意授權頁面。在這里,用戶可以決定是否要將他的身份信息發布到客戶端應用程序。

可以使用客戶端配置上RequireConsent的屬性關閉同意授權頁面。

../_images/3_consent.png

之后,IdentityServer將重定向回MVC客戶端,其中OpenID Connect身份認證處理程序處理響應並通過設置 cookie 在本地登錄用戶。最后,MVC視圖將顯示cookie的內容。

../_images/3_claims.png

如您所見,cookie 包含兩部分,即用戶的Claim和一些元數據。此元數據還包含IdentityServer發出的原始令牌。可以將此令牌復制到jwt.io以檢查其內容。

添加注銷

后一步是向MVC客戶端添加注銷。

使用IdentityServer等身份認證服務,僅清除本地應用程序cookie是不夠的。此外,您還需要向IdentityServer進行往返交互以清除中央單點登錄會話。

確切的協議步驟在OpenID Connect處理程序中實現,只需將以下代碼添加到某個控制器即可觸發注銷:

public IActionResult Logout()
{
    return SignOut("Cookies", "oidc");
}

這將清除本地cookie,然后重定向到IdentityServer。IdentityServer將清除其cookie,然后為用戶提供返回MVC應用程序的鏈接。

進一步的實驗

如上所述,OpenID Connect處理程序默認要求 profile scope。此Scope還包括 name 或者 website。

讓我們將這些Claim添加到用戶信息中,以便IdentityServer可以將它們放入 identity token:

public static List<TestUser> GetUsers()
{
    return new List<TestUser>
    {
        new TestUser
        {
            SubjectId = "1",
            Username = "alice",
            Password = "password",

            Claims = new []
            {
                new Claim("name", "Alice"),
                new Claim("website", "https://alice.com")
            }
        },
        new TestUser
        {
            SubjectId = "2",
            Username = "bob",
            Password = "password",

            Claims = new []
            {
                new Claim("name", "Bob"),
                new Claim("website", "https://bob.com")
            }
        }
    };
}

下次進行身份認證時,您的Claim頁面現在會顯示這些Claim。

添加更多Claim - 以及更多Scope。OpenID Connect中間件上的Scope屬性是您配置在身份認證期間將哪些Scope發送到IdentityServer。

值得注意的是,對令牌Claim的檢索是一個可擴展點--IProfileService。 由於我們使用的是AddTestUsers,因此默認使用TestUserProfileService。 您可以在此處檢查源代碼以查看其工作原理,以便實現自定義Claim檢索。

資料

本文 Demo:3_ImplicitFlowAuthentication

官方文檔原文:Adding User Authentication with OpenID Connect


免責聲明!

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



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