Java 기반 웹 응용 프로그램에서 작업 중이며 ThreadLocal을 사용하여 현재 로그인 한 사용자의 트랙을 유지합니다. 자, 정상적으로 완벽하게 작동합니다. 그러나 세션 시간 제한이 있고 시스템이 변수 (ThreadLocal 데이터에서)에 액세스하려고하면 임의의 값 (다른 로그인 한 사용자의 값)이 제공됩니다. 이상적으로 그것은 null 값을 리턴해야합니다. 나는 여기서 무슨 일이 일어나고 있는지 혼란 스럽다.세션 타임 아웃시 ThreadLocal 동작
답변
스레드가 풀링되므로 각 요청에 대해 ThreadLocal을 지워야합니다. 당신이 필터에이 일을 한 경우는 다음과 같이 보일 수 있습니다에서
- 사용자 A 로그 및 (사용자 A는 맥락에서) ThreadA에 연결되어 있습니다 : 이
private static final ThreadLocal<String> CONTEXT = new ThreadLocal<String>();
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
try {
CONTEXT.set(userName);
chain.doFilter(req,res);
} finally {
CONTEXT.remove();
}
}
그렇지 않으면 일어날 일입니다 과의
이 문제는 보안 문제 일뿐만 아니라 메모리 누수입니다. 사용자 당 채워지는 하나의 스레드 당 하나만 더 작아 보이지만 합산 할 수 있습니다. 또한 ThreadLocal에있는 객체가 해당 유형의 클래스 ClassLoader에 속한 객체 인 경우 응용 프로그램 서버를 다시 시작하지 않고 응용 프로그램을 배포 취소/배포 할 때마다 전쟁의 전체 내용을 누설하는 큰 PermGen leak을 갖게됩니다.
@LaurentG는 Spring Security와 함께 사용하는 접근법이 SecurityContextHolder를 사용하는 것이 맞습니다. SecurityContextPersistenceFilter는 finally 블록에 SecurityContext gets cleared out을 보장합니다.
도와 주신 모든 분들께 감사드립니다. 모든 것을 자세히 설명하므로 답변으로 표시하고 있습니다. 이 필터 접근법은 좋은 것처럼 보이며 시도해 볼 것입니다. – archangel
이것은 부서지기 쉬운 디자인입니다. 스레드 (및 TLS)는 세션과 관련이 없습니다. * 다중 요청 및 다중 세션은 동일한 스레드에서 실행될 수 있으며 동일한 TLS !!!를 공유 할 수 있습니다. TLS가 로그 아웃하기 전에 "작동"한다고해도 나는 운이 좋을 것으로 기대합니다. – user2246674
OK, ThreadLocal 변수가 세션에 개별적이지 않다는 말을하는 것입니까? 그렇다면 웹 응용 프로그램의 스레드 로컬 기능에 대한 세부 정보를 제공 할 수 있습니까? – archangel
1. 우리는 세션을 무효화하고 스레드 로컬 변수를 변경하지 않습니다. 2. 우리는 null로 설정하지 않지만 왜 다른 사용자의 로그인 값을 제공합니까? – archangel