除了一个(登录)之外,保护Controller中所有操作的最佳方法是什么?

时间:2011-06-16 17:40:58

标签: c# .net asp.net-mvc asp.net-mvc-3 razor

目前,除了[Authorize]操作之外,我AdminController上的所有方法都有Logon个属性。

最干净的方法是什么来反转它,所以我不必记住将属性添加到所有方法,而是仅将属性添加到应该可用的方法中没有登录?

Logon操作移动到自己的控制器,并将[Authorize]属性应用于AdminController类,我会更好吗?

5 个答案:

答案 0 :(得分:8)

在ASP.NET MVC 3中,您可以实现自定义全局action filter provider

public class MyProvider : IFilterProvider
{
    public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        var rd = controllerContext.RouteData;
        var controller = rd.GetRequiredString("controller");
        if (string.Equals("admin", controller, StringComparison.OrdinalIgnoreCase) &&
            string.Equals("logon", actionDescriptor.ActionName))
        {
            return Enumerable.Empty<Filter>();
        }

        return new[]
        {
            new Filter(new AuthorizeAttribute(), FilterScope.Action, 0)
        };
    }
}

可以在Application_Start注册:

FilterProviders.Providers.Add(new MyProvider());

现在,如果您正在使用某些DI容器(例如NInject),例如它支持filter binding syntax,这意味着您可以配置内核以根据上下文动态注入过滤器。

这种方法的优点在于,现在无需向应用程序添加什么控制器或操作=&gt;它需要授权。

答案 1 :(得分:4)

我会按照您的建议将Logon操作移动到自己的控制器,并将[Authorize]属性应用于整个AdminController类。这样更清洁,将来更容易维护。

答案 2 :(得分:2)

使用web.config中的<location>元素执行此操作的另一种方法。这是一个例子:

  <location path="/Admin/LogOn">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>  

  <location path="/Admin">
    <system.web>
      <authorization>
        <allow users="?" />
        <deny users="*" />
      </authorization>
    </system.web>
  </location>

答案 3 :(得分:1)

我通常做这样的事情:

[Authorize]
public abstract class AdminController : Controller
{
}

继承自命名惯例:

public class UserAdminController : AdminController 
{
}

VS

public class UserController : Controller 
{
}

答案 4 :(得分:0)

您可以使用过滤器提供商执行此操作。

Phill Haack wrote about it here