Asp.NetCore 2.0 OpenId Connect Handler欠損Claims?

10458 ワード


原文:https://leastprivilege.com/2017/11/15/missing-claims-in-the-asp-net-core-2-openid-connect-handler/2017年11月環境:ASP.NET Core 2.0
OIDC providerでClaimsをClaimsPrincipalにマッピングするには、ASP.NET Core 2における新しいOpenID Connect handlerは異なる動作を有する.これは特に困惑し、診断しにくいです.ここにはいくつかの部品が集まっているからです.ちょっと見てみましょう.私のサンプルOIDCクライアントを使用して、同じ結果を観察できます.

Microsoft固有のclaimタイプに標準claimタイプをマッピング


悩ましいことは、マイクロソフトがあなたに最適なものを知っていると考えていることです.OIDC標準声明を独自の声明にマッピングします.MicrosoftJWTトークンハンドラのインバウンド宣言タイプマッピングをクリアすることで、優雅に修復できます.
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

基本的なOpenId接続許可要求


次に、クライアントがopenid scopeを要求するシーンから始めましょう.まず困惑するのは、Microsoftがopenidとprofile scopeを使用してOpenIdConnectOptionsにScopeセットを予め埋め込んでいることです.これは、openidのみを要求する場合は、まずScopeコレクションをクリアし、手動でopenidを追加する必要があることを意味します.
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 v 1プロセッサは、次の宣言を返します:nbf,exp,iss,aud,nonce,iat,c_hash,sid,sub,auth_time,idp,amr.
V 2ではsid,sub,idpしか得られない.何があったの?
マイクロソフトはOpenID Connect handlerにClaimActionsという新しい概念を追加しました.Claim actionsは、外部providerからのclaimがClaimsPrincipalのclaimにどのようにマッピング(またはマッピングしない)かを実現するために使用されます.OpenIdConnectOptionsのコンストラクション関数を表示すると、プロセッサはデフォルトで次の宣言をスキップします.
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宣言を取得する非常に直感的な構文です.
options.ClaimActions.Remove("amr");

OIDC providerからより多くのClaimを要求


個人情報やカスタム範囲など、より多くの範囲を要求すると、より多くのクレームが発生し、もう一つの困惑する詳細に注意する必要があります.OIDCプロトコルのresponse_に従ってtype、いくつかの宣言はid_を通過しますtokenは転送され、userinfoエンドポイントを介して転送されるものもあります.私はここでこの詳細についての文章を書いた.したがって、まずプロセッサでuserinfoエンドポイントのサポートを有効にする必要があります.
options.GetClaimsFromUserInfoEndpoint = true;

宣言がuserinfoによって返された場合、ClaimsActionsは、返されたJSONドキュメントからprincipalへのclaimのマッピングに使用されます.ここでは、次のデフォルト設定を使用します.
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宣言の1つですが、Microsoftによってマッピングされていません)を使用してwebsite claimを取得する場合は、マッピングを自分で追加する必要があります.
options.ClaimActions.MapUniqueJsonKey("website", "website");

これは、userinfoを介して返される他の宣言にも適用されます.
これが役に立つことを願っています.簡単に言えば、デフォルトのマッピングが変化する可能性があると信じているため、クライアント・アプリケーションで予期せぬ動作を起こす可能性があります.