简体   繁体   English

使用Web API控制器中的身份验证过滤器发送JSON响应?

[英]Sending json response using Authentication filter in Web api controller?

I have an authentication filter in my controller 我的控制器中有一个身份验证过滤器

[ArcGISAuthentication]

I have defined the filter like below 我已经定义了如下的过滤器

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()
    {

    }
}

The problem is I want to send a json repsonse when the authentication fail. 问题是我想在身份验证失败时发送json回复。 As in the else statement in the AuthenticateAsync above. 就像上面AuthenticateAsync中的else语句一样。

How can I do this? 我怎样才能做到这一点?

Create a custom error result 创建自定义错误结果

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;
    }
}

and set it to the context.Error property 并将其设置为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");
}

In the Execute of the result you can set the response message to JSON or let the content negotiator determine what media type to return based on request headers. 在结果的Execute中,您可以将响应消息设置为JSON,或者让内容协商程序根据请求标头确定要返回的媒体类型。

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

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