首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在AuthorizationHandlerContext标识服务器4 JWT中无法访问自定义声明

在AuthorizationHandlerContext标识服务器4 JWT中无法访问自定义声明
EN

Stack Overflow用户
提问于 2020-12-25 15:57:22
回答 1查看 915关注 0票数 0

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

配置文件服务

代码语言:javascript
复制
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令牌

代码语言:javascript
复制
{
  "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

代码语言:javascript
复制
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 , Product声明。我正在使用标识服务器4最新版本。

更新1

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

代码语言:javascript
复制
            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令牌被刷新,但是,用户标识仍然包含旧值,为了刷新身份,我需要显式地再次登录用户(这是不合适的),我如何解决这个问题?

EN

回答 1

Stack Overflow用户

发布于 2020-12-26 14:52:37

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

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

代码语言:javascript
复制
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选项中设置:

代码语言:javascript
复制
options.ClaimActions.MapUniqueJsonKey("website", "website");
options.ClaimActions.MapUniqueJsonKey("gender", "gender");
options.ClaimActions.MapUniqueJsonKey("birthdate", "birthdate");

另一个选择

代码语言:javascript
复制
options.ClaimActions.MapAllExcept("iss", "nbf", "exp", "aud", "nonce");

相同的配置可能如下所示:

代码语言:javascript
复制
 }).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";
            });

如果您不想处理令牌并在那里添加声明,那么另一种方法是在授权策略中查找其他用户详细信息。有关自定义授权策略的详细信息,请参阅此页面。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65449615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档