令牌中缺少“角色”声明-NET CORE 3.1和IS4

时间:2020-07-21 13:50:58

标签: c# cookies oauth-2.0 identityserver4 asp.net-core-3.1

我有一个负责验证用户身份的服务。

更新后:

  • IdentityServer4从2.3.2到4.0.2;

弹出一个问题:

  • 令牌已不再包含必需的用户声明。

以这种方式配置服务:

  • Startup.cs包含:
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);
}
  • 设置cookie的(针对IS4 4.0.2更新)登录控制器包含:
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);

  • 在更新IS4之前,控制器如下所示:
await HttpContext.SignInAsync(user.SubjectId, props, user.Claims.ToArray());

在受保护的api项目中:

  • 当尝试验证我的控制器请求时(在另一个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已设置:

    Startup.cs上的授权服务上的
  • startup.cs

  • 关于AuthorizeRoles属性的OnAuthorization方法: OnAuthorization

问题:

  • 为什么令牌不包含添加到ClaimsIdentity对象的所有声明?
  • 如何解决该问题,以便令牌再次包含“角色”声明?

涉及的技术:

  • Net Core 3.1
  • IdentityServer4 4.0.2

1 个答案:

答案 0 :(得分:0)

默认情况下,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;