许多关于基于角色的访问的在线文章谈到应用这样的东西来确保基于角色的访问控制器或操作
[Authorize(Roles = "Admin, Manager")]
public class SomeController : Controller
{
}
所有这一切都很好,但是现在如果我需要实现我自己的基于角色的自定义访问,其中我在[RoleMaster]表中有角色,并且从另一个名为[UserRoles]的表中的[User]表中分配给用户的角色]。在我的代码中,我将在会话中有一个用户对象,其中现在将有一个角色列表
public class RegisteredUsers
{
//... other user properties
public List<UserRole> Roles { get; set; }
}
public class UserRole
{
public string RoleID { get; set; }
public string RoleName { get; set; }
//... other properties
}
现在,我如何检查RegisteredUsers对象的Roles列表中的UserRole.RoleName属性,以匹配我使用以下命令分配给Authorize属性的任何值:[Authorize(Roles =“Admin,Manager”)] 。在某些情况下,如果角色有管理员或经理,他们应该获得访问权限。在某些情况下,我希望他们同时拥有Admin和Manager Role来获取访问权限。
此外,将来如果将新角色添加到系统中,我是否需要重新构建并重新部署我的应用程序并重新授予所有授权属性?
我无法找到实现相同的任何明确示例,或者我可能没有正确搜索。请以任何方式帮助我。谢谢你的时间......
答案 0 :(得分:3)
您需要实现自定义IPrincipal(或自定义RoleProvider,但在我看来,IPrincipal更容易)。
在表单身份验证控制器中,针对您的用户表进行身份验证,并使用角色表中的角色创建IPrincipal。您可能还希望在使用角色时设置Forms Auth cookie,这样您就不需要在每个请求中使用数据库(或使用会话)。有关此方法的示例,请查看this question中的代码。
如果您的用户没有任何自定义属性,则可以使用内置的GenericIdentity和GenericPrincipal。
编辑 - 如果您在会话中存储用户信息,则只需确保在每个会话开始时将HttpContext.Current.User设置为会话派生的IPrincipal。请求(OnPostAuthenticate)
您需要使用此方法重建/重新部署以迎合新角色。如果要在运行时动态分配角色并处理它们,则需要实现自定义AuthorizationAttribute - 这可以采用(例如)字符串'Operation'参数,该参数可以与DB中的角色匹配。我会亲自离开这个,直到你明白你需要它为止。
答案 1 :(得分:0)
听起来你可能会超过基于角色的安全设计。如果您需要动态粒度或/或权限,那么您应该开始至少查看更多claims-based approach。
您可以通过实施自定义IPrincipal
来完成您所描述的内容,例如上面的链接显示(没有基于声明的完整版)。
希望这有帮助。