.NET Core 覆盖特定操作的控制器级别授权属性

Exo*_*omp 4 .net-core asp.net-core-2.0

这是一个示例控制器来解释这种情况

[Authorize]
public class AccountController : ControllerBase
{
    [AllowAnonymous]
    [Authorize(Policy = "SpecificPolicy")]
    public string MethodA() {}

    public string MethodB() {}
}
Run Code Online (Sandbox Code Playgroud)
  • MethodA 只能通过“SpecificPolicy”进行授权。
  • MethodB 应该通过 Authorized 属性授权

我遇到的问题是,如果我删除 AllowAnonymous 属性,则控制器上的 Authorize 优先,我不希望 MethodA。

当我为 MethodA 保留 AllowAnonymous 时,将忽略 Authorize(Policy = "SpecificPolicy") 。

Dav*_*ang 5

当我为 MethodA 保留 AllowAnonymous 时,将忽略 Authorize(Policy = "SpecificPolicy") 。

[AllowAnonymous]绕过所有其他授权属性。当您同时拥有其他授权属性时,所有其他属性都将被忽略,甚至其他属性是更具体的方法级别。

例如:

[AllowAnonymous]
public class DashboardController : Controller
{
    [Authorize]
    public IActionResult Index()
    {
        return View();
    }
}
Run Code Online (Sandbox Code Playgroud)

/dashboard 将开放/公开。

我遇到的问题是,如果我删除 AllowAnonymous 属性,则控制器上的 Authorize 优先,我不希望 MethodA。

当您有多个授权属性时,在调用该方法之前需要满足所有这些属性。在您的情况下,在授予访问权限之前[Authorize][Authorize(Policy = "SpecificPolicy")]必须通过和。

如果不想[Authorize]优先,则只能将其应用于方法B:

public class AccountController : ControllerBase
{
    [Authorize(Policy = "SpecificPolicy")]
    public string MethodA() {}

    [Authorize]
    public string MethodB() {}
}
Run Code Online (Sandbox Code Playgroud)

我想避免将特定的 [Authorize] 属性放在动作上,因为该控制器有很多动作,但只有一个动作有自己的授权规则。

那么这可能是您将 MethodA 分成Areas 的好时机。

例如:

你仍然有[Authorize]你的AccountController,但只需取出 MethodA:

[Authorize]
public class AccountController : ControllerBase
{
    public string MethodB() {}
}
Run Code Online (Sandbox Code Playgroud)

然后为 MethodA 创建一个区域:

[Area("specific")]
[Authorize(Policy = "SpecificPolicy")]
public abstract class SpecificControllerBase : ControllerBase
{ }

public class AccountController : SpecificationControllerBase
{
    public string MethodA() {}
}
Run Code Online (Sandbox Code Playgroud)

最后,您需要在您的Startup.cs.

app.UseMvc(routes =>
{
    ...

    routes.MapRoute(
        name: "areaRoute",
        template: "{area:exists}/{controller=dashboard}/{action=index}/{id?}");

    routes.MapRoute(
        name: "default",
        template: "{controller=home}/{action=index}/{id?}");
});
Run Code Online (Sandbox Code Playgroud)