如何将IsActiveAsync故障信息传递给用户和客户端? [英] How do I pass IsActiveAsync failure information to users and clients?

查看:28
本文介绍了如何将IsActiveAsync故障信息传递给用户和客户端?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的IdentityServer4项目中,我实现了IProfileService。在使用隐式流和混合流时,在人工用户通过登录网页成功进行身份验证后,将多次调用IsActiveAsync方法。

我注意到当context.Caller是下列值之一时会调用它:

  • AuthorizeEndpoint(用户声明)
  • AuthorizationCodeValidation(用户声明)
  • AccessTokenValidation(无用户声明)

由于错误,我的代码集context.IsActive = false-当这种情况发生时,用于访问登录页面的Web浏览器被重定向回登录页面,没有错误消息或原因信息。用户会感到困惑,为什么他们已经成功地进行了身份验证,但却被提示再次登录。也没有添加新的查询字符串参数。

IdentityServer4日志显示原因:

[23:16:40信息]IdentityServer4.ResponseHandling.AuthorizeInteractionResponseGenerator 显示登录:用户未处于活动状态

现在,假设我的IsActive = false代码不是错误,而实际上是人为设计的(例如,因为用户的帐户确实在不同的OAuth/OpenIDConnect HTTP请求之间的微秒内被禁用),在这种情况下,我如何确保将此消息呈现给用户和/或客户端软件?

推荐答案

经过一番调查后,我决定更新答案。

首先,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);
        },
    }
}

这可能就是您要找的。

这篇关于如何将IsActiveAsync故障信息传递给用户和客户端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆