【问题标题】:OpenID Connect: How to add custom claims data in the client credential flowOpenID Connect:如何在客户端凭证流中添加自定义声明数据
【发布时间】:2020-08-19 19:51:22
【问题描述】:

我正在使用我的身份服务器设置客户端凭据流,以从客户端获取访问令牌。我可以使用以下代码获取访问令牌,

  • 身份服务器配置:

     public void Configuration(IAppBuilder app)
    {
        app.Map("/identity", idsrvApp =>
        {
            var corsPolicyService = new DefaultCorsPolicyService()
            {
                AllowAll = true
            };
    
            var idServerServiceFactory = new IdentityServerServiceFactory()
            .UseInMemoryClients(Clients.Get())
            .UseInMemoryScopes(Scopes.Get())
            .UseInMemoryUsers(Users.Get());
    
            var options = new IdentityServerOptions
            {
                Factory = idServerServiceFactory,
                SiteName = "Demo",
                IssuerUri = IdentityConstants.IssuerUri,
                PublicOrigin = IdentityConstants.STSOrigin,
                SigningCertificate = LoadCertificate()
            };
    
            idsrvApp.UseIdentityServer(options);
        });
    }
    
  • 身份服务器 - 客户端配置:

    public static class Clients
    {
        public static IEnumerable<Client> Get()
        {
        return new[]
         {
            new Client
            {
                 ClientId = "ClientSDK",
                 ClientName = "Client SDK (Client Credentials)",
                 Flow = Flows.ClientCredentials,
                 AllowAccessToAllScopes = true,
    
                ClientSecrets = new List<Secret>()
                {
                    new Secret(IdentityConstants.ClientSecret.Sha256())
                }
            }
         };
    }
    

    }

  • MVC 客户端:

      var oAuth2Client = new TokenClient(
                  IdentityConstants.STSTokenEndpoint,
                  "ClientSDK",
                    IdentityConstants.ClientSecret);
    
        var tokenResponse = oAuth2Client.RequestClientCredentialsAsync("MyScope").Result;
    
        return tokenResponse.AccessToken;
    

我可以获得访问令牌(即 JWT)。谁能告诉我如何在创建令牌时使用其声明数据创建 JWT 时,如何从我的数据库中添加一个唯一键,例如 (UserId)。

【问题讨论】:

  • @你已经配置了内存用户,你想从你的应用程序数据库中验证用户并从数据库中添加对令牌的声明吗?

标签: oauth-2.0 openid-connect claims clientcredential


【解决方案1】:

首先,您需要在 Azure 门户上创建自定义属性“userId”,并将其应用于选定的应用程序。然后按照这个例子, Update user using Graph API

如果您使用的是内置用户流,则需要为您的应用程序选择“userId”。 如果您使用的是自定义策略,请遵循以下流程。 JWT 令牌仅显示 Azure AD B2C 自定义策略的输出声明。创建和更新自定义策略是一个多步骤过程。这里是阅读更多关于How to create custom attribute的链接

【讨论】:

    【解决方案2】:

    您应该实现自定义用户存储以验证用户并从数据库添加声明。如下更改启动代码,Userrepository 类代表数据库通信以验证用户并从数据库获取声明:

    var idServerServiceFactory = new IdentityServerServiceFactory()
       .UseInMemoryClients(Clients.Get())
       .UseInMemoryScopes(Scopes.Get())
       .AddCustomUserStore();
    

    添加以下类并根据您的要求进行更改:

    public static class CustomIdentityServerBuilderExtensions
    {
        public static IIdentityServerBuilder AddCustomUserStore(this IIdentityServerBuilder builder)
        {                   
            builder.AddProfileService<UserProfileService>();           
            builder.AddResourceOwnerValidator<UserResourceOwnerPasswordValidator>();
            return builder;
        }
    }
    
    public class UserProfileService : IProfileService
    {
        public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
                UserRepository userRepository=new UserRepository();
                var user = userRepository.GetUserById(int.Parse(context.Subject.GetSubjectId()));
                if (user != null)
                {
                    var userTokenModel = _mapper.Map<UserTokenModel>(user);
                    var claims = new List<Claim>();
                    claims.Add(new Claim("UserId", user.UserId));
                    // Add another claims here 
                    context.IssuedClaims.AddRange(claims);                    
        }
        public async Task IsActiveAsync(IsActiveContext context)
        {          
        }
    }
    
    public class UserResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
    {        
        public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
        {           
                UserRepository userRepository=new UserRepository();
                var userLoginStatus = userRepository.GetUserById(context.UserName, context.Password);
    
                if (userLoginStatus != null)
                {
    
                        context.Result = new GrantValidationResult(userLoginStatus.UserId.ToString(),
                             OidcConstants.AuthenticationMethods.Password);                   
                }
                else
                {                    
                    context.Result = new GrantValidationResult(TokenRequestErrors.InvalidClient, 
                            "Wrong Credentials");
                }            
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-18
      • 1970-01-01
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 2020-08-22
      • 1970-01-01
      相关资源
      最近更新 更多