C# 在Asp.net Core中根据每个请求决定是否使用授权
我正在开发一个ASP.net core MVC 2.2应用程序,目前我正在控制器操作上使用经典的[Authorize]和[AllowAnonymous]属性来决定某个操作是可以匿名访问还是需要授权 但是,我有一个要求,只有当http请求中缺少某个标头时,某些操作才需要授权。通常情况下,我会通过以下方式实现:C# 在Asp.net Core中根据每个请求决定是否使用授权,c#,asp.net-core,asp.net-core-mvc,asp.net-core-2.0,C#,Asp.net Core,Asp.net Core Mvc,Asp.net Core 2.0,我正在开发一个ASP.net core MVC 2.2应用程序,目前我正在控制器操作上使用经典的[Authorize]和[AllowAnonymous]属性来决定某个操作是可以匿名访问还是需要授权 但是,我有一个要求,只有当http请求中缺少某个标头时,某些操作才需要授权。通常情况下,我会通过以下方式实现: [HttpGet] [AllowAnonymous] public IActionResult SomeAction() { if (!Request.Headers.Contain
[HttpGet]
[AllowAnonymous]
public IActionResult SomeAction()
{
if (!Request.Headers.ContainsKey("something"))
{
return RedirectToAction("SomeActionWithAuth");
}
...
}
[HttpGet]
[Authorize]
public IActionResult SomeActionWithAuth()
{
...
}
然而,在这种特殊情况下,我有一个避免重定向的严格要求,所以我不能使用这种方法
所以我的问题是:
是否有办法在请求到达控制器之前拦截请求,并在运行时根据每个请求决定请求是否需要身份验证?
如果不可能,是否有一种方法可以在运行时决定将请求路由到哪个控制器/操作?这样,我就可以有一个与上面类似的设置,有两个具有不同身份验证要求的操作,但不会在客户端导致实际的HTTP重定向,这是我无法做到的
创建您自己的授权策略来处理此问题
public class HeaderRequirement : IAuthorizationRequirement
{
public HeaderRequirement(string header)
{
Header = header;
}
public string Header { get; }
}
public class HeaderRequirementHandler : AuthorizationHandler<HeaderRequirement>
{
protected override Task HeaderRequirementHandler (
AuthorizationHandlerContext context,
HeaderRequirement requirement)
{
var hasHeader = context.Request.Headers.ContainsKey(requirement.Header);
if (hasHeader) // if we have the header
{
context.Succeed(requirement); // authorization successful
}
return Task.CompletedTask;
}
}
现在可以这样使用:[AuthorizePolicy=SomeHeader]
如果您需要更动态一点,如果您不想注册每个可能经过身份验证但在运行时进行解释的头文件。您可以编写您自己的您只需编写您自己的授权筛选器,以替换授权/允许匿名筛选器。编写过滤器非常重要。谢谢你的回答。我的问题是:如果我不调用context.success,这种方法会像标准的授权过滤器一样工作吗?因为如果找不到所需的头,我需要它返回默认[Authorize]属性的标准行为,在我的情况下,该属性执行NTLM/Windows身份验证。@Master\t我不能确定,因为这在很大程度上取决于您如何配置授权。我刚刚测试了它。。。它起作用了!有点。如果我返回而不调用context.successful在我的情况下执行默认授权行为:执行NTLM auth浏览器接收标准NTLM auth质询。身份验证通过后,将再次调用HeaderRequirementHandler。这本身会导致无限循环,但由于第二次对用户进行身份验证时,如果我找不到要查找的头,我会直接检查context.user对象以查看用户是否经过身份验证,并直接在那里执行权限检查逻辑。谢谢
services.AddAuthorization(options =>
{
options.AddPolicy("SomeHeader", policy =>
policy.Requirements.Add(new HeaderRequirement("SomeHeader")));
});