Reputation: 646
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?
Upvotes: 2
Views: 1908
Reputation: 247088
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.
Upvotes: 3