【问题标题】:Returning a custom HTTP response code when the authentication fails for a custom basic auth provider当自定义基本身份验证提供程序的身份验证失败时返回自定义 HTTP 响应代码
【发布时间】:2023-03-19 12:04:01
【问题描述】:

我知道在使用自定义身份验证提供程序时可以返回自定义响应,如下面的代码:

从 ServiceStack 身份验证返回一个自定义的身份验证响应对象

我只是想知道是否有办法返回自定义 HTTP 响应代码。

例如,当身份验证失败时,我想发送另一个 HTTP 响应代码,而不是 401 未授权错误,以提供有关失败原因的更多详细信息。比如账号被锁定,我会发送错误码XYZ!

public class MyBasicAuthProvider : BasicAuthProvider
{
    public override object Authenticate(ServiceStack.ServiceInterface.IServiceBase authService, IAuthSession session, Auth request)
    {
        //let normal authentication happen
        var authResponse = (AuthResponse)base.Authenticate(authService, session, request);

        //return your own class, but take neccessary data from AuthResponse
        return new
            {
                UserName = authResponse.UserName,
                SessionId = authResponse.SessionId,
                ReferrerUrl = authResponse.ReferrerUrl,
                SessionExpires = DateTime.Now
            };

    }
}

在一次尝试中,我找到了一种在该函数中返回自定义 HTTP 代码的方法。我返回例如:

return new ServiceStack.HttpError(423, "Locked");

我不确定这是否正确

【问题讨论】:

  • 您可以这样做,但状态 423 用于其他情况。 401 状态适合这种情况。如果您想为您的回复提供更多信息,请创建带有正文的自定义回复。就像nordicapis.com/best-practices-api-error-handling 一样。如果您不知道该怎么做,那取决于您使用的是什么 .net 框架或 .net 核心。中间件/过滤器中的解决方案。如果您需要帮助,我可以用示例写一个答案。
  • @Che 这就是我所做的,我创建了一个自定义响应,但如果我发送 423,Servicestack 仍在发送 401 状态事件。它在某处被覆盖,我不知道它在哪里以及是否破坏了某些东西.
  • 好的,我知道了。可以调试吗?你确定你进入了'return new ServiceStack.HttpError(423, "Locked")'这行吗?
  • @Che 是的,我调试了它并正确返回。即使使用 restlet 客户端,返回码仍然是 401。

标签: c# servicestack


【解决方案1】:

BasicAuthProvider 是一个IAuthWithRequest Auth Provider,它启用HTTP Basic Auth,它在调用服务时进行身份验证,即它不使用对ServiceStack 的/auth 端点的显式请求进行身份验证。

对于失败的基本身份验证请求,您希望返回 ServiceStack 的 401 Unauthorized 状态响应和 WWW-Authenticate HTTP 标头,这是 HTTP 客户端知道提示输入凭据所必需的。

我建议不要使用不同的错误响应,但如果您真的想为 HTTP 基本身份验证请求自定义失败响应,您可以在 BasicAuthProvider 中的override OnFailedAuthentication 编写您想要的自定义错误响应:

public virtual Task OnFailedAuthentication(IAuthSession session, IRequest httpReq, IResponse httpRes)
{
    httpRes.StatusCode = (int)HttpStatusCode.Unauthorized;
    httpRes.AddHeader(HttpHeaders.WwwAuthenticate, "{0} realm=\"{1}\"".Fmt(this.Provider, this.AuthRealm));
    return HostContext.AppHost.HandleShortCircuitedErrors(httpReq, httpRes, httpReq.Dto);
}

【讨论】:

    猜你喜欢
    • 2020-02-17
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 2016-09-24
    • 2015-11-12
    • 1970-01-01
    相关资源
    最近更新 更多