繁体   English   中英

身份验证过滤器:如何使用消息执行HTTP 401

[英]authentication filter: How to do a HTTP 401 with message

我按照http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/进行自定义身份验证过滤器。

一切正常,但我不能让服务器在401上说什么。它正确地给出了www-authenicate标题和状态代码401但没有内容/正文。

我尝试使用来自http://www.asp.net/web-api/overview/security/authentication-filters的 AuthenticationFailureResult ,但没有帮助。 我将AuthenticateAsync转换为async并忽略了await警告。

这是我目前的工作,评论中的代码是我 - 我希望 - 我可以做的,这主要是它使用任何格式化程序

//request.CreateResponse(HttpStatusCode.Unauthorized, new { Error = true, Message = "Token is invalid" });
HttpContext.Current.Response.ContentType = "application/json";
HttpContext.Current.Response.Write("{ \"Error\" = true, \"Message\" = \"Token is invalid\" }");
context.ErrorResult = new UnauthorizedResult(new AuthenticationHeaderValue[0], request);

有两个选项可以做到这一点:快速但粗暴,更长,但更优雅

A.直接修改HttpResponse:

HttpContext.Current.Response.StatusCode = 401;
HttpContext.Current.Response.Write("some content");

B.实现IHttpActionResult并在该类中设置HttpResponseMessageContent属性:

public class AuthenticationFailureResult : IHttpActionResult
{
    public AuthenticationFailureResult(object jsonContent, HttpRequestMessage request)
    {
        JsonContent = jsonContent;
        Request = request;
    }

    public HttpRequestMessage Request { get; private set; }

    public Object JsonContent { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(Execute());
    }

    private HttpResponseMessage Execute()
    {
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        response.RequestMessage = Request;
        response.Content = new ObjectContent(JsonContent.GetType(), JsonContent, new JsonMediaTypeFormatter());
        return response;
    }
}

然后你就可以像这样使用它:

context.ErrorResult = new AuthenticationFailureResult(new { Error = true, Message = "Token is invalid" }, request);

注意:如果要对JsonContent使用匿名类型, JsonContent确保在同一个库中实现AuthenticationFailureResult

如果你想附上一条消息和401响应,我想你应该这样做。 这就是我在项目中的表现:

public class TokenAuthenticationAttribute : AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        // Do your authentication here
    }

    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        if (actionContext == null)
        {
            throw new ArgumentNullException("actionContext", "Null actionContext");
        }

        actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized);
        actionContext.Response.Headers.Add("AuthenticationStatus", "NotAuthorized");
        actionContext.Response.ReasonPhrase = "Authentication failed";

        // Create your content here (I use Student class as an example)
        actionContext.Response.Content = new ObjectContent(
            typeof (Student),
            new Student("Forte", 23),
            new JsonMediaTypeFormatter());
    }
}

学生班:

public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Student(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

然后,我像这样使用它:

[TokenAuthentication]
public class DocumentController : ApiController
{
    // Your code here
}

编辑!!!

感谢评论中的wal建议,这是将消息附加到响应的更短方式:

actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized,
                new {Error = true, Message = "Token is invalid"});

然后,您的回复消息将是:

{"$id":"1","error":true,"message":"Token is invalid"}

通过这种方式,您不必再设置actionContext.Response.Content

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM