OpenID Connect: как добавить данные пользовательских утверждений в поток учетных данных клиента
Я настраиваю поток учетных данных клиента с моим сервером идентификации, чтобы получить токен доступа от клиента. Я могу получить токен доступа с помощью следующего кода,
Конфигурация сервера идентификации:
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). Не могли бы вы рассказать мне, как добавить уникальный ключ, например (UserId), из моей базы данных, когда JWT создается с его данными утверждений при создании токена.
2 ответа
Во-первых, вам нужно создать настраиваемый атрибут userId на портале Azure и применить его к выбранному приложению. Затем следуйте этому примеру, обновите пользователя с помощью Graph API.
Если вы используете встроенные пользовательские потоки, вам нужно выбрать для своего приложения "userId". Если вы используете настраиваемую политику, то следующий процесс. Токен JWT показывает только выходные утверждения настраиваемой политики Azure AD B2C. Создание и обновление настраиваемой политики состоит из нескольких этапов. Вот ссылка, чтобы узнать больше о том, как создать собственный атрибут
Вы должны реализовать настраиваемое хранилище пользователей для проверки пользователя и добавления утверждений из базы данных. Измените код запуска, как показано ниже, класс 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");
}
}
}