经过一番调查后,我决定更新答案。
首先,context.IsActive
用于指示是否GetProfileDataAsync
应该被执行。
“问题”是客户端启动对 ProfileService 的多次调用来检索信息。这些单独的调用由客户端发起,并在用户登录后进行。
For a 直接回应您可以将代码添加到登录方法中。当用户不活跃时,您可以使用错误消息进行响应。我认为这是最好的检查位置,因为它会阻止很多操作。
以下代码片段取自 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);
},
}
}
这可能就是您正在寻找的。