Asp.net Core 2.0 OpenId Connect Handler缺失Claims?

 

原文:https://leastprivilege.com/2017/11/15/missing-claims-in-the-asp-net-core-2-openid-connect-handler/
發佈於:2017年11月
環境:ASP.NET Core 2.0html

經過OIDC provider 把Claims映射到ClaimsPrincipal這一步驟,在ASP.NET Core 2中新的OpenID Connect handler具備不一樣的行爲。
這是特別使人困惑和難以診斷的,由於這裏有幾個部件彙集在一塊兒。咱們來看一下。
您可使用個人示例OIDC客戶端來觀察到相同的結果。git

將標準claim類型映射到Microsoft專有claim類型

一件使人煩惱的事情是微軟仍然認爲他們知道什麼是最適合你的,將OIDC標準聲明映射到其專有聲明。
能夠經過清除Microsoft JWT令牌處理程序上的入站聲明類型映射來優雅地修復:github

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

基本的OpenId Connect受權請求

接下來,讓咱們從客戶端請求openid scope的場景開始。
首先使人困惑的是Microsoft使用openid和profile scope預先在OpenIdConnectOptions上填充了Scope集合。這意味着若是你只想請求openid,你首先須要清除Scope集合,而後手動添加openid。web

services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
    .AddCookie("Cookies", options =>
    {
        options.AccessDeniedPath = "/account/denied";
    })
    .AddOpenIdConnect("oidc", options =>
    {
        options.Authority = "https://demo.identityserver.io";
        options.ClientId = "server.hybrid";
        options.ClientSecret = "secret";
        options.ResponseType = "code id_token";
 
        options.SaveTokens = true;
                    
        options.Scope.Clear();
        options.Scope.Add("openid");
                    
        options.TokenValidationParameters = new TokenValidationParameters
        {
            NameClaimType = "name", 
            RoleClaimType = "role"
        };
    });

使用ASP.NET Core v1處理程序,將返回如下聲明:nbf,exp,iss,aud,nonce,iat,c_hash,sid,sub,auth_time,idp,amr。ide

在V2中咱們只能獲得sid,sub和idp。發生了什麼?函數

微軟在其OpenID Connect handler中添加了一個名爲ClaimActions的新概念。Claim actions用來實現自外部provider的claim如何映射(或不)到您的ClaimsPrincipal中的claim。查看OpenIdConnectOptions的構造函數,您能夠看到,處理程序如今默認會跳過如下聲明:spa

ClaimActions.DeleteClaim("nonce");
ClaimActions.DeleteClaim("aud");
ClaimActions.DeleteClaim("azp");
ClaimActions.DeleteClaim("acr");
ClaimActions.DeleteClaim("amr");
ClaimActions.DeleteClaim("iss");
ClaimActions.DeleteClaim("iat");
ClaimActions.DeleteClaim("nbf");
ClaimActions.DeleteClaim("exp");
ClaimActions.DeleteClaim("at_hash");
ClaimActions.DeleteClaim("c_hash");
ClaimActions.DeleteClaim("auth_time");
ClaimActions.DeleteClaim("ipaddr");
ClaimActions.DeleteClaim("platf");
ClaimActions.DeleteClaim("ver");

若是您想「取消」跳過某項聲明,則須要在設置handler時刪除特定聲明。如下是獲取amr聲明的很是直觀的語法:.net

options.ClaimActions.Remove("amr");

從OIDC provider請求更多的Claim

當你要求更多的範圍時,例如我的資料或自定義範圍致使更多索賠,還有另外一個使人困惑的細節須要注意。
根據OIDC協議中的response_type,某些聲明經過id_token進行傳輸,有些經過userinfo端點進行傳輸。我在這裏寫了關於此細節的文章
所以,首先您須要在處理程序中啓用對userinfo端點的支持:code

options.GetClaimsFromUserInfoEndpoint = true;

若是聲明由userinfo返回,ClaimsActions將用於從返回的JSON文檔映射claim到principal。這裏使用如下默認設置:server

ClaimActions.MapUniqueJsonKey("sub", "sub");
ClaimActions.MapUniqueJsonKey("name", "name");
ClaimActions.MapUniqueJsonKey("given_name", "given_name");
ClaimActions.MapUniqueJsonKey("family_name", "family_name");
ClaimActions.MapUniqueJsonKey("profile", "profile");
ClaimActions.MapUniqueJsonKey("email", "email");

若是您向您的客戶發送的不屬於上述列表的claim,它會被忽略,您須要進行明確的映射。例如您但願客戶端經過userinfo(標準OIDC聲明之一,但不幸未由Microsoft映射)得到website claim - 您須要自行添加映射:

options.ClaimActions.MapUniqueJsonKey("website", "website");

這一樣適用於您經過userinfo返回的任何其餘聲明。

我但願這有幫助。簡而言之 – 你應該明確的知道你的映射,由於我相信這些默認映射將在可能會發生變化,這將致使您的客戶端應用程序出現意外行爲。

相關文章
相關標籤/搜索