#angular #asp.net-core #identityserver4 #abp
#angular #asp.net-core #identityserver4 #abp
Вопрос:
У нас есть решение, основанное на стороннем фреймворке ABP и его многоуровневой архитектуре:
Мы используем Angular в качестве веб-интерфейса и IdentityServer4 для аутентификации пользователя. Итак, мы запускаем 2 хоста — хост HTTP API и хост IdentityServer, а что касается web face — он работает стандартным образом: поле входа, пользователь вводит учетные данные — вуаля.
Тем не менее, у нас есть пользовательская настройка, позволяющая использовать одно и то же имя для входа под другим клиентом. Список клиентов отображается в виде выпадающего списка в пользовательском интерфейсе, и мы хотели бы повторно авторизовать пользователя с выбранным клиентом вместо пользователя, вошедшего в систему в данный момент. Это должно выглядеть как простая перезагрузка страницы. Проблема в том, что у меня нет четкого понимания, как это реализовать. Я пытался использовать следующий вызов с уровня приложения, но он не работает (ошибка «Обработчик аутентификации не зарегистрирован для идентификатора scheme «.Приложение ‘…», но я не знаю, как настроить конфигурацию аутентификации на прикладном уровне, чтобы иметь возможность работать с нашим IdentityServer):
[HttpGet]
public async Task<TenantDto> SwitchTenantForCurrentUser(Guid? tenantId)
{
var abxUser = await _abxUserRepository.FirstOrDefaultAsync(x => x.Login == CurrentUser.UserName amp;amp; x.Tenant.AbpId == tenantId);
if (abxUser == null)
return null;
using var _ = _abpCurrentTenant.Change(tenantId);
var currentTenant = await _abxTenantRepository.FirstOrDefaultAsync(x => x.AbpId == _abpCurrentTenant.Id.Value);
var identityUser = await _identityUserRepository.FindByNormalizedUserNameAsync(abxUser.Login.ToUpper());
if (await _signInManager.CanSignInAsync(identityUser))
{
await _signInManager.SignOutAsync();
await _signInManager.SignInAsync(identityUser, true);
}
return ObjectMapper.Map<Tenant, TenantDto>(currentTenant); // Not decided yet what to return, it depends on proper implementation
}
Часть конфигурации хоста Http API относительно аутентификации:
private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
{
context.Services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = configuration["AuthServer:Authority"];
options.RequireHttpsMetadata = true;
options.ApiName = "CentralTools";
options.JwtBackChannelHandler = new HttpClientHandler
{
//TODO: use valid certificate in future and change the logic
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
});
context.Services.AddAbpIdentity().AddDefaultTokenProviders();
Ответ №1:
Миссия выполнена. Шаги:
-
СЕРВЕРНАЯ часть: внедрите и зарегистрируйте пользовательский валидатор типа гранта в проекте IdentityServer:
SwitchToTenantGrantValidator: IdentityServer4.Проверка.IExtensionGrantValidator
Короче говоря, ValidateAsync принимает данные аутентифицированного пользователя (его токен доступа, идентификатор клиента и т.д.) И принимает решение, должен ли пользователь быть допущен. Метод записывает данные целевого клиента в объект context resu<
-
ИНТЕРФЕЙС: выполните вызов IdentityServer с заданным типом пользовательского разрешения, предоставив данные, необходимые для (1). Мы использовали Angular, поэтому мне пришлось расширить OAuthService для поддержки пользовательского запроса типа grant;
-
Приведите все в порядок (если (2) прошло успешно), чтобы отобразить правильные данные в пользовательском интерфейсе: очистите старые состояния и т.д.