2011-08-19 7 views
2

스프링 서비스의 순차적 인 일련의 호출을 비동기 적으로 변환하려고합니다.SecurityContextHolder.getContext() @Async를 사용할 때의 NPE

나는 @Async으로 주석을 달고 taskExecutor 구성을 추가했습니다.

나는 방법은 이제 비동기 적으로 호출되고 있음을 볼 수 있지만 나는 SecurityContextHolder.getContext()이 오류를 던지고 문제가 있습니다 :

java.util.concurrent.ExecutionException: java.lang.NullPointerException

어떤 통찰력을 정말 감사하겠습니다. 감사!

+0

http://stackoverflow.com/questions/3467918/how-to-set-up-spring-security-securitycontextholder-strategy를 참조하십시오. – Ritesh

답변

6

SecurityContext는 ThreadLocal에 저장됩니다. 따라서 아무 곳이나 설정하지 않은 새 스레드에서 액세스하면 SecurityContext는 null입니다.

업데이트 : 추가 ThreadLocal를 javadoc의 링크

2

난에 "MODE_INHERITABLETHREADLOCA은"내 문제를 해결 startegy을 변경, 해결책을 발견했다.

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
<property name="targetClass" value="org.springframework.security.core.context.SecurityContextHolder"/> 
<property name="targetMethod" value="setStrategyName"/> 
<property name="arguments"> 
    <list> 
     <value>MODE_INHERITABLETHREADLOCAL</value> 
    </list> 
</property> 
</bean> 
0

봄 - 보안 3.2 이후이 답변의 끝 부분에 설명 된 좋은 주석 @AuthenticationPrincipal있다. 이것은 Spring Security> = 3.2를 사용할 때 가장 좋은 방법입니다. 여러 가지 방법으로 주입 할 수 있습니다. 자세한 내용은 look at this answer

0

비동기 호출에서 보안 컨텍스트에 액세스하려는 경우 아래와 같이 스레드를 만들 때 컨텍스트 인식 스레드 풀 실행 프로그램을 구현하여 보안 컨텍스트를 저장할 수 있습니다.

public class CustomExecutor extends ThreadPoolTaskExecutor { @Override public <T> Future<T> submit(Callable<T> task) { return super.submit(new ScopeAwareCallable<T>(task, SecurityContextHolder.getContext())); } }

public class ScopeAwareCallable<T> implements Callable<T> { 

private Callable<T> callableTask; 
private SecurityContext securityContext; 

public ScopeAwareCallable(Callable<T> task, SecurityContext secContex) { 
    this.callableTask = task; 
    this.securityContext = secContex; 
} 

@Override 
public T call() throws Exception { 
    if(securityContext != null){ 
     SecurityContextHolder.setContext(securityContext); 
    } 
    try { 
     return callableTask.call(); 
    } 
    finally { 
     SecurityContextHolder.clearContext(); 
    } 
} 

}이 스프링 구성에서 작업 실행과 같은

구성합니다. Callable 대신 Runnable를 사용하는 경우 Runnable 실행을 지원하는 ThreadPoolTaskExecutor의 다른 메서드도 재정의합니다.

관련 문제