2

我在 wcf 服务中使用 PrincipalPermission 已经有一段时间了。[PrincipalPermission(SecurityAction.Demand, Role = SecurityRoles.CanManageUsers)]

我们的角色以:Can* 为前缀,这是我们使用内置 asp.net 会员系统实现细粒度操作控制的方式。

这使得作为一个业务部门很难知道我们可以为用户提供哪些细粒度的角色。

这是我的新方法,想看看是否有人可以在我实施我的建议之前提供反馈和代码审查。

1) aspnet_roles - 业务部门角色

2)通过创建权限表和Role_Permission表和User_Permission表来扩展asp.net会员系统(多对多)

3)创建自定义 CodeAccessSecurityAttribute + 来查看新表 [CustomPermissionCheck(Security.Demand, HasPermission="can*")] 第一次迭代我将静态地新建依赖存储库.. 理想情况下,我想要一个注入存储库的 aop 样式属性IPermissionRepository.HasPermission(...);

如果我采用新的 aop 方式,我可能会停止从 CodeAccessSecurityAttribute 继承——安全人员对此有何看法?

有没有其他人解决了这个问题,我错过了框架中有什么东西吗?

4

2 回答 2

0

我想说,如果你在 ASP.NET 中,那么你应该实现一个自定义 RoleProvider

在您的自定义 RoleProvider 中,您将访问另一个表,该表将业务组链接到细粒度权限。

然后,当您找到用户时,您可以找到他们所在的业务组,并在 RoleProvider 中分配所有适当的角色,而不更改您拥有的任何现有代码。

它也工作得更好,因为它允许您轻松更改哪些组具有哪些权限,同时在代码端保持权限的域模型纯。

于 2010-05-03T18:51:08.167 回答
0

我实现了第一次迭代,它运行良好。[PermissionValidate(SecurityAction.Demand, HasPermission = CensusSchedulerRoles.CanUpdateCensusScheduler)]

public void Demand()
{
    var principal = Thread.CurrentPrincipal;
    if(principal == null || principal.Identity.IsAuthenticated == false)
    {
        throw new SecurityException("Unable to get IPrincipal.");
    }
    if(principal.Identity.IsAuthenticated == false)
    {
        throw new SecurityException("You must be authenticated.");
    }   
     #warning this should be moved to an aop attribute that is injected by a ioc container.
    using (var connection = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["......."].ConnectionString))
    {
        connection.Open();
        using(var command = new SqlCommand(
        @"
            SELECT COUNT(t.name) FROM
            (
                SELECT p.name, u.UserName FROM 
                    aspnet_Users as u
                    INNER JOIN [User_Permission] as up
                        ON up.user_id = u.UserId
                    INNER JOIN Permission as p
                        ON p.id = up.permission_id
                UNION
                SELECT p2.name, u2.UserName FROM 
                    aspnet_Users as u2
                    INNER JOIN aspnet_UsersInRoles as uir
                        ON uir.UserId = u2.UserId
                    INNER JOIN aspnet_Roles as r
                        ON r.RoleId = uir.RoleId
                    INNER JOIN Role_Permission as rp
                        ON rp.role_id = r.RoleId
                    INNER JOIN Permission as p2
                        ON p2.id = rp.permission_id
            ) as t
            WHERE t.UserName = @username AND t.name = @haspermission
        ", connection))
        {
            command.Parameters.Add("@username", SqlDbType.VarChar).Value = Thread.CurrentPrincipal.Identity.Name;
            command.Parameters.Add("@haspermission", SqlDbType.VarChar).Value = _permissionRequested;

            if( Convert.ToInt32(command.ExecuteScalar()) <=0)
            {
                throw new SecurityException(String.Format("User '{0}' is not assigned permission '{1}'.", principal.Identity.Name, _permissionRequested));
            }
        }
    }
}
于 2011-05-15T04:53:57.263 回答