2

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

[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 响应。就像上面 AuthenticateAsync 中的 else 语句一样。

我怎样才能做到这一点?

4

1 回答 1

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,或者让内容协商器根据请求标头确定要返回的媒体类型。

于 2017-02-06T18:46:07.443 回答