java - 是/如何从托管 Spring bean 向线程提供 SecureContext

标签 java spring concurrency spring-security alfresco

我希望能够异步启动 Alfresco 节点的创建,以防止创建瓶颈。

为此,我尝试使用初始化为 10 的 ScheduledExecutorService

执行过程如下:

来 self 的UploadServlet --> (public) UploadManager#createNodeRef(SOME_PARAMS) --> (private synchronized) UploadManager#createNodeRef( SOME_PARAMS)

事务在 UploadServlet 中管理

代码:

private synchronized NodeRef createNodeRef(ARGS) {
  //
  // Creation Code using other Alfresco/Spring beans
  //
  return RETURN_VALUE;
}

异步代码(我正在尝试做的)

    private NodeRef makeAsyncNodeCreation(ARGS) {
    final ScheduledFuture<NodeRef> scheduledFuture = nodeCreationExecutor.schedule(new Callable<NodeRef>() {
        @Override
        public NodeRef call() throws Exception {
            // HERE I MAKE THE EFFECTIVE NODE CREATION
            return createNodeRef(filename, type, parentNode, label, kinematic);
        }
    }, MAX_NODE_CREATION_DELAY_IN_SECONDS, SECONDS);

    try {
        return scheduledFuture.get();
    } catch (InterruptedException e) {
        throw new AsyncNodeCreationException(e);
    } catch (ExecutionException e) {
        throw new AsyncNodeCreationException(e);
    }
}

然后是公共(public)方法

public NodeRef create(ARGS) {
    return makeAsyncNodeCreation(ARGS);
}

问题

我有以下异常

net.sf.acegisecurity.AuthenticationCredentialsNotFoundException: A valid SecureContext was not provided in the RequestContext

我的问题 为什么我的异步调用中不再存在 SecureContext?

最佳答案

因为 SecurityContextSecurityContextHolder 保存在 ThreadLocal 变量(默认策略)中,因此是当前线程,您需要传递 SecurityContext 到 Callable,因为它在不同的线程中运行,然后将它注入(inject)到 SecurityContextHolder 中它自己的 ThreadLocal。

我希望这个解决方案适用于 Acegi Security:

 // Get the SecurityContext hold by the main thread
 final SecurityContext securityContext = SecurityContextHolder.getContext();

 final ScheduledFuture<NodeRef> scheduledFuture = nodeCreationExecutor.schedule(new Callable<NodeRef>() {

  @Override
   public NodeRef call() throws Exception {

    // Inject the securityContext 
    SecurityContextHolder.setContext(securityContext);

    // HERE I MAKE THE EFFECTIVE NODE CREATION
    NodeRef noderef = createNodeRef(filename, type, parentNode, label, kinematic);

    // Cleaning...the thread may be recycled
    SecurityContextHolder.setContext(null);

    return noderef;

 }
}, MAX_NODE_CREATION_DELAY_IN_SECONDS, SECONDS);

关于java - 是/如何从托管 Spring bean 向线程提供 SecureContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27838631/

相关文章:

java - Spring 启动 : writing array of object to db

java - 不确定 volatile 的这种用法是否有意义,似乎有同样的问题

go - 如何编写一个接受 2 个函数(返回结构)并同时运行它们的函数?

java - 如何从 IPv6 计算国家代码

java - java CLASSPATH 环境变量上的 Jar 被忽略

Spring-boot liquibase 集成

java - Apache CXF/WSS4J 证书验证

java - 动态 Action 状态问题

Java 从 DateFormat 获取 int 数字并让用户输入

mysql - 这个更新丢失了吗?