ASP.NET 5 未调用基于策略的授权句柄
ASP.NET 5 Policy-Based Authorization Handle Not Being Called
按照此处的文档,我尝试实施基于策略的身份验证方案。 http://docs.asp.net/en/latest/security/authorization/policies.html#security-authorization-handler-example
我 运行 解决了我的自定义 AuthorizationHandler 上未调用我的 Handle 方法的问题。 (这里不抛)。它还会在构造函数中注入当前的依赖项。
这里是 AuthorizationHandler 代码。
using WebAPIApplication.Services;
using Microsoft.AspNet.Authorization;
namespace WebAPIApplication.Auth
{
public class TokenAuthHandler : AuthorizationHandler<TokenRequirement>, IAuthorizationRequirement
{
private IAuthService _authService;
public TokenAuthHandler(IAuthService authService)
{
_authService = authService;
}
protected override void Handle(AuthorizationContext context, TokenRequirement requirement)
{
throw new Exception("Handle Reached");
}
}
public class TokenRequirement : IAuthorizationRequirement
{
public TokenRequirement()
{
}
}
}
在启动中我有
// Authorization
services.AddSingleton<IAuthorizationHandler, TokenAuthHandler>()
.AddAuthorization(options =>
{
options.AddPolicy("ValidToken",
policy => policy.Requirements.Add(new TokenRequirement()));
});
控制器方法是
// GET: api/values
[HttpGet, Authorize(Policy="ValidToken")]
public string Get()
{
return "test";
}
没有命中此端点 returns 并且在
的控制台中出现警告
warn: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[0]
Authorization failed for the request at filter 'Microsoft.AspNet.Mvc.Filters.AuthorizeFilter'.
我能够成功命中其他没有该属性的端点。
紧急求救,
杰克
看看 我认为添加 options.AutomaticChallenge = true;
可以解决您的问题。
adem caglin 的评论中提到了这个问题的答案,所以支持他。
问题是 AuthorizeFilter
在调用 AuthorizationHandler
之前拒绝请求。这是因为每次使用 Authorize
标记时,MVC 都会在管道中的 AuthorizationHandler
之前添加 AuthorizeFilter
。此 AuthorizeFilter
检查是否有任何当前用户身份已获得授权。在我的例子中,没有与任何用户关联的授权身份,所以这总是会失败。
一个解决方案(IMO 有点 hackish)是插入一个中间件,它将在任何 MVC 代码之前执行。该中间件将为用户添加一个通用的经过身份验证的身份(如果用户还没有)。
因此AuthorizeFilter
检查将通过,AuthenticationHandler
方法上的Handle
方法将被执行,我们的问题将得到解决。中间件代码(在调用app.UseMvc();
之前需要在Configure
中添加)如下
app.Use(async (context, next) =>
{
if (!context.User.Identities.Any(i => i.IsAuthenticated))
{
context.User = new ClaimsPrincipal(new GenericIdentity("Unknown"));
}
await next.Invoke();
});
覆盖 AuthorizeFilter
的另一种方法在此处概述 ()
引用此处的回复 ()
我把它放在这里以供参考,因为我花了太长时间才弄明白...
我已经实现了自定义要求和处理程序(为了测试而留空):
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
public class TestHandler : AuthorizationHandler<TestRequirement>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TestRequirement requirement)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}
public class TestRequirement : IAuthorizationRequirement
{
}
在我的 Startup.cs
ConfigureServices()
部分注册:
services.AddAuthorization(options =>
{
options.AddPolicy("Test", policy => policy.Requirements.Add(new TestRequirement()));
// Other policies here
}
将其添加到我的控制器方法中:
[HttpGet]
[Authorize(Policy = "Test")]
public IActionResult Index()
{
Return View();
}
但是每次向控制器方法发出请求时都会收到 403 错误(不是 401)!
事实证明,我没有在 Startup.cs
的 ConfigureServices()
(依赖注入)部分注册 TestHandler
。
services.AddSingleton<IAuthorizationHandler, TestHandler>();
希望这可以避免有人用头撞桌子。 :|
按照此处的文档,我尝试实施基于策略的身份验证方案。 http://docs.asp.net/en/latest/security/authorization/policies.html#security-authorization-handler-example
我 运行 解决了我的自定义 AuthorizationHandler 上未调用我的 Handle 方法的问题。 (这里不抛)。它还会在构造函数中注入当前的依赖项。
这里是 AuthorizationHandler 代码。
using WebAPIApplication.Services;
using Microsoft.AspNet.Authorization;
namespace WebAPIApplication.Auth
{
public class TokenAuthHandler : AuthorizationHandler<TokenRequirement>, IAuthorizationRequirement
{
private IAuthService _authService;
public TokenAuthHandler(IAuthService authService)
{
_authService = authService;
}
protected override void Handle(AuthorizationContext context, TokenRequirement requirement)
{
throw new Exception("Handle Reached");
}
}
public class TokenRequirement : IAuthorizationRequirement
{
public TokenRequirement()
{
}
}
}
在启动中我有
// Authorization
services.AddSingleton<IAuthorizationHandler, TokenAuthHandler>()
.AddAuthorization(options =>
{
options.AddPolicy("ValidToken",
policy => policy.Requirements.Add(new TokenRequirement()));
});
控制器方法是
// GET: api/values
[HttpGet, Authorize(Policy="ValidToken")]
public string Get()
{
return "test";
}
没有命中此端点 returns 并且在
的控制台中出现警告warn: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[0]
Authorization failed for the request at filter 'Microsoft.AspNet.Mvc.Filters.AuthorizeFilter'.
我能够成功命中其他没有该属性的端点。
紧急求救, 杰克
看看 options.AutomaticChallenge = true;
可以解决您的问题。
adem caglin 的评论中提到了这个问题的答案,所以支持他。
问题是 AuthorizeFilter
在调用 AuthorizationHandler
之前拒绝请求。这是因为每次使用 Authorize
标记时,MVC 都会在管道中的 AuthorizationHandler
之前添加 AuthorizeFilter
。此 AuthorizeFilter
检查是否有任何当前用户身份已获得授权。在我的例子中,没有与任何用户关联的授权身份,所以这总是会失败。
一个解决方案(IMO 有点 hackish)是插入一个中间件,它将在任何 MVC 代码之前执行。该中间件将为用户添加一个通用的经过身份验证的身份(如果用户还没有)。
因此AuthorizeFilter
检查将通过,AuthenticationHandler
方法上的Handle
方法将被执行,我们的问题将得到解决。中间件代码(在调用app.UseMvc();
之前需要在Configure
中添加)如下
app.Use(async (context, next) =>
{
if (!context.User.Identities.Any(i => i.IsAuthenticated))
{
context.User = new ClaimsPrincipal(new GenericIdentity("Unknown"));
}
await next.Invoke();
});
覆盖 AuthorizeFilter
的另一种方法在此处概述 (
引用此处的回复 (
我把它放在这里以供参考,因为我花了太长时间才弄明白...
我已经实现了自定义要求和处理程序(为了测试而留空):
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
public class TestHandler : AuthorizationHandler<TestRequirement>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, TestRequirement requirement)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
}
public class TestRequirement : IAuthorizationRequirement
{
}
在我的 Startup.cs
ConfigureServices()
部分注册:
services.AddAuthorization(options =>
{
options.AddPolicy("Test", policy => policy.Requirements.Add(new TestRequirement()));
// Other policies here
}
将其添加到我的控制器方法中:
[HttpGet]
[Authorize(Policy = "Test")]
public IActionResult Index()
{
Return View();
}
但是每次向控制器方法发出请求时都会收到 403 错误(不是 401)!
事实证明,我没有在 Startup.cs
的 ConfigureServices()
(依赖注入)部分注册 TestHandler
。
services.AddSingleton<IAuthorizationHandler, TestHandler>();
希望这可以避免有人用头撞桌子。 :|