2009-09-14

톰켓 6.0 JSESSIONID 충돌

동일 도메인이나 IP에 포트 번호를 달리해서 여러 개의 자바 애플리케이션 서버를 운영하면 세션 유지를 위해 사용하는 JSESSIONID 쿠키가 충돌한다.

예를 들어 한 사용자가 동일 브라우저에서 이 애플리케이션들을 동시에 사용하면 계속해서 세션이 상실되는 현상이 발생한다.


웹로직같은 경우에는 JSESSIONID 대신에 다른 이름을 사용하도록 변경할 수 있지만 톰켓 5.5에서는 이를 지원하지 않았다. 문제 해결을 위해서 구글링하다가 톰켓 개발자가 쓴 글을 보고 톰켓 코드를 수정해서 사용한 적이 있다.


그런데 톰켓 6.0.20 버전에서는 그 내용이 그대로 반영되어서 코드 수정없이 JSESSIONID 대신에 다른 이름을 사용할 수 있다. (정확하게 톰켓 6.0 어떤 버전부터인지는 모르겠다)


다음 자바 시스템 환경 변수로 JSESSIONID를 수정한다.

-Dorg.apache.catalina.SESSION_COOKIE_NAME=JSESSIONID
-Dorg.apache.catalina.SESSION_PARAMETER_NAME=jsessionid
-Dorg.apache.catalina.authenticator.Constants.SSO_SESSION_COOKIE_NAME=JSESSIONIDSSO

  • 첫번째는 JSESSIONID 쿠키 이름이다.
  • 두번째는 URL Rewriting을 할 때 사용하는 파라미터 이름으로 톰켓에서는 JSESSIONID에 대한 소문자를 사용한다.
  • 세번째는 SSO 처리와 관련된 것으로 보이는데 사용해본 적이 없어서 자세히는 모르겠다.

따라서 위의 값에 대해서 JSESSIONID 대신에 다른 걸 사용하면 세션 충돌을 방지할 수 있다.



동일 도메인에서 서로 다른 자바 애플리케이션 서버가 같은 HTTP 포트 번호를 사용할 수는 없다. 그래서 JSESSIONID + HTTP 포트 번호 조합을 사용하는 것이 가장 바람직하다.


먼저 conf/server.xml 파일을 다음과 같이 수정한다.

<?xml version="1.0" encoding="UTF-8"?>

<Server port="${http.shutdown.port}" shutdown="SHUTDOWN">

  <Service name="Catalina">

    <Connector port="${http.startup.port}" protocol="HTTP/1.1" connectionTimeout="20000"
      redirectPort="8443" URIEncoding="UTF-8"/>

    <!-- 나머지 부분 생략 -->

톰켓 설정 파일에 ${}로 설정하면 자동으로 자바 환경 변수로 치환된다.

  • http.startup.port - HTTP 시작 포트
  • http.shutdown.port - HTTP 종료를 위한 포트

윈도우에서는 bin/catalina.bat 파일 앞부분에 다음 내용을 추가한다.

if "%STARTUP_PORT%" == "" SET STARTUP_PORT=8080
if "%SHUTDOWN_PORT%" == "" SET SHUTDOWN_PORT=8005

set JAVA_OPTS=%JAVA_OPTS%
-Xmx512m
set JAVA_OPTS=%JAVA_OPTS% -Dhttp.startup.port=%STARTUP_PORT%
set JAVA_OPTS=%JAVA_OPTS% -Dhttp.shutdown.port=%SHUTDOWN_PORT%
set JAVA_OPTS=%JAVA_OPTS% -Dorg.apache.catalina.SESSION_COOKIE_NAME=JSESSIONID%STARTUP_PORT%
set JAVA_OPTS=%JAVA_OPTS% -Dorg.apache.catalina.SESSION_PARAMETER_NAME=jsessionid%STARTUP_PORT%
set JAVA_OPTS=%JAVA_OPTS% -Dorg.apache.catalina.authenticator.Constants.SSO_SESSION_COOKIE_NAME=JSESSIONIDSSO%STARTUP_PORT%


* 띄어쓰기 문제로 맨 마지막 줄이 잘려보인다.  =JSESSIONIDSSO%STARTUP_PORT%이 잘려 보이는 것이다.


유닉스/리눅스에서는 bin/catalina.sh 파일 앞부분에 다음 내용을 추가한다.

STARTUP_PORT="${STARTUP_PORT}"
SHUTDOWN_PORT="${SHUTDOWN_PORT}"

if [ "${STARTUP_PORT}" = "" ]
then
    STARTUP_PORT="7900"
fi

if [ "${SHUTDOWN_PORT}" = "" ]
then
    SHUTDOWN_PORT="7999"
fi

JAVA_OPTS="$JAVA_OPTS -Xmx512m"
JAVA_OPTS="$JAVA_OPTS -Dhttp.startup.port=${STARTUP_PORT}"
JAVA_OPTS="$JAVA_OPTS -Dhttp.shutdown.port=${SHUTDOWN_PORT}"
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.SESSION_COOKIE_NAME=JSESSIONID${STARTUP_PORT}"
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.SESSION_PARAMETER_NAME=jsessionid${STARTUP_PORT}"
JAVA_OPTS="$JAVA_OPTS -Dorg.apache.catalina.authenticator.Constants.SSO_SESSION_COOKIE_NAME=JSESSIONIDSSO${STARTUP_PORT}"

* 띄어쓰기가 없어서 맨 마지막 줄이 잘려보인다.  =JSESSIONIDSSO%STARTUP_PORT%이 잘려 보이는 것이다.


이렇게 설정하면 HTTP 포트 번호가 8080일때 JSESSIONID8080이 세션 유지를 위한 쿠키 이름으로 사용된다.

No comments: