【问题标题】:How to get claims only via userinfo endpoint and not in the access token如何仅通过 userinfo 端点而不是在访问令牌中获取声明
【发布时间】:2018-05-28 17:01:05
【问题描述】:

我想通过 userinfo 端点获取自定义声明。这也有效,但所有自定义声明也在访问令牌中。我以这种方式理解它,有可能我可以在访问令牌中放置一个或两个声明(如电子邮件或姓名),并且所有其他声明(给定名称,...)都通过 userinfo 端点访问。 (并且它们不在访问令牌中)

我的 ProfileService 看起来像这样:

public class ProfileService : IProfileService
    {
        private readonly IUserClaimsPrincipalFactory<CustomUser> _claimsFactory;
        private readonly UserManager<CustomUser> _userManager;

        public ProfileService(UserManager<CustomUser> userManager,    IUserClaimsPrincipalFactory<CustomUser> claimsFactory)
        {
            _claimsFactory = claimsFactory;
            _userManager = userManager;
        }

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

            var claims = principal.Claims.ToList();
            claims = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();

            claims.Add(new Claim(JwtClaimTypes.GivenName, user.FirstName));

            context.IssuedClaims = claims;

        }

        public async Task IsActiveAsync(IsActiveContext context)
        {
            var sub = context.Subject.GetSubjectId();
            var user = await _userManager.FindByIdAsync(sub);
            context.IsActive = user != null;
        }
    }

这是我的 config.cs 文件:

return new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile(),
                new IdentityResources.Email(),
            };
        }

 public static IEnumerable<ApiResource> GetApiResources()
      {
          return new List<ApiResource>
          {
              new ApiResource("api1", "My API", new [] {JwtClaimTypes.Name })
          };
      }
new Client
                {
                    ClientId = "xxx",
                    ClientName = "xxx",
                    //AccessTokenType = AccessTokenType.Reference,
                    AccessTokenType = AccessTokenType.Jwt,
                    AllowedGrantTypes = GrantTypes.Implicit,
                    AllowAccessTokensViaBrowser = true,
                    RequireConsent = false,

                    RedirectUris =           { "http://localhost:4200/home" },
                    PostLogoutRedirectUris = { "http://localhost:4200/unauthorized" },
                    AllowedCorsOrigins =     { "http://localhost:4200" },

                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Email,
                        "api1"
                       }
                }
            };

我是不是误会了?

【问题讨论】:

    标签: c# authentication asp.net-core openid identityserver4


    【解决方案1】:

    GetProfileDataAsync 被调用了两次,但上下文不同。

    1. 对于访问令牌Context.Caller = ClaimsProviderAccessToken
    2. 对于身份令牌Context.Caller = UserInfoEndpoint

    请注意,对于这两种情况,请求的声明有所不同。

    如果您只想为身份添加声明,您可以通过将这些声明添加到过滤器 (IdentityResource) 来配置身份服务器以包含这些声明,在这种情况下,您不需要在 GetProfileDataAsync 中添加其他声明全部。或者,如果您想添加特定声明,请检查当前上下文。

    所以在GetProfileDataAsync 中,您可能会有如下内容:

    if (Context.Caller == "UserInfoEndpoint")
        claims.Add(new Claim(JwtClaimTypes.GivenName, user.FirstName));
    

    这应该只将声明添加到用户信息。

    【讨论】:

    • 感谢您的解释。这正是我想要的
    猜你喜欢
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 2021-05-24
    • 2019-04-19
    • 2020-09-09
    相关资源
    最近更新 更多