I have an almost working implementation of OAuth2 in asp.net 5 (RC1). My solution is based upon the code given by Mark Hughes in Token Based Authentication in ASP.NET 5 (vNext), which is brilliant.
My problem is that my setup is using CORS requests and almost every request is preceded by an OPTIONS request. Even though I only apply the Authorize attribute to the GetAll controller action/method, as shown below, the preceding OPTIONS request is authorized as well.
[Route("api/[controller]")]
public class TextController : Controller
{
[HttpGet]
[Authorize("Bearer", Roles = "admin")]
public IEnumerable<string> GetAll()
{
return _repository.GetAll;
}
...
}
The authorization service setup in startup.cs looks like this:
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
Is ther any way I can change the behavior of the authorization middleware to skip authorization of OPTIONS requests?
Note:
I have tried creating my own authorization attribute, but for some reason IsAuthenticated always evaluates to false, as if the authorization has not happened yet when reaching this code:
public class BearerAuthorizationAttribute : Attribute, IAuthorizationFilter
{
private readonly string Role;
public BearerAuthorizationAttribute(string Role = null)
{
this.Role = Role;
}
[Authorize("Bearer")]
public void OnAuthorization(Microsoft.AspNet.Mvc.Filters.AuthorizationContext context)
{
string meth = context.HttpContext.Request.Method;
if (meth != "OPTIONS")
{
if (!context.HttpContext.User.Identity.IsAuthenticated)
{
context.Result = new ContentResult() { Content = "Unauthorized", StatusCode = 401 };
return;
}
if (Role != null && !context.HttpContext.User.IsInRole(Role))
{
context.Result = new ContentResult() { Content = "Unauthorized, role level insufficient", StatusCode = 401 };
return;
}
}
}
}