【问题标题】:fine-grained permissions; PrincipalPermission - roles seperate from permissions;细粒度的权限; PrincipalPermission - 角色与权限分开;
【发布时间】:2010-05-03 18:11:40
【问题描述】:

我在 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 继承——安全人员对此有何看法?

有其他人解决过这个问题吗,框架中是否有我遗漏的东西?

【问题讨论】:

    标签: c# wcf security code-access-security principalpermission


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      我实现了第一次迭代,它运行良好。 [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));
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2023-03-25
        • 1970-01-01
        • 2021-08-27
        • 2014-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-17
        相关资源
        最近更新 更多