ASP.NET Core - 从 AuthenticationHandler 获取消息

Kir*_*Kir 8 asp.net authentication asp.net-core

我已经实现了AuthenticationHandler. 它返回AuthenticationResult.Fail("This is why you can't log in");

我原以为这条消息会出现在正文中,或者至少出现在 HTTP 状态文本中,但我得到的是一个空白的 401 响应。

有没有办法为 ASP.NET 核心中失败的身份验证尝试提供附加信息?

小智 11

重写 HandleChallengeAsync:

在下面的示例中,failReason是我的 AuthenticationHandler 实现中的一个私有字段。我不知道这是否是传递失败原因的最好方法。但AuthenticationPropertiesAuthenticateResult.Fail方法在我的测试中并未成功HandleChallengeAsync

public class CustomAuthenticationHandler<TOptions> : AuthenticationHandler<TOptions> where TOptions : AuthenticationSchemeOptions, new()
{
    private string failReason;

    public CustomAuthenticationHandler(IOptionsMonitor<TOptions> options
        , ILoggerFactory logger
        , UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock) { }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        failReason = "Reason for auth fail";
        return AuthenticateResult.Fail(failReason);
    }

    protected override Task HandleChallengeAsync(AuthenticationProperties properties)
    {
        Response.StatusCode = 401;

        if (failReason != null)
        {
            Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = failReason;
        }

        return Task.CompletedTask;
    }
}
Run Code Online (Sandbox Code Playgroud)

来自文档:https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.authenticationhandler-1? view=aspnetcore-2.2

如果相关身份验证方案将身份验证交互作为其请求流的一部分进行处理,则重写此方法来处理 401 质询问题。(例如添加响应标头,或将登录页面或外部登录位置的 401 结果更改为 302。)

来源: https: //github.com/aspnet/Security/blob/master/src/Microsoft.AspNetCore.Authentication/AuthenticationHandler.cs#L201

  • 将字符串传递给 AuthenticateResult.Fail 的目的是什么?是不是没有被什么东西利用? (7认同)

Tao*_*hou 1

要更改正文或 Http 状态,您可以尝试Context.Response.

这是一个演示代码:

using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace TestIdentity
{
    public class CustomAuthenticationHandler<TOptions> : AuthenticationHandler<TOptions> where TOptions : AuthenticationSchemeOptions, new()
    {
        public CustomAuthenticationHandler(IOptionsMonitor<TOptions> options
            , ILoggerFactory logger
            , UrlEncoder encoder, ISystemClock clock) : base(options, logger, encoder, clock)
        {

        }
        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            await Context.Response.WriteAsync("This is why you can't log in");
            return AuthenticateResult.Fail("This is why you can't log in");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 当我添加 `Context.Response.WriteAsync()` 时,我收到“无法设置 StatusCode,因为响应已经开始”。此外,StatusCode 显示为 200 而不是 401。不确定上述答案和 Core 3.1 之间是否发生了变化。 (6认同)
  • 我确实想到过类似的事情,但直接写入这样的处理程序中的响应似乎不干净。这是否意味着该框架实际上没有提供实现这一目标的方法? (2认同)