繁体   English   中英

在 Asp.net 内核中根据每个请求决定是否使用授权

[英]Deciding to use Authorization or not on a per-request basis in Asp.net Core

我正在开发一个 ASP.net 核心 MVC 2.2 应用程序,目前我在我的 controller 操作上使用经典的[Authorize][AllowAnonymous]属性来决定是否可以匿名访问某个操作或需要授权。

但是,我有一个要求,即仅当 http 请求中缺少某个 header 时,某些操作才需要授权。 通常我会通过简单地实现这一点:

[HttpGet]
[AllowAnonymous]
public IActionResult SomeAction()
{
    if (!Request.Headers.ContainsKey("something"))
    {
        return RedirectToAction("SomeActionWithAuth");
    }
    ...
}

[HttpGet]
[Authorize]
public IActionResult SomeActionWithAuth()
{
    ...
}

但是,在这种特殊情况下,我对避免重定向有严格的要求,因此我不能使用这种方法。

所以我的问题是:

  • 有没有办法在请求到达 controller 之前拦截请求,并在运行时根据每个请求决定请求是否需要身份验证?
  • 如果那不可能,是否有办法在运行时决定将请求路由到哪个控制器/动作? (这样我可以有一个类似于上面的设置,有两个具有不同身份验证要求的操作,但不会在客户端引起实际的 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;
    }
}

将处理程序注册为服务

services.AddScoped<IAuthorizationHandler, HeaderRequirementHandler>();

将策略添加到授权服务

services.AddAuthorization(options =>
    {
        options.AddPolicy("SomeHeader", policy =>
            policy.Requirements.Add(new HeaderRequirement("SomeHeader")));
    });

现在你可以像这样使用它: [Authorize(Policy = "SomeHeader")]

如果你需要它更动态一点,如果你不想注册每一个 header 可能会被验证,而是在运行时解释。 您可以编写自己的策略提供程序

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM