2

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. As in the else statement in the AuthenticateAsync above.

How can I do this?

1
  • Create a custom error result and set it to the context.Error property. In 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 Commented Feb 6, 2017 at 18:45

1 Answer 1

3

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

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.