【问题标题】:ASP.Net Core 3.0 merged rolesASP.Net Core 3.0 合并角色
【发布时间】:2020-06-22 16:18:53
【问题描述】:

在我当前的 Web 应用程序中,我使用声明“customRole”(加上它的值)对用户进行身份验证,并使用属性“Authorize”来允许/拒绝对操作的访问。 一切正常,直到用户作为同一类型的多个声明,访问一直被拒绝,并且在调试时我注意到只为“customRole”类型创建了一个声明,并且它的值更改为连接字符串两个值。

我期待两个相同类型的声明,但每个声明的值不同。 我将 ASPNET.Core 3.0 与 IdentityServer4 一起使用,但根据 here 所写的内容,IdentityServer4 不是问题。

例如,我在 IdentityServer 端添加这样的声明:

uClaims.Add(new Claim("customRole", "superadmin"));
uClaims.Add(new Claim("customRole", "simpleadmin"));

但是当我进入客户端应用程序时,我得到这样的声明:

customRole = ["superadmin","simpleadmin"]

这打破了我在客户端应用程序的操作中使用的角色属性背后的所有逻辑:

[Authorize(Roles = "superadmin")]

我尝试按照上一个链接 (here) 中讨论的内容进行操作,但问题仍然存在。

是否缺少任何东西,因此声明被分开而不是与不同的值合并?还是以允许值数组的不同方式使用授权?

还应该提到,我在上个月第一次开始使用 Asp.NetCore、IdentityServer4 和 Roles,我正处于学习曲线中。

感谢您的宝贵时间,干杯

【问题讨论】:

    标签: asp.net-core identityserver4 claims


    【解决方案1】:

    您可以在身份验证后更改您的 Principal,并将该声明转换为多个。

            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
              ...
                options.Events = new JwtBearerEvents();
                options.EventsType = typeof(CustomJwtBearerEvents);
            });
    
            public class CustomJwtBearerEvents : JwtBearerEvents
            {
               public override async Task TokenValidated(TokenValidatedContext context)
               {
                  var claims = context.Principal.Claims.ToList();
    //write your code
                      claims.Add(new Claim("key", "value"));
                      context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, 
        "Bearer"));        }
            }
    

    找到您的特定声明('customclaim'),并检查它的值,如果包含多个值,则为每个值添加一个声明。

    【讨论】:

      【解决方案2】:

      这是因为[Authorize(Roles="superadmin")] 属性检查当前身份是否包含ClaimsIdentity.RoleClaimType(http://schemas.microsoft.com/ws/2008/06/identity/claims/role) 类型的声明,其中声明的值等于Roles 参数指定的值。

      superadminsimpleadmincustomRole 的类型,而不是默认的 http://schemas.microsoft.com/ws/2008/06/identity/claims/role 。所以授权失败。您可以配置AddOpenIdConnect 中间件来设置RoleClaimType

      JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
      
      services.AddAuthentication(options =>
      {
          options.DefaultScheme = "Cookies";
          options.DefaultChallengeScheme = "oidc";
      })
      .AddCookie("Cookies")
      .AddOpenIdConnect("oidc", options =>
      {
          options.Authority = "http://localhost:5000";
          options.RequireHttpsMetadata = false;
      
          options.ClientId = "mvc";
          options.ClientSecret = "secret";
          options.ResponseType = "code";
      
          options.SaveTokens = true;
      
          options.Scope.Add("api1");
          options.Scope.Add("offline_access");
          options.TokenValidationParameters.RoleClaimType = "customRole";   //add this line
      
      });
      

      这样 MVC 将在触发 [Authorize(Roles="superadmin")] 时检查 customRole 声明。

      【讨论】:

        【解决方案3】:

        我找到了原因。 我在“启动”上使用

        .AddOpenIdConnect(IdentityServerConstants.ProtocolTypes.OpenIdConnect, options => { options.ClaimActions.MapUniqueJsonKey("customRole", "customRole"); }

        而不是

        .AddOpenIdConnect(IdentityServerConstants.ProtocolTypes.OpenIdConnect, options => { options.ClaimActions.MapJsonKey("customRole", "customRole"); }

        现在,所有相同类型的声明都会在 clientApp 中分离,而不是连接为一个。我认为我使用了错误的映射器,因为我从 identityServer4 快速入门教程之一(或谷歌搜索的其他人示例)复制了 :) 希望,我自己的回答可以防止其他人不得不浪费时间来理解事情应该按照他们应该的方式工作:)

        @南宇: 对 RoleClaimType 选项的更正解决了使用 type = "customRole" 而不是默认值的问题,但同一类型的多个声明仍然连接在一起。但是,从您的评论中我学到了一些新东西,自定义了 roleClaimType,谢谢您

        @Mehrdad 使用我正在使用的配置,声明未在上下文中列出,仅显示“nbf”、“iss”、“aud”等声明,自定义声明不显示在此处(不知道为什么)。但是,我还是搞砸了,发现有可能,就像你说的,在这里添加额外的声明,所以它将来可能会有用,感谢分享信息

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-13
          • 2021-12-18
          • 1970-01-01
          • 1970-01-01
          • 2021-09-04
          • 2017-12-01
          • 1970-01-01
          • 2020-05-18
          相关资源
          最近更新 更多