我在asp.net 5(RC1)中有一个几乎可以实现的OAuth2。我的解决方案是基于Mark Hughes在Token Based Authentication in ASP.NET 5 (vNext)中给出的代码,这很精彩。
我的问题是我的设置正在使用CORS请求,几乎每个请求前面都有一个OPTIONS请求。即使我只将Authorize属性应用于GetAll控制器操作/方法,如下所示,前面的OPTIONS请求也被授权。
[Route("api/[controller]")]
public class TextController : Controller
{
[HttpGet]
[Authorize("Bearer", Roles = "admin")]
public IEnumerable<string> GetAll()
{
return _repository.GetAll;
}
...
}
startup.cs中的授权服务设置如下所示:
services.AddAuthorization(auth =>
{
auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
我是否可以通过任何方式更改授权中间件的行为以跳过OPTIONS请求的授权?
注意:
我已尝试创建自己的授权属性,但由于某种原因,IsAuthenticated始终评估为false,就好像授权在到达此代码时尚未发生一样:
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;
}
}
}
}
答案 0 :(得分:1)
我终于想出了如何解决我的问题。在我的Startup.cs中,我使用services.AddCors
,如下所示:
// Create CORS policies
services.AddCors(options =>
{
// Define one or more CORS policies
options.AddPolicy("AllowSpecificOrigin",
builder =>
{
builder.WithOrigins(Configuration.Get<string[]>("AppSettings:AllowedOrigins")) // TODO: revisit and check if this can be more strict and still allow preflight OPTION requests
.AllowAnyMethod()
.AllowAnyHeader();
}
);
});
// Apply CORS policy globally
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory("AllowSpecificOrigin"));
});
事实证明,这只能部分发挥作用。
对我来说 解决方案的目的是代替app.UseCors
,即删除上面的代码并执行此操作:
app.UseCors(builder =>
{
builder.WithOrigins(Configuration.Get<string[]>("AppSettings:AllowedOrigins")) // TODO: revisit and check if this can be more strict and still allow preflight OPTION requests
.AllowAnyMethod()
.AllowAnyHeader();
});
使用app.UseCors
时,我会完全使用CORS处理,在获得授权之前将OPTIONS请求退回。
该解决方案的灵感来自CORS is not working in web api with OWIN authentication。