2011-04-19 44 views
4

我正試圖將spring security acl實現到一個項目中。在構建主要配置部分並創建相應的數據庫模式之後,我試圖創建一些ACE並讓魔法發生。但我一遍又一遍面對這個異常再次JdbcMutableAclService - 事務必須正在運行

java.lang.IllegalArgumentException: Transaction must be running 
    org.springframework.util.Assert.isTrue(Assert.java:65) 
    org.springframework.security.acls.jdbc.JdbcMutableAclService.createOrRetrieveSidPrimaryKey(JdbcMutableAclService.java:219) 
    org.springframework.security.acls.jdbc.JdbcMutableAclService$1.setValues(JdbcMutableAclService.java:136) 
    org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:892) 
    org.springframework.jdbc.core.JdbcTemplate$4.doInPreparedStatement(JdbcTemplate.java:1) 
    org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:586) 
    org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:614) 
    org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:883) 
    org.springframework.security.acls.jdbc.JdbcMutableAclService.createEntries(JdbcMutableAclService.java:123) 
    org.springframework.security.acls.jdbc.JdbcMutableAclService.updateAcl(JdbcMutableAclService.java:314) 

我的基本配置部分

<bean id="dataSource" 
    class="org.apache.commons.dbcp.BasicDataSource" 
    destroy-method="close" > 
    <property name="driverClassName" value="${core.db.driverClassName}" /> 
    <property name="url" value="${core.db.jdbcUrl}" /> 
    <property name="username" value="${core.db.user}" /> 
    <property name="password" value="${core.db.password}" /> 
</bean> 

<bean id="aclCache" 
    class="org.springframework.security.acls.domain.EhCacheBasedAclCache"> 
    <constructor-arg> 
     <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean"> 
      <property name="cacheManager"> 
       <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" /> 
      </property> 
      <property name="cacheName" value="aclCache" /> 
     </bean> 
    </constructor-arg> 
</bean> 

<bean id="auditLogger" 
    class="org.springframework.security.acls.domain.ConsoleAuditLogger" /> 

<bean id="aclAuthorizationStrategy" 
    class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl"> 
    <constructor-arg name="auths"> 
     <list> 
      <bean 
       class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
       <constructor-arg value="ACL_ADMIN" /> 
      </bean> 
      <bean 
       class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
       <constructor-arg value="ACL_ADMIN" /> 
      </bean> 
      <bean 
       class="org.springframework.security.core.authority.GrantedAuthorityImpl"> 
       <constructor-arg value="ACL_ADMIN" /> 
      </bean> 
     </list> 
    </constructor-arg> 
</bean> 

<bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy"> 
    <constructor-arg name="dataSource" ref="dataSource"/> 
    <constructor-arg name="aclCache" ref="aclCache"/> 
    <constructor-arg name="aclAuthorizationStrategy" ref="aclAuthorizationStrategy"/> 
    <constructor-arg name="auditLogger" ref="auditLogger"/> 
</bean> 

<bean id="aclService" 
    class="org.springframework.security.acls.jdbc.JdbcMutableAclService" > 
    <constructor-arg name="dataSource" ref="dataSource" /> 
    <constructor-arg name="lookupStrategy" ref="lookupStrategy" /> 
    <constructor-arg name="aclCache" ref="aclCache" /> 
    <property name="sidIdentityQuery" value="SELECT id FROM acl_sid" /> 
    <property name="classIdentityQuery" value="SELECT id FROM acl_class" /> 
</bean> 

<bean id="jdbcTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource"></property> 
</bean> 

<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager"><ref local="jdbcTransactionManager"/></property> 
    <property name="target"><ref local="aclService" /></property> 
    <property name="transactionAttributes"> 
     <props> 
      <prop key="create*">PROPAGATION_REQUIRED</prop> 
      <prop key="update*">PROPAGATION_REQUIRED</prop> 
      <prop key="delete*">PROPAGATION_REQUIRED</prop> 
     </props> 
    </property> 
</bean> 

看來,我失去了一些東西,因爲該交易應通過TransactionProxy活躍。

這種方式訪問​​該服務在控制器

... 
ObjectIdentity oi = new ObjectIdentityImpl(X.class, vm.hashCode()); 
Sid sid = new PrincipalSid(userDn); 
Permission p = BasePermission.READ; 

// Create or update the relevant ACL 
MutableAcl acl = null; 
try { 
    acl = (MutableAcl) aclService.readAclById(oi); 
} catch (NotFoundException nfe) { 
    acl = aclService.createAcl(oi); 
} 

// Now grant some permissions via an access control entry (ACE) 
acl.insertAce(acl.getEntries().size(), p, sid, true); 
aclService.updateAcl(acl); 
... 

回答

7

試圖掩蓋呼叫aclService方法與交易模板:

TransactionTemplate tt = new TransactionTemplate(transactionManager); 
    tt.execute(new TransactionCallbackWithoutResult() { 
     @Override 
     protected void doInTransactionWithoutResult(TransactionStatus status) { 
      ObjectIdentity oid = new ObjectId 
      entityImpl(clazz.getCanonicalName(), securedObject.getId()); 
       // your aclService operation here: 
       aclService.deleteAcl(oid, true);    
     } 
    }); 
+0

6年後,我碰到了同樣的問題,發現這非常有幫助。只是一個小小的評論:當爲了同步目的創建類或sid記錄時,事務被斷言。不需要爲deleteAcl()運行事務 – Michal 2017-04-06 03:58:00

相關問題