Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JdbcMutableAclService - Transaction must be running

I'm trying to implement spring security acl into a project. After building the main configuration part and creating the according database schema, I'm trying to create some ACEs and let the magic happen. But I'm facing this exception over and over again

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)

My basic configuration parts

<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>  

It seems that I'm missing something because the transaction should be active through the TransactionProxy.

Accessing the service in a controller this way

...
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);
...
like image 859
onigunn Avatar asked Apr 19 '11 09:04

onigunn


3 Answers

Try to cover the calling aclService methods with a transaction template:

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);            
        }
    });
like image 178
kiro11 Avatar answered Oct 16 '22 00:10

kiro11


The error you mentioned only happens when the sid is not present in the acl_sid table and is inserted by Spring ACL automatically. Try adding the rows manually and then rerun the code. This worked for me.

Refer http://forum.springsource.org/showthread.php?55490-ACL-Transaction-must-be-running

like image 25
Shashank Singhal Avatar answered Oct 16 '22 01:10

Shashank Singhal


The @Transactional annotation above method or service (containing the method) may solve the problem.

like image 2
Ivan Gandacov Avatar answered Oct 16 '22 01:10

Ivan Gandacov