原文: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
一件使人烦恼的事情是微软仍然认为他们知道什么是最适合你的,将OIDC标准声明映射到其专有声明。
能够经过清除Microsoft JWT令牌处理程序上的入站声明类型映射来优雅地修复:github
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
接下来,让咱们从客户端请求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协议中的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返回的任何其余声明。
我但愿这有帮助。简而言之 – 你应该明确的知道你的映射,由于我相信这些默认映射将在可能会发生变化,这将致使您的客户端应用程序出现意外行为。