2010-05-03 82 views
2

我一直在wcf服務中使用PrincipalPermission。 [PrincipalPermission(SecurityAction.Demand,Role = SecurityRoles.CanManageUsers)]細粒度權限; PrincipalPermission - 角色與權限分離;

我們的角色前綴爲: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繼承 - 安全人員對此有何評論?

有其他人解決了這個問題,在框架中有沒有什麼東西我錯過了?

回答

0

我會說,如果你在ASP.NET中,那麼你應該實現一個custom RoleProvider

在您的自定義RoleProvider中,您將訪問另一個表,該表會將業務組鏈接到細粒度的權限。

然後,當您找到用戶時,您可以找到他們所在的業務組,並在RoleProvider中分配所有適當的角色,而不會更改您擁有的任何現有代碼。

它也可以更好地工作,因爲它允許您輕鬆地更改哪些組擁有什麼權限,同時保持純粹在代碼方面的權限的域模型。

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)); 
      } 
     } 
    } 
}