本文介绍了无法在AuthorizationHandlerContext身份服务器4 JWT中访问自定义声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个配置文件服务,可将声明添加到令牌中

I have a profile service that adds the claim to the token

个人资料服务

public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var sub = context.Subject.GetSubjectId();
            var user = await _userManager.FindByIdAsync(sub);

            var claims = new List<Claim>();

            var userClaims = await _userManager.GetClaimsAsync(user);
            foreach (var userClaim in userClaims)
            {
                claims.Add(new Claim(userClaim.Type, userClaim.Value));
            }

            context.IssuedClaims.AddRange(claims);
        }

JWT令牌

{
  "nbf": 1608909669,
  "exp": 1608996069,
  "iss": "https://localhost:5001",
  "aud": "https://localhost:5001/resources",
  "client_id": "Local",
  "sub": "307f4f24-71a5-4aee-8505-f87b58a1eb2e",
  "auth_time": 1608908167,
  "idp": "local",
  "IdentityServer": [
    "Read",
    "Create",
    "Update",
    "Delete"
  ],
  "Product": [
    "Read",
    "Create",
    "Update",
    "Delete"
  ],
  "jti": "87FA14C0153AD10D0E16A721720D19DB",
  "sid": "C739A377659C364AA29040FEE2FB4FA2",
  "iat": 1608909669,
  "scope": [
    "openid",
    "profile",
    "email"
  ],
  "amr": [
    "pwd"
  ]
}

只能在 AuthorizationHandlerContext

StartUp.cs

services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                // base-address of your identityserver
                options.Authority = configuration.GetSection("IdentityServer:OAuth:AuthorizationUrl").Value;

                // name of the API resource
                options.ApiName = AuthorizePolicy.apiScope;
            });


app.UseAuthentication();

为什么我无法访问 IdentityServer,产品声明.我正在使用Identity Server 4最新版本

Why I am not able to access IdentityServer , Product claim. I am using Identity server 4 latest version

更新1

在帐户控制器的登录过程中添加以下代码时

While adding the below code during the login process in the Account controller

            var principal = await _claimsFactory.CreateAsync(user);
            var claims = principal.Claims.ToList();

            var isuser = new IdentityServerUser(user.Id)
            {
                DisplayName = user.UserName,
                AdditionalClaims = claims
            };

            await HttpContext.SignInAsync(isuser, props);

现在,用户包含所有其他声明,但是,如果我删除其中一个声明,则JWT令牌已刷新,但是,用户标识仍然包含旧值,要刷新该标识,我需要再次明确登录用户,不适合,我该如何解决?

Now the user contains all the additional claims, but if I remove one of the claims the JWT token is refreshed, however, the User Identity still contains the old value, to refresh the identity I need to explicitly login the user again which is not suitable, how can I fixed this ?

推荐答案

默认情况下,用户不会包含自定义声明,而是需要手动映射您关心的传入声明.

by default custom claims will not be included in the User, instead you need to manually map the incoming claims that you care about.

通常,您将添加以下内容:

Typically, you would add this:

public void ConfigureServices(IServiceCollection services)
{
    // By default, Microsoft has some legacy claim mapping that converts
    // standard JWT claims into proprietary ones. This removes those mappings.
    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
    JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

,然后在AddOpenIDConnect选项中,设置:

and then in the AddOpenIDConnect options, set:

options.ClaimActions.MapUniqueJsonKey("website", "website");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
options.ClaimActions.MapUniqueJsonKey("birthdate", "birthdate");

或者

options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce");

相同的配置如下所示:

 }).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");

                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";
            });

如果您不想处理令牌并在其中添加声明,那么另一种方法是在授权策略中查找其他用户详细信息.关于自定义授权策略了解更多信息.

If you don't want to deal with the tokens and add the claims there, then an alternative is to lookup additional user details in your authorization polices.See this page about Custom Authorization Policies for more details.

这篇关于无法在AuthorizationHandlerContext身份服务器4 JWT中访问自定义声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 04:09