无法访问 JWT 令牌 .NET Core 中的角色

时间:2023-03-29
本文介绍了无法访问 JWT 令牌 .NET Core 中的角色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个使用 .NET Core API、Keycloak 和 JWT Token 制作的应用程序.

I have an application made with .NET Core API, Keycloak and JWT Token.

到目前为止,我一直在使用旧版本的 Keycloak,当它创建 JWT 令牌时,它在有效负载上写入了角色:

The older version of Keycloak that I've been using so far, when it created the JWT Token it wrote the roles here on payload:

{
    "user_roles": [
        "offline_access",
        "uma_authorization",
        "admin",
        "create-realm"
  ]
}

但是现在我更新它之后,它在payload上写了角色:

But now after I updated it, it's writing the roles here on payload:

{
  "realm_access": {
    "roles": [
      "create-realm",
      "teacher",
      "offline_access",
      "admin",
      "uma_authorization"
    ]
  },
}

我需要知道如何将这个旧代码更改为新代码,告诉它不要查看 user_roles,而是查看 realm_access 然后角色.

And I need to know how to change this old code to the new one, to tell that don't look at user_roles, but do look at realm_access then to roles.

public void AddAuthorization(IServiceCollection services)
{
    services.AddAuthorization(options =>
    {
        options.AddPolicy("Administrator", policy => policy.RequireClaim("user_roles", "admin"));
        options.AddPolicy("Teacher", policy => policy.RequireClaim("user_roles", "teacher"));
        options.AddPolicy("Pupil", policy => policy.RequireClaim("user_roles", "pupil"));
        options.AddPolicy(
            "AdminOrTeacher",
            policyBuilder => policyBuilder.RequireAssertion(
                context => context.User.HasClaim(claim =>
                               claim.Type == "user_roles" && (claim.Value == "admin" || claim.Value == "teacher")
                          ))
        );
    });
}

推荐答案

以下代码会将 Keycloak (v4.7.0) 中的realm_access.roles"-claim (JWT Token) 转换为 Microsoft Identity Model 角色声明:

The following code will transform "realm_access.roles"-claim (JWT Token) from Keycloak (v4.7.0) into Microsoft Identity Model role-claims:

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
    ...
}

public class ClaimsTransformer : IClaimsTransformation
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        ClaimsIdentity claimsIdentity = (ClaimsIdentity)principal.Identity;

        // flatten realm_access because Microsoft identity model doesn't support nested claims
        // by map it to Microsoft identity model, because automatic JWT bearer token mapping already processed here
        if (claimsIdentity.IsAuthenticated && claimsIdentity.HasClaim((claim) => claim.Type == "realm_access"))
        {
            var realmAccessClaim = claimsIdentity.FindFirst((claim) => claim.Type == "realm_access");
            var realmAccessAsDict = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(realmAccessClaim.Value);
            if (realmAccessAsDict["roles"] != null)
            {
                foreach (var role in realmAccessAsDict["roles"])
                {
                    claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, role));
                }
            }
        }

        return Task.FromResult(principal);
    }
}

这篇关于无法访问 JWT 令牌 .NET Core 中的角色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:Swashbuckle .NET Core 2 中 JWT 承载的授权 下一篇:如何在 .net 核心中记录授权尝试

相关文章