在Web api控制器中使用身份验证过滤器发送json响应?

时间:2017-02-06 18:26:27

标签: c# asp.net asp.net-web-api owin http-token-authentication

我的控制器中有一个身份验证过滤器

[ArcGISAuthentication]

我已经定义了如下所示的过滤器

public class ArcGISAuthenticationAttribute : Attribute, IAuthenticationFilter
{
    public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        return Task.Run(async () =>
        {
            var queryParameters = HttpUtility.ParseQueryString(context.Request.RequestUri.Query);
            var token = queryParameters["token"];
            if (!string.IsNullOrWhiteSpace(token))
            {
                var userInfo = await CommunityManager.GetUserInfoAsync(token);
                context.Principal = new ArcGISUserPrincipal(userInfo, token);
                context.Request.SetUserPrincipal(context.Principal);
            }
            else{
                //What shoudld I do here to send a json response
            }
        });
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
        return Task.Run(() => { });
    }

    public ArcGISAuthenticationAttribute()
    {

    }
}

问题是我想在身份验证失败时发送json repsonse。与上面的AuthenticateAsync中的else语句一样。

我该怎么做?

1 个答案:

答案 0 :(得分:3)

创建自定义错误结果

public class ErrorResult : IHttpActionResult {
    public ErrorResult(HttpRequestMessage request, string message, HttpStatusCode status = HttpStatusCode.InternalServerError, string reasonPhrase = "Internal Server Error") {
        ReasonPhrase = reasonPhrase;
        Request = request;
        Message = message;
        Status = status;
    }

    public HttpStatusCode Status { get; private set; }

    public string ReasonPhrase { get; private set; }

    public string Message { get; private set; }

    public HttpRequestMessage Request { get; private set; }

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

    private HttpResponseMessage Execute() {
        var status = Status;
        var responseBody = new Models.envelope {
            meta = new Models.metadata {
                code = (int)status,
                type = ReasonPhrase ?? status.ToString().ToCamelCase(),
                message = Message
            },
            data = null
        };
        var response = Request.CreateResponse(status, responseBody);
        response.RequestMessage = Request;
        response.ReasonPhrase = ReasonPhrase;
        return response;
    }
}

并将其设置为context.Error属性

if (!string.IsNullOrWhiteSpace(token))
{
    var userInfo = await CommunityManager.GetUserInfoAsync(token);
    context.Principal = new ArcGISUserPrincipal(userInfo, token);
    context.Request.SetUserPrincipal(context.Principal);
}
else
{
    context.Error = new ErrorResult(context.Request, "Some message to return");
}

在结果的Execute中,您可以将响应消息设置为JSON,或让内容协商者根据请求标头确定要返回的媒体类型。