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

时间:2018-10-09 21:19:55

标签: .net-core asp.net-core-2.0

这是一个解释此情况的示例控制器

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

    public string MethodB() {}
}
  • 方法A仅应通过“ SpecificPolicy”进行授权。
  • 方法B应通过“授权”属性进行授权

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

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

2 个答案:

答案 0 :(得分:1)

  

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

[AllowAnonymous]绕过所有其他授权属性。当您同时将其与其他授权属性一起使用时,所有其他属性都会被忽略,甚至其他属性也是更特定的方法级别。

例如:

[AllowAnonymous]
public class DashboardController : Controller
{
    [Authorize]
    public IActionResult Index()
    {
        return View();
    }
}

/dashboard将公开/公开。

  

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

当您具有多个授权属性时,必须满足所有条件,然后才能调用该方法。对于您来说,[Authorize][Authorize(Policy = "SpecificPolicy")]都必须先通过,然后才能授予访问权限。

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

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

    [Authorize]
    public string MethodB() {}
}
  

我想避免在操作上放置特定的[Authorize]属性,因为该Controller有很多操作,但是一个具有自己的授权规则的操作。

那么这可能是您将MethodA划分为区域的好时机。

例如:

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

[Authorize]
public class AccountController : ControllerBase
{
    public string MethodB() {}
}

然后为MethodA创建一个区域:

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

public class AccountController : SpecificationControllerBase
{
    public string MethodA() {}
}

最后,您需要在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?}");
});

答案 1 :(得分:1)

您可以尝试通过检查政策来实施自己的Authorize Attribute

请按照以下步骤操作:

  • AllowAnonymousWithPolicyFilter

    public class AllowAnonymousWithPolicyFilter : IAsyncAuthorizationFilter
    {
    private readonly IAuthorizationService _authorization;
    public string Policy { get; private set; }
    
    public AllowAnonymousWithPolicyFilter(string policy, IAuthorizationService authorization)
    {
        Policy = policy;
        _authorization = authorization;
    }
    
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, Policy);
        if (!authorized.Succeeded)
        {
            context.Result = new ForbidResult();
            return;
        }
    }
    }
    
  • AllowAnonymousWithPolicyAttribute

    public class AllowAnonymousWithPolicyAttribute : TypeFilterAttribute, IAllowAnonymous
    {
    public AllowAnonymousWithPolicyAttribute(string Policy) : base(typeof(AllowAnonymousWithPolicyFilter))
    {
        Arguments = new object[] { Policy };
    }
    }
    
  • 使用

    [Authorize]
     public class HomeController : Controller
    {
    [AllowAnonymousWithPolicy("MyPolicy")]
    public IActionResult About()
    {
        ViewData["Message"] = "Your application description page.";
    
        return View();
    }