2013-10-07 47 views
3

我正在使用Spring Security ACL實現,並且想知道爲現有對象身份授予角色/用戶(安全身份-SID)的新權限的最佳方式。使用Spring Security ACL授予對現有對象身份的許可

例如,假設我有以下的(我主要是省略了主鍵和一些列,只需通過字符串值可讀性參考):

  • ACL_SID:ROLE_TEST
  • ACL_CLASS: test_class
  • ACL_OBJECT_IDENTITY:
    • ID:1
    • object_id_class:test_class
    • object_id_identity:someObjectInstanceId
  • ACL_ENTRY:
    • ACL_OBJECT_IDENTITY:1
    • SID:ROLE_TEST
    • 掩模:CREATE(這將是在分貝的整數)

現在,我想授予角色ROLE_TESTtest_class類的所有未來和現有對象的許可WRITE。對於將來創建的對象,我將簡單地檢查角色的權限並授予它們。但是,現有的對象呢?

Spring是否提供任何方法來輕鬆完成此操作,或者是否必須編寫自己的自定義代碼來執行以下操作(這不會太糟糕,但如果Spring已經提供了這個,我寧願不要自己做):

  1. 檢索與該角色/用戶我要授予新的權限和引用具有適當object_id_class對象身份的SID所有ACL條目。
  2. 對於每個結果,創建一個新的ACL條目,其結果與除了掩碼之外的結果相同,這將反映新的權限。

回答

2

因爲我找不到任何內建的Spring支持,所以我最終使用了下面的自定義代碼。不是最高效的,但它做我需要它做的事情。

如果有人知道更好的解決方案或有改善下面的代碼的建議,請讓我知道。

定製JDBC ACL服務按類型來檢索所有現有的對象標識(ACL_CLASS):

import org.springframework.jdbc.core.JdbcTemplate; 
import org.springframework.security.acls.domain.GrantedAuthoritySid; 
import org.springframework.security.acls.domain.ObjectIdentityImpl; 
import org.springframework.security.acls.domain.PrincipalSid; 
import org.springframework.security.acls.model.ObjectIdentity; 
import org.springframework.security.acls.model.Sid; 

import javax.sql.DataSource; 
import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 

public class CustomJdbcAclService { 

    private final JdbcTemplate jdbcTemplate; 

    private final static String SELECT_EXISTING_BY_CLASS_AND_SID = 
      "SELECT DISTINCT " + 
      "acl_object_identity.object_id_identity " + 
      "FROM acl_object_identity " + 
      "LEFT JOIN acl_entry on acl_entry.acl_object_identity = acl_object_identity.id " + 
      "LEFT JOIN acl_class on acl_class.id = acl_object_identity.object_id_class " + 
      "LEFT JOIN acl_sid on acl_entry.sid = acl_sid.id " + 
      "WHERE acl_class.class = ? && acl_sid.sid = ? && acl_entry.granting = 1"; 

    public CustomJdbcAclService(DataSource dataSource) { 
     this.jdbcTemplate = new JdbcTemplate(dataSource); 
    } 

    public List<ObjectIdentity> getExistingObjectIdentities(String type, Sid sid) { 
     String sidName = getSidName(sid); 

     List<Map<String, Object>> results = jdbcTemplate.queryForList(SELECT_EXISTING_BY_CLASS_AND_SID, type, sidName); 
     List<ObjectIdentity> oids = new ArrayList<>(); 

     for (Map<String, Object> result : results) { 
      oids.add(new ObjectIdentityImpl(type, (Serializable) result.get("object_id_identity"))); 
     } 

     return oids; 
    } 

    private String getSidName(Sid sid) { 
     String sidName; 

     if (sid instanceof PrincipalSid) { 
      sidName = ((PrincipalSid) sid).getPrincipal(); 
     } else if (sid instanceof GrantedAuthoritySid) { 
      sidName = ((GrantedAuthoritySid) sid).getGrantedAuthority(); 
     } else { 
      throw new IllegalArgumentException("Unsupported implementation of Sid"); 
     } 
     return sidName; 
    } 

} 

我撥打以上從另一個ACL服務:

public class MyAclService { 

public void grantPermissionsToExisting(String type, Sid securityIdentity, Permission... permissions) { 
     List<ObjectIdentity> existingOids = customJdbcAclService.getExistingObjectIdentities(type, securityIdentity); 
     for (ObjectIdentity oid : existingOids) { 
      // grantPermissions() gets the ACL of the object identity and inserts the new ACEs 
      grantPermissions(oid, securityIdentity, permissions); 
     } 
    } 

} 
相關問題