1

很多关于基于角色的访问的在线文章都谈到应用这样的东西来确保对控制器或操作的基于角色的访问

[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(Roles = "Admin, Manager")] 分配给 Authorize 属性的任何值匹配。在某些情况下,如果角色具有管理员或经理,他们应该获得访问权限。在某些情况下,我希望他们同时拥有管理员和经理角色来获得访问权限。

此外,如果将来将新角色添加到系统中,我是否需要重新构建和重新部署我的应用程序,并重做所有授权属性?

我无法找到任何实现相同功能的明确示例,或者我可能没有正确搜索。请以任何方式帮助我。谢谢你的时间...

4

2 回答 2

3

您需要实现自定义IPrincipal(或自定义RoleProvider,但在我看来 IPrincipal 更容易)。

在您的表单身份验证控制器中,针对您的用户表进行身份验证,并使用您的角色表中的角色创建一个 IPrincipal。您可能还希望在使用您的角色时设置一个 Forms Auth cookie,这样您就不需要在每个请求(或使用会话)时访问数据库。查看此问题中的代码以获取此方法的示例。

如果您的用户没有任何自定义属性,则可以使用内置的 GenericIdentity 和 GenericPrincipal。

编辑- 如果您将用户信息存储在会话中,您只需要确保在每个请求开始时将 HttpContext.Current.User 设置为会话派生的 IPrincipal (OnPostAuthenticate)

您将需要重建/重新部署以适应这种方法的新角色。如果您想动态分配角色并在运行时处理它们,则需要实现自定义 AuthorizationAttribute - 这可能需要(例如)一个字符串“Operation”参数,该参数可以与数据库中的角色匹配。我个人会留下这个,直到你很明显需要它。

于 2012-03-07T12:31:06.333 回答
0

听起来您可能超出了基于角色的安全设计。如果您需要动态细粒度的非/或特权,那么您至少应该开始考虑一种更加基于声明的方法

您可能可以通过实现IPrincipal像上面链接显示的自定义(没有完全基于声明)来实现您所描述的一些内容。

希望这可以帮助。

于 2012-03-07T12:36:29.310 回答