【问题标题】:ASP MVC Authorize all actions except a fewASP MVC 授权除少数之外的所有操作
【发布时间】:2010-10-21 07:03:51
【问题描述】:

我有一个控制器,我希望默认情况下对所有操作都要求授权,除了一对。因此,在下面的示例中,除索引外,所有操作都应需要身份验证。我不想用 Authorize 来装饰每个操作,我只想在某些情况下使用自定义过滤器(例如 NotAuthorize)覆盖默认授权。

[Authorize]
public class HomeController : BaseController
{
    [NotAuthorize]
    public ActionResult Index()
    {
        // This one wont
        return View();
    }

    public ActionResult About()
    {
        // This action will require authorization
        return View();
    }
}

【问题讨论】:

    标签: asp.net asp.net-mvc


    【解决方案1】:

    好的,这就是我所做的。如果有更好的方法请告诉我。

    public class NotAuthorizeAttribute : FilterAttribute
    {
        // Does nothing, just used for decoration
    }
    
    public class BaseController : Controller
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Check if this action has NotAuthorizeAttribute
            object[] attributes = filterContext.ActionDescriptor.GetCustomAttributes(true);
            if (attributes.Any(a => a is NotAuthorizeAttribute)) return;
    
            // Must login
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                filterContext.Result = new HttpUnauthorizedResult();
            }
        }
    }
    

    【讨论】:

    • 我认为 MVC4 复制了你,现在我们有了 [AllowAnonymous]
    • 在自定义控制器中创建自定义验证功能时了解仍然很有帮助:)
    • @Simon_Weaver,你可以看到这段代码有两部分。第一个是AllowAnonymous 覆盖的部分,第二个是AllowAnonymous 未覆盖的部分。我的意思是第二个if 子句-它检查用户是否经过身份验证。现在,如果我想避免一直输入Authorize,那么我需要它。我们在 ASP.NET 中有类似的东西吗?
    【解决方案2】:

    [AllowAnonymous] 呢??

    【讨论】:

    • 这是后来创建的,但现在是正确答案。
    • 好的。有AllowAnonymous 属性。但是,如果我希望所有其他地方都默认需要授权,我该怎么办?我的意思是所有其他控制器和操作。如何避免在控制器操作需要授权时一直明确输入?
    【解决方案3】:

    MVC4 有一个新属性,正好用于这个 [AllowAnonymous](正如 Enrico 所指出的)

    [AllowAnonymous]
    public ActionResult Register()
    

    在此处阅读所有相关信息:

    http://blogs.msdn.com/b/rickandy/archive/2012/03/23/securing-your-asp-net-mvc-4-app-and-the-new-allowanonymous-attribute.aspx

    【讨论】:

    • 好的。有AllowAnonymous 属性。但是,如果我希望所有其他地方都默认需要授权,我该怎么办?我的意思是所有其他控制器和操作。如何避免在控制器操作需要授权时一直明确输入?
    【解决方案4】:

    这就是我要做的,类似于 Craig 的回答,但有一些变化:

    1) 创建一个从 System.Attribute 派生的普通属性(无需从 FilterAttribute 派生,因为您不会使用 FilterAttribute 提供的任何东西)。

    也许可以创建一个属性的类层次结构,以便您可以基于层次结构进行测试,例如

    Attribute
        AuthorizationAttribute
             AuthorizationNotRequiredAttribute
             AuthorizationAdminUserRequiredAttribute
                 AuthorizationSuperUserRequiredAttribute
    

    2) 在您的 BaseController 中覆盖 OnAuthorization 方法而不是 OnActionExecuting 方法:

    protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        var authorizationAttributes = filterContext.ActionDescriptor.GetCustomAttributes(true).OfType<AuthorizationAttribute>();
        bool accountRequired = !authorizationAttributes.Any(aa => aa is AuthorizationNotRequiredAttribute);
    

    我喜欢默认安全的方法:即使您忘记在 Action 上添加属性,它也至少需要用户登录。

    【讨论】:

    • 如果我重写 OnAuthorization(AuthorizationContext filterContext),filterContext 没有 ActionDescriptor 属性,所以我不知道如何从 filterContext 中找到自定义属性?
    • 你能确认这是 ASP.NET MVC 2 吗? V2 中肯定有一个 ActionDescriptor。
    • 已安装 mvc 2 并且代码正在运行,我进入我的 onAuthorisation 重载,检查我的属性,如果找到,则返回。在我退出 onAuth 方法后,它仍然会重定向到登录页面吗?编辑:nvm 是因为我的控制器上仍然有授权属性
    【解决方案5】:

    使用Securing your ASP.NET MVC 3 Application 中所述的自定义过滤器。

    【讨论】:

    • 请注意,不鼓励仅链接的答案,堆栈溢出答案应该是搜索解决方案的终点(与另一个参考中途停留,随着时间的推移往往会变得陈旧)。
    【解决方案6】:

    用 [Authorize] 标记控制器

    [授权] 公共类 YourController : ApiController

    标记您希望公开的操作:

    [允许匿名]

    【讨论】:

      【解决方案7】:

      晚了一点,但我最终创建了一个控制器级别的身份验证属性和一个动作级别的身份验证属性,如果操作有自己的身份验证属性,我就跳过了控制器身份验证。在此处查看代码:

      https://gist.github.com/948822

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-29
        • 1970-01-01
        • 2014-06-09
        • 2022-07-01
        • 2012-02-19
        • 1970-01-01
        相关资源
        最近更新 更多