是 it/How 从托管 Spring bean 向线程提供 SecureContext
Is it/How to provide SecureContext to a Thread from a managed Spring bean
我希望能够异步启动 Alfresco 节点的创建以防止创建瓶颈。
为此,我正在尝试使用 ScheduledExecutorService
初始化值 10。
执行处理如下:
来自我的 UploadServlet
--> (public) UploadManager#createNodeRef(SOME_PARAMS)
--> (私有同步) 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?
因为 SecurityContext
由 SecurityContextHolder
保存在 ThreadLocal 变量(默认策略)中,因此是当前线程,您需要将 SecurityContext
传递给 Callable 因为它是 运行 在不同的线程中,然后将其注入到 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);
我希望能够异步启动 Alfresco 节点的创建以防止创建瓶颈。
为此,我正在尝试使用 ScheduledExecutorService
初始化值 10。
执行处理如下:
来自我的 UploadServlet
--> (public) UploadManager#createNodeRef(SOME_PARAMS)
--> (私有同步) 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?
因为 SecurityContext
由 SecurityContextHolder
保存在 ThreadLocal 变量(默认策略)中,因此是当前线程,您需要将 SecurityContext
传递给 Callable 因为它是 运行 在不同的线程中,然后将其注入到 SecurityContextHolder
.
我希望这个解决方案适用于 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);