按照这里的文档,我尝试实现基于策略的身份验证方案。 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()
{
}
}
}
在Start Up中我有
// 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";
}
点击此端点不返回任何内容,并且
控制台中有警告warn: Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker[0]
Authorization failed for the request at filter 'Microsoft.AspNet.Mvc.Filters.AuthorizeFilter'.
我能够点击其他没有成功拥有该属性的端点。
SOS, 千斤顶
答案 0 :(得分:10)
我把它放在这里供参考,因为我花了太长时间搞清楚这一点...
我已经实现了自定义要求和处理程序(为测试而空了):
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)!
事实证明,我没有在TestHandler
的{{1}}(依赖注入)部分注册ConfigureServices()
。
Startup.cs
希望这可以避免某人在他们的桌子上敲头。 :|
答案 1 :(得分:3)
对阿德姆卡格林的评论中提到了这个问题的答案,这对他来说是道具。
问题是AuthorizeFilter
在调用AuthorizationHandler
之前拒绝了请求。这是因为对于Authorize
标记的每次使用,MVC都会在管道中的AuthorizeFilter
之前添加AuthorizationHandler
。此AuthorizeFilter
检查是否已授权任何当前用户身份。在我的情况下,没有与任何用户关联的授权身份,因此这总是会失败。
一个解决方案(IMO有点hackish)是插入一个中间件,它将在任何MVC代码之前执行。此中间件将向用户添加通用身份验证身份(如果用户尚未拥有)。
因此,AuthorizeFilter
检查将通过,Handle
方法上的AuthenticationHandler
方法将被执行,我们的问题将得到解决。中间件代码(需要在调用Configure
之前添加到app.UseMvc();
)如下所示
app.Use(async (context, next) =>
{
if (!context.User.Identities.Any(i => i.IsAuthenticated))
{
context.User = new ClaimsPrincipal(new GenericIdentity("Unknown"));
}
await next.Invoke();
});
覆盖AuthorizeFilter
的另一种方法是此处概述(Override global authorize filter in ASP.NET Core MVC 1.0)
引用此处的回复(Asp.Net Core policy based authorization ends with 401 Unauthorized)
答案 2 :(得分:1)
看看Asp.net Core Authorize Redirection Not Happening我认为添加options.AutomaticChallenge = true;
可以解决您的问题。