我正在构建一个简单的CMS,其中角色是在管理员面板中动态设置的。现有的授权控制器方法的方式,例如添加[Authorize(Roles="admin")]
,因此已不再足够。角色与操作之间的关系必须存储在数据库中,以便最终用户可以轻松地在管理员面板中向其他用户授予/收回权限。如何实现这一点?
我正在构建一个简单的CMS,其中角色是在管理员面板中动态设置的。现有的授权控制器方法的方式,例如添加[Authorize(Roles="admin")]
,因此已不再足够。角色与操作之间的关系必须存储在数据库中,以便最终用户可以轻松地在管理员面板中向其他用户授予/收回权限。如何实现这一点?
如果你想控制授权过程,你应该继承 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;
}
}
这样做的缺点是您将无法访问通过构造函数注入的IoC,因此您必须直接从容器请求任何依赖项。这正是ASP.NET会员/配置文件所能为您做的事情。而且它还可以与Authorize属性一起使用。
如果您想自行开发,您可以创建一个自定义操作过滤器来模仿标准的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);
}
}
}
AuthorizeAttribute
,以便它为您从数据库中查找角色。