“角色"是指令牌缺少声明-NET CORE 3.1& IS4 [英] "Role" Claim is missing from the token - NET CORE 3.1 & IS4

查看:116
本文介绍了“角色"是指令牌缺少声明-NET CORE 3.1& IS4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a service which is responsible for authenticating users.

更新后:

  • IdentityServer4从2.3.2到4.0.2;

弹出一个问题:

  • 该令牌不再包含必需的用户声明.

通过以下方式配置服务:

The service is configured this way:

  • 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项目中:

      In the api project which is being protected:

      • 当尝试验证我的控制器请求时(在其他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项目的启动包含:

      The startup of the protected api project contains:

      builder.AddAuthorization(ConfigureAuthorization);
      
      var auth = builder.Services.AddAuthentication(ConfigureAuthenticationOptions);
      
      auth.AddIdentityServerAuthentication(ConfigureIdentityServerAuthentication);
      

      ConfigureIdentityServerAuthentication方法设置一些IdentityServerAuthenticationOptions.尚未设置RoleClaimType,因为它具有默认值'role',这是预期值.

      The ConfigureIdentityServerAuthentication method sets some IdentityServerAuthenticationOptions. The RoleClaimType is not being set because it have a default value 'role' which is the expected one.

      IdentityServerAuthenticationOptions来自'IdentityServer4.AccessTokenValidation'程序包3.0.1版.

      The IdentityServerAuthenticationOptions is from the 'IdentityServer4.AccessTokenValidation' package version 3.0.1.

      以下是两个屏幕快照,用于证明已设置RoleClaimType:

      Here are two screenshots to prove that the RoleClaimType is set:

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

      • on the authorization service on Startup.cs:

      关于AuthorizeRoles属性的OnAuthorization方法:

      on the OnAuthorization method from the AuthorizeRoles attribute:

      问题:

      • 为什么令牌不包含添加到ClaimsIdentity对象中的所有声明?
      • 如何解决此问题,以使令牌包含角色"?再次提出索赔?

      涉及的技术:

      • Net Core 3.1
      • IdentityServer4 4.0.2

      推荐答案

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

      by default IdentityServer and ASP.NET core have different opinion on what the name of the RoleClaim should be.

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

      Add this code in your client to fix that mapping (setting the TokenValidationParameters option)

             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中的各种请求以找出您的索赔问题也可能会有所帮助.

      Also, it can be helpful to look at the various requests in Fiddler to figure out your claim issues.

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

      Settings this one to True can also help out:

      options.GetClaimsFromUserInfoEndpoint = true;
      

      这篇关于“角色"是指令牌缺少声明-NET CORE 3.1&amp; IS4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆