.net core 特定操作的.NET Core重写控制器级别授权属性
下面是一个示例控制器来解释这个案例.net core 特定操作的.NET Core重写控制器级别授权属性,.net-core,asp.net-core-2.0,.net Core,Asp.net Core 2.0,下面是一个示例控制器来解释这个案例 [Authorize] public class AccountController : ControllerBase { [AllowAnonymous] [Authorize(Policy = "SpecificPolicy")] public string MethodA() {} public string MethodB() {} } MethodA只能通过“SpecificPolicy”授权 MethodB应该
[Authorize]
public class AccountController : ControllerBase
{
[AllowAnonymous]
[Authorize(Policy = "SpecificPolicy")]
public string MethodA() {}
public string MethodB() {}
}
- MethodA只能通过“SpecificPolicy”授权
- MethodB应该通过authorized属性进行授权
[AllowAnonymous]
绕过所有其他授权属性。当它与其他authorize属性同时使用时,所有其他属性都被忽略,甚至其他属性都是更具体的方法级别
例如:
[AllowAnonymous]
公共类仪表板控制器:控制器
{
[授权]
公共IActionResult索引()
{
返回视图();
}
}
/dashboard
将打开/公开
我遇到的问题是,如果我删除AllowAnonymous属性,那么控制器上的Authorize将优先于MethodA,这是我不希望看到的
当您有多个authorize属性时,需要满足所有这些属性,然后才能调用该方法。在您的情况下,必须先通过[Authorize]
和[Authorize(Policy=“SpecificPolicy”)]
才能授予访问权限
如果您不希望[Authorize]
优先,则只能将其应用于方法B:
公共类AccountController:ControllerBase
{
[授权(Policy=“SpecificPolicy”)]
公共字符串MethodA(){}
[授权]
公共字符串MethodB(){}
}
我希望避免在操作上放置特定的[Authorize]属性,因为该控制器有很多操作,但只有一个操作有自己的授权规则
那么这可能是将MethodA划分为区域的好时机
例如:
您的账户控制器上仍有[Authorize]
,但只需取出方法A:
[授权]
公共类AccountController:ControllerBase
{
公共字符串MethodB(){}
}
然后为MethodA创建一个区域:
[区域(“特定”)]
[授权(Policy=“SpecificPolicy”)]
公共抽象类特定ControllerBase:ControllerBase
{ }
公共类AccountController:SpecificationControllerBase
{
公共字符串MethodA(){}
}
最后,您需要在Startup.cs
中注册区域路由:
app.UseMvc(路由=>
{
...
routes.MapRoute(
名称:“区域路线”,
模板:“{area:exists}/{controller=dashboard}/{action=index}/{id?}”);
routes.MapRoute(
名称:“默认”,
模板:“{controller=home}/{action=index}/{id?}”);
});
通过检查策略,您可以尝试实现自己的授权属性
请遵循以下步骤:
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();
}
您的回答很有道理,我希望避免在操作上添加特定的[Authorize]属性,因为该控制器有很多操作,但只有一个操作有自己的授权规则。所以我认为,如果不能在一个控制器中完成,更好的方法是将单个方法移动到它自己的控制器中。@Exocomp:我理解。当你的情况发生时,我只是对自己说:“嗯,也许我应该在一个同名的控制器下为这个方法创建一个区域。”。在区域的帮助下,您可以将特定的授权策略放在那里。它的URL在我看来也更正式。i、 例如,/dashboard
vs/admin/dashboard
vs/vendor/dashboard
。我没有想到使用区域。请你在回答中举例说明。@Exocomp:请看我的更新。同样,有很多方法可以实现你的目标。使用一个区域只是我的想法。其他人可能有更好的解决方案。我只是在这个例子中虚构了一些东西。您还可以在抽象基类或控制器上应用policy属性。但是我认为在基类上这样做更有意义。这非常有用,但是这个例子有一个小问题。如果策略处理程序需要AuthorizationFilterContext,则需要将其传递给AuthorizationAsync方法。这个方法有很多重写,这里使用的方法将上下文默认为null。