首页 > 解决方案 > 令牌中缺少“角色”声明 - NET CORE 3.1 和 IS4

问题描述

我有一项负责对用户进行身份验证的服务。

更新后:

弹出一个问题:

服务是这样配置的:

applicationBuilder.UseCookiePolicy();
applicationBuilder.UseIdentityServer();
applicationBuilder.UseAuthorization();
//...
mvcCoreBuilder.AddAuthorization(ConfigureAuthorization);
var auth = mvcCoreBuilder.Services.AddAuthentication(ConfigureAuthenticationOptions);
auth.AddIdentityServerAuthentication(ConfigureIdentityServerAuthentication);
//...
void ConfigureAuthenticationOptions(AuthenticationOptions authenticationOptions)
{
    authenticationOptions.DefaultScheme = IdentityServerConstants.DefaultCookieAuthenticationScheme;
}
//...
void ConfigureAuthorization(AuthorizationOptions authorizationOptions)
{
    var requirements = new List<IAuthorizationRequirement> { new DenyAnonymousAuthorizationRequirement() };
    var schemes = new List<string> { IdentityServerConstants.DefaultCookieAuthenticationScheme };
    authorizationOptions.DefaultPolicy = new AuthorizationPolicy(requirements, schemes);
}
props = new _AuthenticationProperties
{
    IsPersistent = true,
    ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration),
};

// user.Claims contains the "role" claim

var claimsIdentity = new ClaimsIdentity(user.Claims, CookieAuthenticationDefaults.AuthenticationScheme);
claimsIdentity.AddClaim(new Claim(JwtClaimTypes.Subject, user.SubjectId));
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);

// The created claimsPrincipal contains the "role" claim

await HttpContext.SignInAsync(claimsPrincipal, props);

await HttpContext.SignInAsync(user.SubjectId, props, user.Claims.ToArray());

在被保护的api项目中:

// attribute for validating roles on controllers
[AuthorizeRoles(Role.SimpleRole)] // which implements IAuthorizationFilter

// And the implementation:
public void OnAuthorization(AuthorizationFilterContext context)
{
    var user = context.HttpContext.User;
    // user is of type 'ClaimsIdentity'
    // and it does not contain the "role" claim
 
    // some checks to verify the user here...
}

受保护的api项目的启动包含:

builder.AddAuthorization(ConfigureAuthorization);

var auth = builder.Services.AddAuthentication(ConfigureAuthenticationOptions);

auth.AddIdentityServerAuthentication(ConfigureIdentityServerAuthentication);

ConfigureIdentityServerAuthentication方法设置了一些IdentityServerAuthenticationOptions. RoleClaimType没有设置,因为它有一个默认值,'role'这是预期的值。

来自IdentityServerAuthenticationOptions'IdentityServer4.AccessTokenValidation' 包版本 3.0.1。

这里有两个截图来证明RoleClaimType是设置的:

问题:

涉及技术:

标签: c#cookiesoauth-2.0identityserver4asp.net-core-3.1

解决方案


默认情况下,IdentityServer 和 ASP.NET 核心对 RoleClaim 的名称应该是什么有不同的看法。

在您的客户端中添加此代码以修复该映射(设置 TokenValidationParameters 选项)

       services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        }).AddCookie(options =>
        {
            options.LoginPath = "/User/Login";
            options.LogoutPath = "/User/Logout";
            options.AccessDeniedPath = "/User/AccessDenied";
        }).AddOpenIdConnect(options =>
        {
            options.Authority = "https://localhost:6001";
            options.ClientId = "authcodeflowclient";
            options.ClientSecret = "mysecret";
            options.ResponseType = "code";

            options.Scope.Clear();
            options.Scope.Add("openid");
            options.Scope.Add("profile");
            options.Scope.Add("email");
            options.Scope.Add("employee_info");


            //Map the custom claims that should be included
            options.ClaimActions.MapUniqueJsonKey("employment_start", "employment_start");
            options.ClaimActions.MapUniqueJsonKey("seniority", "seniority");
            options.ClaimActions.MapUniqueJsonKey("contractor", "contractor");
            options.ClaimActions.MapUniqueJsonKey("employee", "employee");
            options.ClaimActions.MapUniqueJsonKey("management", "management");
            options.ClaimActions.MapUniqueJsonKey(JwtClaimTypes.Role, JwtClaimTypes.Role);

            options.SaveTokens = true;
            options.SignedOutRedirectUri = "/";
            options.GetClaimsFromUserInfoEndpoint = true;



            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = JwtClaimTypes.Name,
                RoleClaimType = JwtClaimTypes.Role,

            };

            options.Prompt = "consent";
        });

此外,查看 Fiddler 中的各种请求以找出您的索赔问题可能会有所帮助。

将此设置为 True 也可以提供帮助:

options.GetClaimsFromUserInfoEndpoint = true;

推荐阅读