创建(可变)Spring Security ACL会失败一半

时间:2012-12-14 04:45:51

标签: spring-mvc transactions spring-security acl

我正在使用JDBC支持的SpringSecurity ACL来管理用户创建的对象。

我有一个@Service,它处理我受ACL保护的对象的CRUD,因此需要生成适当的ACL并存储它们。我将整个类标记为@Transactional,在spring-security.xml中配置为

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

<tx:annotation-driven transaction-manager="oauthTXManager" />

dataSource正在发挥作用(承诺!),它是一个Postgres数据库,如果这可能很重要。

回到@Service。它看起来像这样(部分):

@Autowired
@Qualifier("aclService")
private MutableAclService aclService;

...

public Store createNewProfileWithOwner(Store profile, User owner) {
    try {
        Connection con = dataSource.getConnection();
        PreparedStatement query = con.prepareStatement(PROFILE_INSERT);
        ...
        query.executeUpdate();

        Sid sid = new PrincipalSid(owner.getUsername());
        Permission p = BasePermission.ADMINISTRATION;
        ObjectIdentity oi = new ObjectIdentityImpl(profile);
        MutableAcl acl = null;
        try {
            acl = (MutableAcl) aclService.readAclById(oi);
        } catch (NotFoundException e) {
            acl = aclService.createAcl(oi);
        }
        acl.setOwner(sid);
        acl.insertAce(acl.getEntries().size(), p, sid, true);
        aclService.updateAcl(acl);
        profile.setOwner(owner.getUsername());
        ...

    } catch (SQLException e) {
        e.printStackTrace();
    }
    return profile;
}

我有一个小脚本,用于测试调用此方法的API。我运行脚本的时间大约是一半,我在acl = aclService.createAcl(oi)得到一个错误,其中创建了ACL SpringSecurity尝试将其读回但无法找到它。很像this forum中描述的问题。其他50%的时间它工作得很好。最好的我可以缩小它,而不是“随机,大约一半的时间”,如果我运行脚本,它不起作用,然后再运行超过四秒但不到二十秒后,它会工作的。

奇怪的是,当我检查数据库时,SpringSecurity声称它在数据库中找不到的ID肯定存在。

我假设我正在遇到某种交易或缓存问题。我阅读了Transaction Management的第10.5.6节,但我担心它并没有真正帮助我找出错误的位置。

欢迎任何和所有建议。

1 个答案:

答案 0 :(得分:1)

我通过制作所有方法synchronized来“固定”它,并且还被SpringSecurity @Secured and @PreAuthorized倾斜,我强迫@PreAuthrorized在@Transactional之前进行评估。

到目前为止,它有效。