2013-07-09 2 views
0

Java 기반 웹 응용 프로그램에서 작업 중이며 ThreadLocal을 사용하여 현재 로그인 한 사용자의 트랙을 유지합니다. 자, 정상적으로 완벽하게 작동합니다. 그러나 세션 시간 제한이 있고 시스템이 변수 (ThreadLocal 데이터에서)에 액세스하려고하면 임의의 값 (다른 로그인 한 사용자의 값)이 제공됩니다. 이상적으로 그것은 null 값을 리턴해야합니다. 나는 여기서 무슨 일이 일어나고 있는지 혼란 스럽다.세션 타임 아웃시 ThreadLocal 동작

+1

이것은 부서지기 쉬운 디자인입니다. 스레드 (및 TLS)는 세션과 관련이 없습니다. * 다중 요청 및 다중 세션은 동일한 스레드에서 실행될 수 있으며 동일한 TLS !!!를 공유 할 수 있습니다. TLS가 로그 아웃하기 전에 "작동"한다고해도 나는 운이 좋을 것으로 기대합니다. – user2246674

+0

OK, ThreadLocal 변수가 세션에 개별적이지 않다는 말을하는 것입니까? 그렇다면 웹 응용 프로그램의 스레드 로컬 기능에 대한 세부 정보를 제공 할 수 있습니까? – archangel

+0

1. 우리는 세션을 무효화하고 스레드 로컬 변수를 변경하지 않습니다. 2. 우리는 null로 설정하지 않지만 왜 다른 사용자의 로그인 값을 제공합니까? – archangel

답변

1

스레드가 풀링되므로 각 요청에 대해 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(); 
        } 
    } 
    

    그렇지 않으면 일어날 일입니다 과의

  • 사용자 B 로그는 ThreadB (사용자 B가 문맥에)
  • A의 세션 시간 초과되고 더 이상 자신의 세션에 연결된 사용자 정보가 연관되어
  • 사용자 A는 스레드를 사용 B 스레드 B가 다시 사용되기 때문에 UserB가 컨텍스트에 있음을 나타냅니다.)

이 문제는 보안 문제 일뿐만 아니라 메모리 누수입니다. 사용자 당 채워지는 하나의 스레드 당 하나만 더 작아 보이지만 합산 할 수 있습니다. 또한 ThreadLocal에있는 객체가 해당 유형의 클래스 ClassLoader에 속한 객체 인 경우 응용 프로그램 서버를 다시 시작하지 않고 응용 프로그램을 배포 취소/배포 할 때마다 전쟁의 전체 내용을 누설하는 큰 PermGen leak을 갖게됩니다.

@LaurentG는 Spring Security와 함께 사용하는 접근법이 SecurityContextHolder를 사용하는 것이 맞습니다. SecurityContextPersistenceFilter는 finally 블록에 SecurityContext gets cleared out을 보장합니다.

+0

도와 주신 모든 분들께 감사드립니다. 모든 것을 자세히 설명하므로 답변으로 표시하고 있습니다. 이 필터 접근법은 좋은 것처럼 보이며 시도해 볼 것입니다. – archangel