我有一个用AuthorizeAttribute修饰的控制器。除了一个需要CustomAuthorizeAttribute提供的自定义身份验证的操作外,控制器还包含几个需要身份验证的操作。
我的问题是,一旦我在控制器级别添加[授权],我可以使用[CustomAuthorize]仅在一个操作上覆盖它(或删除它)吗?或者我是否必须从控制器级别删除[授权]并将其单独添加到其他所有操作中?
我纯粹是为了方便,因为我很懒,不想用AuthorizeAttribute来装饰每个动作。
[Authorize]
public class MyController : Controller {
//requires authentication
public ViewResult Admin() {
return View();
}
//... a lot more actions requiring authentication
//requires custom authentication
[CustomAuthorize] //never invoked as already failed at controller level
public ViewResult Home() {
return View();
}
}
答案 0 :(得分:95)
在MVC 5 中,您可以使用新属性OverrideAuthorization覆盖任何操作的授权。基本上,您将其添加到具有与控制器中定义的授权配置不同的授权配置的操作。
你这样做:
[OverrideAuthorization]
[Authorize(Roles = "Employee")]
public ActionResult List() { ... }
http://www.c-sharpcorner.com/UploadFile/ff2f08/filter-overrides-in-Asp-Net-mvc-5/
的更多信息在ASP.NET Core 2.1 中没有OverrideAuthorization属性,您唯一能做的就是匿名操作,即使控制器没有。有关更多信息,请访问https://docs.microsoft.com/en-us/aspnet/core/security/authorization/roles?view=aspnetcore-2.1
一种选择是这样做:
[Authorize(Roles = "Admin,Employee")] // admin or employee
public class XController : Controller
{
[Authorize(Roles = "Admin")] // only admin
public ActionResult ActionX() { ... }
[AllowAnonymous] // anyone
public ActionResult ActionX() { ... }
}
答案 1 :(得分:23)
您可以更改运行属性的顺序(使用Order属性),但我相信在这种情况下,除非生成立即生效的结果,否则它们仍会运行。关键是在最高级别(类)应用限制性最小的属性,并对方法进行更严格的限制。例如,如果您希望Home
操作可公开,则需要从类中删除Authorize属性,并将其应用于其他每种方法。
如果动作具有相同的容许度,但结果不同,则更改顺序可能就足够了。例如,您通常会重定向到Logon
操作,但对于Home
,您要重定向到About
操作。在这种情况下,案例提供了类属性Order=2
和Home
操作属性Order=1
。
答案 2 :(得分:12)
经过太多时间,我想出了一个解决方案。您需要使用自定义AuthorizeAttribute来装饰控制器。
public class OverridableAuthorize : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var action = filterContext.ActionDescriptor;
if(action.IsDefined(typeof(IgnoreAuthorization), true)) return;
var controller = action.ControllerDescriptor;
if(controller.IsDefined(typeof(IgnoreAuthorization), true)) return;
base.OnAuthorization(filterContext);
}
}
哪个可与动作
上的AllowAnonymous
配对
[AllowAnonymous]
答案 3 :(得分:0)
您需要覆盖控制器中的 [Authorize] ,特定操作是添加
[AllowAnonymous]
对您不希望被授权的操作(然后根据需要添加自定义属性)。
查看评论/智慧:
表示一个属性,该属性标记控制器和操作以跳过 授权过程中的System.Web.Mvc.AuthorizeAttribute。
答案 4 :(得分:0)
在处理原型和生产环境时覆盖所有控制器。
这样就不需要去除每个控制器的授权了。
app.UseEndpoints(endpoint =>
{
endpoint.MapControllers().WithMetadata(new AllowAnonymousAttribute());
});