AuthorizeAttribute是包含在ASP.NET MVC中默认的授权过滤器。可以使用它来限制对动作方法的访问。将该特性运用到控制器上可以迅速将其运用到每个动作方法中。
在运用该过滤器时需要牢记如下内容:
在运用该特性时,可以指定一个逗号来划分角色(Role)或用户(User)的列表。如果指定了一个角色的列表,那么为了动作方法的执行,用户必须是其中一个角色中的成员。同样的,如果指定了一个用户的列表,那么当前用户的名称必须在该列表中。
为什么不使用已有的、构建在ASP.NET中的URL授权
保护使用了Web Forms的应用程序的常见方式是使用URL授权。例如,如果具有一个管理部分,而且希望将其限制为那些位于管理员(Admins)角色中的用户,那么可能会把所有管理页面都放在管理文件夹中并拒绝除位于管理员角色中以外的任何人访问子文件夹。
对于MVC而言,这种方法不会很好地运转,原因有两个:
请求不再映射到物理目录中。
进入到同一个控制器的路由可能不止一个。
对于MVC而言,理论上讲,是可以使用AdminController封装应用程序的管理功能,然后在web.config根文件中设置URL授权,进而阻止访问任何以/Admin开头的请求。然而,这并不是万无一失的,也有可能存在另外一个路由,它可能在不经意间映射到AdminController中。
例如,后面将会讨论的,如果决定切换默认路由中的{controller}和{action}的顺序,那么此时,/Index/Admin是默认的管理页面的URL,而且URL授权也不再阻止它。
安全性较好的一个方法是总是尽可能紧紧地将安全检查放到需要保护的对象上。虽然可能会在更高层次的堆栈上具有其他检查,但是最终希望保护的是实际的资源。在这种情况下,不希望依靠路由选择和URL授权来保护控制器;真正想要保护的是控制器自身。AuthorizeAttribute正好用于此用途。
如果没有指定任何角色或用户,那么为了调用动作方法,必须只验证当前的用户。这是阻止非验证用户访问特殊控制器动作的一个简单的方法。
如果用户试图访问运用了该特性的动作方法且在授权检查中失败,那么过滤器将引发服务器返回一个401 Unauthorized的HTTP状态代码。
对于启用了表单验证且在web.config中指定了注册URL的情形,ASP.NET将处理该响应代码并将用户重新引向注册页面。这是ASP.NET已有的行为,对于ASP.NET MVC也不是新鲜事物。
产品小组的话:
一开始,我们将PrincipalPermissionAttribute看作是保护控制器动作的一个可行的解决方案,但是碰到了很多问题。首先,在将其运用到类时,PrincipalPermissionAttribute将在安全检查失败而试图实例化Controller类时导致一个异常。因为我们希望当安全检查失败时可能会有其他过滤器运行(例如,日志记录过滤器),所以这并不是我们想要的行为。
其次,我们希望能控制产生的状态代码。而PrincipalPermissionAttribute只是抛出一个SecurityException。
下面看一个使用的简单示例。在下面的代码中,管理控制器只限制于Admins和SuperAdmins角色的成员。注意,角色是通过逗号隔开的。过滤器将忽略逗号之间的空白以允许提高在运用该特性时的可读性。