ASP.NET MVC - 动态授权
Posted
技术标签:
【中文标题】ASP.NET MVC - 动态授权【英文标题】:ASP.NET MVC - Dynamic Authorization 【发布时间】:2011-01-24 18:30:15 【问题描述】:我正在构建一个简单的 CMS,其中角色在管理面板中动态设置。因此,现有的授权控制器方法的方式,例如添加[Authorize(Roles="admin")]
,已经不够用了。角色-动作关系必须存储在数据库中,以便最终用户可以轻松地在管理面板中授予/获取其他人的权限。我该如何实现?
【问题讨论】:
【参考方案1】:如果你想控制授权过程,你应该继承AuthorizeAttribute并覆盖AuthorizeCore方法。然后只需使用 CmsAuthorizeAttribute
而不是默认值来装饰您的控制器。
public class CmsAuthorizeAttribute : AuthorizeAttribute
public override virtual bool AuthorizeCore(HttpContextBase httpContext)
IPrincipal user = httpContext.User;
IIdentity identity = user.Identity;
if (!identity.IsAuthenticated)
return false;
bool isAuthorized = true;
// TODO: perform custom authorization against the CMS
return isAuthorized;
这样做的缺点是您无法访问注入 ctor 的 IoC,因此您必须直接从容器请求任何依赖项。
【讨论】:
直接从容器中获取依赖的缺点是什么?我的 RoleProvider 实施不得不这样做... @Haroon - 缺点之一是设计。通常认为最好的做法是让代码保持对 IoC 容器的无知,以减少对它的依赖(例如,您可能希望在 WP7 上重用您的代码,因为性能原因通常避免使用基于反射的容器)。 @Haroon - 话虽如此,MVC 3 支持通过属性装饰的属性进行过滤器属性注入。它仍然需要容器的知识,但更容易模拟。 这就是我发现自己遇到的问题,mvc2 有时感觉很笨拙,但我认为如果使用容器完成工作。我宁愿不写hacky代码只是为了让事情变得“理想”【参考方案2】:这正是 ASP.NET 成员/配置文件为您所做的。它适用于 Authorize 属性。
如果您想自己动手,您可以创建一个自定义操作过滤器,模仿标准授权操作过滤器的行为。伪代码如下。
public MyAuthorizeAttribute : ActionFilterAttribute
public string MyRole get; set;
public void OnActionExecuting(ControllerContext context)
if (!(bool)Session["userIsAuthenticated"])
throw new AuthenticationException("Must log in.");
if (!Session["userRoles"].Contains(MyRole))
throw new AuthenticationException("Must have role " + MyRole);
【讨论】:
我对这些东西很陌生,但我看到了一个在代码中专门分配角色的示例,我不希望这样。例如,某些客户端可能有一个名为“工程师”的用户组,该用户组具有特定权限。我希望他能够从管理面板设置它们,而无需触及任何代码。现在,我看不出如何使用标准的 Authorize 属性来实现这一点 那么您必须在某个时候在您的数据库中添加查找,也许将用户和控制器/操作名称与您在数据库中的访问规则相匹配。或类似的东西。【参考方案3】:角色-动作关系必须是 存储在数据库中
您必须在控制器方法中检查您的安全性,除非您想继承 AuthorizeAttribute
以便它为您从数据库中查找角色。
【讨论】:
以上是关于ASP.NET MVC - 动态授权的主要内容,如果未能解决你的问题,请参考以下文章