OpenID Connect:如何在客户端凭据流中添加自定义声明数据

时间:2020-05-05 07:53:27

标签: oauth-2.0 openid-connect claims clientcredential

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

  • 身份服务器配置:

     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时创建一个JWT及其声明数据时从我的数据库中添加一个唯一的键,例如(UserId)。

enter image description here

2 个答案:

答案 0 :(得分:0)

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

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

的链接。

答案 1 :(得分:0)

您应该实现自定义用户存储,以验证用户并从数据库添加声明。更改启动代码,如下所示,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");
            }            
    }
}