После некоторого расследования я решил обновить ответ.
Прежде всего, context.IsActive
используется для указания того, следует ли выполнять GetProfileDataAsync
.
Проблема заключается в том, что клиент запускает несколько вызовов в ProfileService для получения информации. Эти отдельные вызовы инициируются клиентом и выполняются после входа пользователя в систему.
Для прямого ответа вы можете добавить код в метод Login. Когда пользователь не активен, вы можете ответить сообщением об ошибке. Я думаю, что это лучшее место для проверки, потому что это предотвратит множество действий.
Следующий фрагмент взят из одного из образцов IdentityServer. Он обрабатывает запрос на вход.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginInputModel model, string button)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(model.Username, model.Password, model.RememberLogin, lockoutOnFailure: true);
if (result.Succeeded)
{
var user = await _userManager.FindByNameAsync(model.Username);
// Assume user has property IsActive for this example.
// You can implement this anyway you like.
if (user.IsActive)
{
...
}
}
ModelState.AddModelError("", AccountOptions.InvalidCredentialsErrorMessage);
}
// something went wrong, show form with error
var vm = await BuildLoginViewModelAsync(model);
return View(vm);
}
Вы можете добавить любое понравившееся вам сообщение, используя ModelState.AddModelError
.
Теперь предположим, что пользователь вошел в систему и позже был деактивирован, тогда ProfileService не будет возвращать претензии. Вместо этого это приведет к 401: пользователь не активен.
Затем клиент выдаст исключение, потому что запрос должен быть успешным: HttpResponseMessage.EnsureSuccessStatusCode
.
К счастью, есть опция для обработки исключения. И это для реализации событий OIDC. Это простой пример:
services.AddOpenIdConnect("oidc", "Open Id connect", options =>
{
options.Events = new OpenIdConnectEvents()
{
// When a user is not active this will result in a 401
OnAuthenticationFailed = (context) =>
{
// Clear the exception, otherwise it is re-thrown after this event.
context.HandleResponse();
// Handle the exception, e.g. redirect to an error page.
context.Response.Redirect($"LoginError/?message={context.Exception.Message}");
return Task.FromResult(0);
},
}
}
Это может быть то, что вы ищете.