MSDN非常清楚MVC路由和安全性:
保护 MVC 应用程序的唯一受支持的方法是将 AuthorizeAttribute 属性应用于每个控制器,并在登录和注册操作上使用 AllowAnonymousAttribute 属性。
但是,我正在考虑以下方法:
首先,我实现了一个自定义控制器工厂,它根据来自自定义 STS 的信息执行安全检查。
除其他信息外,STS 颁发的令牌包含描述允许用户访问的所有 MVC 路由的声明。
然后我检查 CreateController 方法中的用户声明:
public class SecuredControllerFactory : IControllerFactory
{
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
...
bool isAuthorized = principal.HasRequiredRight(verb, ressource);
...
}
}
这样,我们可以集中配置和更新安全规则,而无需重新部署应用程序。此外,它符合"约定优于配置"的想法。
这种方法有问题吗?我不明白为什么这被认为是一种不好的做法?有人可以对此表现出具体的安全问题吗?
我想这是不好的做法,因为它违反了控制器工厂内的单一责任原则。控制器工厂的唯一职责应该是选择和实例化控制器。
我会质疑你使用控制器工厂方法的原因:
这样,我们可以集中配置和更新安全规则 方式,无需重新部署我们的应用程序。
如果使用在代码中指定允许的用户/角色的标准AuthorizeAttribute
,则这是有效的语句。
但是,建议的方法是从派生类中派生AuthorizeAttribute
并通过重写受保护的AuthorizeCore()
方法在派生类中实现安全规则逻辑。例如,它可以在数据库中查找权限,以便您可以在运行时动态更改它们。
这也允许您实现在授权检查失败时调用的自定义逻辑(HandleUnauthorizedrequest()
方法(,这可能是授权逻辑失败时您必须在自定义控制器工厂中执行的操作(例如,重定向到登录或错误页面?
这样,您就可以更改安全规则并集中管理它们,而无需重新部署整个应用程序,并且不会破坏ControllerFactory
的单一责任
ThinkTexture在其身份模型框架中提供了良好的实现,如此处所述
http://leastprivilege.com/2012/10/26/using-claims-based-authorization-in-mvc-and-web-api/
这允许您指定资源/操作,并以通常的 WIF 方式将授权逻辑封装在自定义ClaimsAuthorizationManager
中。如果未在属性中显式指定资源和操作,则框架将使用当前HttpActionContext
获取值,这很好。