Попытка добавить IdentityServer4 в качестве органа идентификации для приложения Javascript с пользовательским хранилищем пользователей
Я следовал документации IdentityServer4, чтобы создать базовую локальную реализацию, используя конфигурацию теста по умолчанию (с клиентами и пользователями в памяти). На этом этапе IS4 инициализируется следующим образом:
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients())
.AddTestUsers(Config.GetUsers());
Затем я следовал инструкциям по созданию простого приложения Javascript с использованием библиотеки oidc-connect. Это работает нормально, так что теперь у меня есть приложение Javascript, которое позволяет пользователю войти через мой экземпляр IS4. Это приложение JS представлено в IS4 как клиент, использующий неявный поток согласно инструкциям.
Теперь я хочу интегрировать свой экземпляр IS4 с моим магазином реальных пользователей. После прочтения нескольких статей мне кажется, что мне нужно предоставить IResourceOwnerPasswordValidator
а также IProfileService
согласно этому так посту и различным другим.
Я сделал это, сейчас просто используя фиктивный репозиторий пользователей, который работает с фиктивным набором пользователей в памяти, а не с реальным внешним хранилищем. Моя инициализация IS4 теперь выглядит так:
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryClients(Config.GetClients());
builder.Services.AddTransient<IProfileService, CustomProfileService>();
builder.Services.AddTransient<IResourceOwnerPasswordValidator, CustomResourceOwnerPasswordValidator>();
Теперь, когда я возвращаюсь и тестирую свое приложение Javascript, оно становится странным. При попытке войти я попал на экран входа в IS4. Я ввожу учетные данные, которые я ожидаю, но неверное имя пользователя или пароль возвращается. Отладка Я вижу, что код никогда не входит в мой ValidateAsync
метод в CustomResourceOwnerPasswordValidator
, Однако случайно я обнаружил, что если я ввожу либо bob, либо alice в качестве имени пользователя и пароля (например, при вводе bob в качестве имени пользователя и пароля), то я аутентифицируюсь и могу вернуться к своему приложению. Это не имеет никакого смысла. Я уверен, что не случайно, что это имена пользователей, которые являются двумя пользователями по умолчанию, используемыми образцами пользователей в памяти IdentityServer4, но вы можете видеть выше, я больше не использую пользователей в памяти. На самом деле, это все еще верно, даже когда я комментирую GetUsers
метод из Config.cs
,
Я не могу этого объяснить, но в любом случае я хочу использовать мой пользовательский магазин. Поэтому я прочитал немного дальше и увидел предложения, которые я могу использовать только IResourceOwnerPasswordValidator
с клиентами, которые имеют GrantTypes.ResourceOwnerPassword
, Однако, когда я изменяю клиент моего приложения Javascript в IS4, чтобы использовать этот тип предоставления, при попытке войти в систему я вижу ошибку unauthorized_client.
Так что я застрял. Я думал, что, поскольку у меня есть настройки, работающие с пользователями в оперативной памяти, использование реального пользовательского магазина не составит большого труда, но, очевидно, что-то мне не хватает. Ваше руководство будет высоко ценится.
1 ответ
Вам не нужно вводить свой ProfileService
как зависимость в ваших услугах.
Вам нужно что-то вроде:
services.AddIdentityServer()
.AddProfileService<CustomProfileService>()
//..... more code
А кроме того - ваш CustomProfileService
не нужно реализовывать IProfileService
(метод принимает универсальный).
Настоящая "магия" происходит в AccountController
в:
/// <summary>
/// Handle postback from username/password login
/// </summary>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model)
{
// logic
}
Там, в LoginInputModel
у вас есть имя пользователя, пароль и т. д., что вам нужно проверить, поэтому в конце нет реальной необходимости IProfileService
если вы пишете свой собственный пользовательский менеджмент.