Spring Security插入ACL:ConcurrentModificationException

纳克

我正在尝试使春季ACL工作。您可以在下面看到我如何尝试将新条目插入MutableAcl。只要我一次只添加一个就可以。但是,如果我尝试添加多个权限(例如READ,WRITE),则会收到ConcurrentModificationException,请参见下面的堆栈跟踪。因此,似乎存在一个并发问题,到目前为止,我还无法确定如何防止它。为了进行测试,我添加了Thread.sleep(1000); 在mutableAclService.updateAcl(acl)下面;call和voila,突然间我可以添加多个权限,因此对于MutableAclService或我的使用显然是一个问题。有任何想法吗?

问候,Nanoquack。

插入ACL的代码:@Autowired私有MutableAclService mutableAclService;

public void addPermission(Object entity, Serializable identifier, Sid recipient, Permission permission) {
    MutableAcl acl;
    ObjectIdentity oid = new ObjectIdentityImpl(entity.getClass(), identifier);
    try {
        acl = (MutableAcl) mutableAclService.readAclById(oid);
    } catch (NotFoundException e) {
        acl = (MutableAcl) mutableAclService.createAcl(oid);
    }
    acl.insertAce(acl.getEntries().size(), permission, recipient, true);
    mutableAclService.updateAcl(acl);
    log.debug("Added permission. Entity: " + entity + " Recipient: " + recipient + " Permission: " + permission);
}

尝试插入多个ACL时的堆栈跟踪:

25565 [acl%0043ache.data] ERROR net.sf.ehcache.store.disk.DiskStorageFactory - Disk Write of org.springframework.security.acls.domain.ObjectIdentityImpl[Type: com.coderunner.caliope.module.caliope.model.Page; Identifier: 0] failed:
net.sf.ehcache.CacheException: Failed to serialize element due to ConcurrentModificationException. This is frequently the result of inappropriately sharing thread unsafe object (eg. ArrayList, HashMap, etc) between threads
    at net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:401)
    at net.sf.ehcache.store.disk.DiskStorageFactory.write(DiskStorageFactory.java:381)
    at net.sf.ehcache.store.disk.DiskStorageFactory$DiskWriteTask.call(DiskStorageFactory.java:473)
    at net.sf.ehcache.store.disk.DiskStorageFactory$PersistentDiskWriteTask.call(DiskStorageFactory.java:1067)
    at net.sf.ehcache.store.disk.DiskStorageFactory$PersistentDiskWriteTask.call(DiskStorageFactory.java:1051)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
Caused by: java.util.ConcurrentModificationException
    at java.util.ArrayList.writeObject(ArrayList.java:713)
    at sun.reflect.GeneratedMethodAccessor40.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1429)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1175)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1541)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1506)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1429)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1175)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1541)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:439)
Hibernate: delete from acl_entry where acl_object_identity=?
    at net.sf.ehcache.Element.writeObject(Element.java:851)
    at sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:988)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1429)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1175)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347)
    at net.sf.ehcache.util.MemoryEfficientByteArrayOutputStream.serialize(MemoryEfficientByteArrayOutputStream.java:97)
    at net.sf.ehcache.store.disk.DiskStorageFactory.serializeElement(DiskStorageFactory.java:399)
    ... 11 more

Spring ACL配置:ROLE_ADMINISTRATOR

  <bean id="aclService"
    class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
    <constructor-arg ref="dataSource" />
    <constructor-arg ref="lookupStrategy" />
    <constructor-arg ref="aclCache" />
    <property name="classIdentityQuery" value="SELECT @@IDENTITY" />
    <property name="sidIdentityQuery" value="SELECT @@IDENTITY" />
  </bean>
  <bean id="expressionHandler"
    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator" ref="permissionEvaluator" />
    <property name="permissionCacheOptimizer">
      <bean
        class="org.springframework.security.acls.AclPermissionCacheOptimizer">
        <constructor-arg ref="aclService" />
      </bean>
    </property>
  </bean>

  <bean id="permissionEvaluator"
    class="org.springframework.security.acls.AclPermissionEvaluator">
    <constructor-arg ref="aclService" />
  </bean>

  <bean id="webexpressionHandler"
    class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />

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

显然您正在使用基于Ehcache的AclCache(由MutableAclService使用),并且Ehcaches磁盘存储似乎存在并发问题。

您的Ehcache配置如何?您是否尝试过使用内存存储(而不是磁盘存储)?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Spring Security插入ACL:ConcurrentModificationException

来自分类Dev

使用Spring Security ACL

来自分类Dev

在Spring Security Acl中授予权限

来自分类Dev

将AOP与Spring Security ACL结合使用

来自分类Dev

Spring Security AccessDecisionManager:roleVoter,Acl选民

来自分类Dev

Spring Security ACL管理权限

来自分类Dev

Spring Security ACL:我无法更新 ACL (SQLIntegrityConstraintViolationException)

来自分类Dev

将Spring Security ACL与Spring Data REST结合使用

来自分类Dev

使用Spring Security ACL授予对现有对象身份的权限

来自分类Dev

Spring Security-ACL readAclsById未按SID过滤

来自分类Dev

如何获得用户具有Spring Security ACL权限的域对象的列表?

来自分类Dev

Spring Security ACL-具有READ权限的用户可以撤销自己的访问权限吗?

来自分类Dev

Spring Security ACL抛出AccessDeniedException后,我该如何请求凭证?

来自分类Dev

Spring Session和Spring Security

来自分类Dev

Spring Security ACL中无法将java.lang.String强制转换为java.lang.Long

来自分类Dev

Spring Security无法登录

来自分类Dev

绕过Spring Security @preauthorize

来自分类Dev

Spring Security + Hibernate认证

来自分类Dev

Spring Security登录表单

来自分类Dev

Spring Security Java配置

来自分类Dev

Spring Security CSRF CORS

来自分类Dev

Spring Security部署错误

来自分类Dev

Spring Security登录实现

来自分类Dev

Spring Security超级密码

来自分类Dev

Spring Security会话并发

来自分类Dev

Spring Security OAuth stackoverflowException

来自分类Dev

Spring Security SAML实施

来自分类Dev

Spring Security中的NoSuchBeanDefinitionException

来自分类Dev

Spring Security服务配置