使用 FusionAuth .NET 示例(链接)并且无法获取声明中的角色
这似乎是一个常见问题,而且似乎尚未解决。在 FusionAuth 中使用一个角色配置了一个简单的应用程序。
以下逻辑来自 Startup.cs
services.AddAuthentication(options =>
{
options.DefaultScheme = "cookie";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("cookie", options =>
{
options.Cookie.Name = Configuration["SampleApp:CookieName"];
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = Configuration["SampleApp:Authority"];
options.ClientId = Configuration["SampleApp:ClientId"];
options.ClientSecret = Configuration["SampleApp:ClientSecret"];
options.Scope.Add("openid");
// leave this in, otherwise the aud claim is removed. See https://stackoverflow.com/questions/69289426/missing-aud-claim-in-asp-net-core-policy-check-prevents-authorization-but-it for more
options.ClaimActions.Remove("aud");
options.ResponseType = "code";
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateAudience = true,
ValidAudience = Configuration["SampleApp:ClientId"]
};
});
}
签入 Secure.cshmtl
@foreach (var claim in User.Claims)
{
<dt>@claim.Type</dt>
<dd>@claim.Value</dd>
}
通过在 OnTokenValidated 事件中手动添加声明来解决。 不确定这是否是一个错误,或者 OpenIdConnect 配置中是否缺少某些内容,或者这是否是 FusionAuth 端的错误,但下面的代码确实正确添加了角色声明,以便
[Authorize(Roles = "MyCustomRole")]
可以在控制器中使用,或者如果需要使用User.IsInRole("MyCustomRole");
FusionAuth 将其添加到其 .NET MVC 模板中,除非缺少替代配置选项或 FusionAuth OpenIdConnect 实现存在潜在错误。
options.Events = new OpenIdConnectEvents
{
OnTokenValidated = (context) =>
{
//** Known Bug - Role Claim getting dropped
//** Add Manually from JWT
if (context?.TokenEndpointResponse?.AccessToken != null && context?.Principal?.Identity != null)
{
var handler = new JwtSecurityTokenHandler();
var jwtSecurityToken = handler.ReadJwtToken(context.TokenEndpointResponse.AccessToken);
var roleClaims = new List<Claim>();
foreach (var claim in jwtSecurityToken.Claims)
{
if (claim.Type.Contains(JwtClaimTypes.Role))
{
var newClaim = new Claim(ClaimTypes.Role, claim.Value);
roleClaims.Add(newClaim);
}
}
var identity = context.Principal.Identity as ClaimsIdentity;
if (identity != null)
{
identity.AddClaims(roleClaims);
}
}
return Task.CompletedTask;
},