IdentityServer4 中文文檔 -11- (快速入門)添加基於 OpenID Connect 的用戶認證


IdentityServer4 中文文檔 -11- (快速入門)添加基於 OpenID Connect 的用戶認證


原文:http://docs.identityserver.io/en/release/quickstarts/3_interactive_login.html

目 錄

上一篇:IdentityServer4 中文文檔 -10- (快速入門)使用密碼保護API
下一篇:IdentityServer4 中文文檔 -12- (快速入門)添加外部認證支持

在這個快速啟動中,我們希望通過OpenID Connect協議向我們的 IdentityServer 添加對交互式用戶身份驗證的支持。

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

添加 UI(用戶界面)

IdentityServer 內置了 OpenID Connect 需要的所有協議支持。你需要提供必需的 UI 部分,包括 登錄、注銷、授權確認以及錯誤頁。

因為在每個 IdentityServer 的實現中,視覺、感覺以及實際工作流可能總是有所不同的,所以我們提供了一套基於 MVC 的樣例 UI,你可以將其作為啟動點來使用。

這套 UI 可以在 快速入門倉庫 找到。你還可以克隆或下載這個倉庫,將其中的控制器、視圖、模型以及 CSS 放到你的 Web 應用程序中。

你還可以在你的 Web 應用程序中以命令行的方式運行以下命令來自動下載:

iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/IdentityServer/IdentityServer4.Quickstart.UI/release/get.ps1'))

查看 自述文件 以了解更多 快速入門UI 相關的信息。

注意: UI 倉庫的 release 分支擁有與最新發布的穩定版相匹配的 UI。dev 分支則與 IdentityServer4 的當前開發構建相符。如果你想要尋找指定版本的 UI,請查看相應的標簽。

花一些時間去查閱控制器和模型,你越是了解他們,將來要修改他們就越簡單。大部分代碼都以“功能目錄”的樣式放在 “Quickstart” 文件夾下,如果這種樣式不適合你,那就按照你想要的方式隨意組織代碼。

創建一個 MVC 客戶端

接下來你將向解決方案添加一個 MVC 應用程序,可以使用 ASP.NET Core "Web 應用程序" 模板來實現。 將應用程序配置為使用 5002 端口(可以查看概覽部分以了解如何配置)。

為了能向 MVC 應用程序添加 OpenID Connect 認證支持,請添加如下 NuGet 程序包:

  • Microsoft.AspNetCore.Authentication.Cookies
  • Microsoft.AspNetCore.Authentication.OpenIdConnect

然后添加這兩個中間件到你的管道中 —— Cookies 對應的中間件很簡單:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme="Cookies"
});

OpenID Connect 中間件需要稍微多一些配置。將它指向 Identity Server,指定一個客戶端 ID 並且告訴它哪個中間件將會負責本地登陸(也就是 cookies 中間件)。此外,我們關閉了 JWT 身份信息類型映射,這樣就允許 well-known 身份信息(比如,“sub” 和 “idp”) 無干擾地流過。這個身份信息類型映射的 “清理” 必須在調用 UseOpenIdConnectAuthentication() 之前完成:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    AuthenticationScheme = "oidc",
    SignInScheme = "Cookies",
    Authority = "http://localhost:5000",
    RequireHttpsMetadata = false,
    ClientId = "mvc",
    SaveTokens = true
});

兩個中間件都應該在 MVC 之前添加到管道。

下一個步驟是觸發認證握手,為此打開 home 控制器並添加 [Authorize] 到其中一個 action 上。另外,修改 action 對應的視圖以顯示用戶的身份信息,比如:

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

現在,如果你使用瀏覽器導航到上述控制器,一個Mvc客戶端將視圖重定向到 IdentityServer - 這會導致錯誤,因為 MVC 客戶端還沒有注冊(在 IdentityServer 上定義)呢。

添加 OpenID Connect 身份 Scopes 支持

與 OAuth 2.0 相似,OpenID Connect 也使用 scopes 這個概念。再一次說明,Scopes 表示你想要保護的和客戶端想要訪問的事物。在與 OAuth 相比,OIDC(OpenID Connect) 中的 scopes 不僅代表 API,還代表了諸如 用戶id、用戶名 或 郵箱地址等身份數據。

通過(在 Config.cs 中)添加新的幫助器來創建 IdentityResource 對象的集合,可以添加對標准 openid(subject id,這里指的是用戶id)和 profile(姓氏,名稱 等等)等 scopes 的支持:

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

注意:所有標准的 Scopes 和他們對應的 身份信息 都可以在 OpenID Connect 規范 中找到。

接下來在 Startup.cs 中你要將這些身份資源添加到你的 IdentityServer 配置。在你調用 AddIdentityServer() 的地方使用 AddInMemoryIdentityResources 擴展方法即可:

public void ConfigureServices(IServiceCollection services)
{
    // 使用內存存儲,密鑰,客戶端和資源來配置身份服務器。
    services.AddIdentityServer()
        .AddTemporarySigningCredential()
        .AddInMemoryApiResources(Config.GetApiResources())
        .AddInMemoryClients(Config.GetClients())
        .AddTestUsers(Config.GetUsers())
        .AddInMemoryIdentityResources(Config.GetIdentityResources());
}

為 OIDC 隱式流添加客戶端定義

最后一個步驟是為 IdentityServer 添加一個新的客戶端。

目前,我們添加的基於 OIDC 的客戶端與 OAuth 2.0 客戶端非常相似。但是由於 OIDC 中的流總是交互式的,所以我們需要添加一些重定向 URL 到我們的配置中。

添加以下代碼到你的客戶端配置中:

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        // 省略的客戶端...

        // OIDC 隱式流客戶端(MVC)
        new Client
        {
            ClientId = "mvc",
            ClientName = "Mvc 客戶端",
            AllowedGrantTypes = GrantTypes.Implicit,
            // 登錄后重定向到的地址
            RedirectUris = { "http://localhost:5002/signin-oidc" },
            // 注銷后重定向到的地址
            AllowedScopes = new List<string>
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile
            }
        }
    };
}

測試 MVC 客戶端

現在,對於新的 MVC 客戶端,一切都准備好了。

將瀏覽器導航到受保護的 控制器 action 以觸發認證握手。你應該能看到客戶端將你重定向到了 IdentityServer 的登錄頁。

登錄成功后,用戶將在授權確認頁中被呈現出來。在這里用戶可以決定他是否想要發布他的身份信息給客戶端應用程序。

注意: 授權確認頁可以通過客戶端定義對象的 RequireConsent 屬性被關閉(以每個客戶端為單位)。

最終瀏覽器將被重定向回客戶端應用程序,即展示用戶的身份信息。

注意:在開發期間你有時候可能會看到 無法驗證令牌 的異常信息。這是因為實際上簽名密鑰材料是憑空產生的,並且在只內存中駐留。這個異常在 客戶端 與 IdentityServer 不同步時就會發生。簡單地重復客戶端上的操作,等到下一次元數據被捕獲時,一切都會再次正常工作的。

添加注銷

最后的最后,是給 MVC 客戶端添加 注銷功能。

通過 IdentityServer 這樣的服務進行身份認證,單單清除本地應用程序的 Cookies 是不夠的。你還需要往返一次 IdentityServer 來清理集中式單點登錄會話。

具體的協議步驟都在 OpenID Connect 中間件中實現了,簡單地添加以下代碼到某個控制器中就可以用來觸發注銷:

public async Task Logout()
{
    await HttpContext.Authentication.SignOutAsync("Cookies");
    await HttpContext.Authentication.SignOutAsync("oidc");
}

進一步實驗

如前面所說,OpenID Connect 中間件默認會請求 profile scope。這個 scope 還包含了用戶名或個人主頁等身份信息。

讓我們將這些身份信息添加到用戶定義里面,這樣的話 IdentityServer 就可以把它們放到身份令牌中了:


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


            Claims = new []
            {
                new Claim("name", "愛麗絲"),
                new Claim("website", "https://alice.com")
            }
        },
        new TestUser
        {
            SubjectId="2",
            Username="博德",
            Password="password",

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

下一次你認證的時候,你的身份信息頁將會顯示額外的身份信息。

請隨意添加更多的身份信息 - 還有更多的 scopes。OpenID Connect 中間件上的 Scope 屬性是你用來配置哪些 Scopes 將在認證期間被發送到 IdentityServer 的地方。

值得注意的是,對令牌中身份信息的遍歷是一個擴展點 - IProfileService。因為我們正在使用 AddTestUser,所以默認使用的是 TestUserProfileService。你可以檢出這里的源代碼來查看它的工作原理。

目 錄

上一篇:IdentityServer4 中文文檔 -10- (快速入門)使用密碼保護API
下一篇:IdentityServer4 中文文檔 -12- (快速入門)添加外部認證支持


免責聲明!

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



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