This question is related to the answer I have provided here. OP's comment got me thinking a bit. I suggested using a class implementing IHttpActionResult
like this in the ChallengeAsync
method of the authentication filter.
public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
CancellationToken cancellationToken)
{
context.Result = new ResultWithChallenge(context.Result);
return Task.FromResult(0);
}
public class ResultWithChallenge : IHttpActionResult
{
private readonly IHttpActionResult next;
public ResultWithChallenge(IHttpActionResult next)
{
this.next = next;
}
public async Task<HttpResponseMessage> ExecuteAsync(
CancellationToken cancellationToken)
{
var response = await next.ExecuteAsync(cancellationToken);
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
response.Headers.WwwAuthenticate.Add(
new AuthenticationHeaderValue("Basic", "realm=localhost"));
}
return response;
}
}
Instead of this, I can simplify the ChallengeAsync
like this.
public Task ChallengeAsync(HttpAuthenticationChallengeContext context,
CancellationToken cancellationToken)
{
var result = await context.Result.ExecuteAsync(cancellationToken);
if (result.StatusCode == HttpStatusCode.Unauthorized)
{
result.Headers.WwwAuthenticate.Add(
new AuthenticationHeaderValue("Basic", "realm=localhost"));
}
context.Result = new ResponseMessageResult(result);
}
This saves me from creating a class implementing IHttpActionResult
but is this the right way? I get an uneasy feeling that this is somehow bad from a performance standpoint because it feels like I'm converting action result to HttpResponseMessage and back to action result. Any pointers on the need for a separate class here implementing IHttpActionResult
like what I suggested will be appreciated as against using the code above.
To apply an authentication filter to a controller, decorate the controller class with the filter attribute. The following code sets the [IdentityBasicAuthentication] filter on a controller class, which enables Basic Authentication for all of the controller's actions.
To create a custom authentication filter in ASP.NET MVC, we need to create a class by implementing the IAuthenticationFilter Interface. This IAuthenticationFilter interface has 2 methods.
Web API provides a built-in authorization filter, AuthorizeAttribute. This filter checks whether the user is authenticated. If not, it returns HTTP status code 401 (Unauthorized), without invoking the action. You can apply the filter globally, at the controller level, or at the level of individual actions.
The authentication and authorization mechanism in such a site is simple. After the user logs into the website, a single database holding user information verifies their identity. A session is created on the server, and all subsequent requests use the session to identify the user without another login required.
The intent was to use the first approach rather than the second. For example, see the Basic Authentication sample (also available for MVC), which follows the first approach: http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/BasicAuthentication/ReadMe.txt
The second approach mostly works. I wouldn't be too concerned about the performance standpoint; either way you're allocating one action result object and one response message object, so I'm not seeing much difference there.
However, there are a couple of reasons I'd recommend the first approach:
The framework definitely could make it easier to implement the interface; feel free to vote on this work item: https://aspnetwebstack.codeplex.com/workitem/1456
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With