이 가이드는 어떻게 스프링 세션을 스프링 시큐리티와 함께 사용하는지 설명할 것이다. 당신의 어플리케이션에 스프링 시큐리티를 이미 적용했다는 가정하에 진행된다.
완전한 가이드는 다음의 시큐리티 샘플 어플리케이션링크에서 확인할 수 있다. |
의존성 업데이트 하기 Updating Dependencies
스프링 세션을 사용하기전, 의존성 업데이트를 해야한다. 메이븐을 쓴다면 다음의 의존성을 추가해주자:
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.0.2.RELEASE</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
</dependencies>
스프링 설정 Spring Configuration
필수 의존성을 추가하면 스프링 설정을 생성할 수 있다. 스프링 설정으로 Servlet 필터를 만들어 HttpSession
구현체를 스프링 세션의 엄호하에 사용되는 구현체로 바꿔줘야한다. 다음의 스프링 설정을 추가하자:
@Configuration
@EnableRedisHttpSession 1
public class Config {
@Bean
public JedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory(); 2
}
}
1 | @EnableRedisHttpSession 어노테이션은 Filter를 구현한 |
2 | 스프링 세션을 레디스 서버에 연결하는 RedisConnectionFactory를 만들었다. |
서블릿 컨테이너 초기화 Servlet Container Initialization
우리는 스프링 설정으로 Filter
를 구현한 springSessionRepositoryFilter
라는 이름의 스프링 빈을 만들어 스프링 세션에 엄호하에 사용되는 커스텀 구현체로 HttpSession
을 대체하는데 쓴다.
우리의 Filter
를 동작하게 하기 위해, 스프링은 우리가 설정한 Config
클래스를 불러와야한다. 어플리케이션이 이미 스프링 설정을 SecurityInitializer
클래스를 통해 실행되고 있기때문에 간단히 다음의 Config 클래스를 추가해주면된다:
public class SecurityInitializer extends
AbstractSecurityWebApplicationInitializer {
public SecurityInitializer() {
super(SecurityConfig.class, Config.class);
}
}
마지막으로 서블릿 컨테이너 (톰캣같은)가 모든 요청에 우리의springSessionRepositoryFilter
를 사용하게 만들야한다. 스프링세션의 springSessionRepositoryFilter
가 스프링 시큐리티의 springSecurityFilterChain
이 불러지기전에 호출되어야한다는 것은 극도로 중요하다. 스프링 시큐리티에서 사용하는 HttpSession
은 반드시 스프링 세션의 엄호하에 있어야 한다. 다행스럽게도 스프링 세션은 이것을 극도로 쉽게 만들어주는 AbstractHttpSessionApplicationInitializer 이라는 유틸리티 클래스를 제공해준다. 밑의 예제를 보자:
public class Initializer extends AbstractHttpSessionApplicationInitializer {
}
클래스 이름 (Initializer)은 무엇이되도 상관없다. 중요한 것은 우리가 |
AbstractHttpSessionApplicationInitializer
를 확장함으로서, springSessionRepositoryFilter라는 이름의 스프링 빈이 스프링 시큐리티의 Security’sspringSecurityFilterChain
이전에 모든 요청을 처리하도록 서블릿 컨테이너와 함께 등록될 것이다.
시큐리티 샘플 어플리케이션 security Sample Application
시큐리티 샘플 어플리케이션 실행하기 Running the security Sample Application
소스 코드를 받아서 다음의 명령어를 호출함으로서 샘플을 실행할 수 있다:
샘플을 동작하려면 먼저 localhost에 레디스 2.8 또는 그 이후버전을 인스톨하고 기본 포트(6379)로 실행하자. 설치 설정이 다르면 |
$ ./gradlew :samples:security:tomcatRun
이제 http://localhost:8080/를 통해 어플리케이션에 접근할 수 있다.
시큐리티 샘플 어플리케이션 둘러보기 Exploring the security Sample Application
어플리케이션을 사용해보자. 다음의 로그인 정보를 입력하자:
Username user
Password password
Login 버튼을 누르면, 방금 입력한 사용자로 로그인됬다로 알려주는 메세지를 볼수 있다. 이 사용자 정보는 톰캣의 HttpSession
구현체가 아닌 레디스에 저장되어있다.
어떻게 동작하는가? How does it work?
톰캣의 HttpSession
대신, 우리는 실제 레디스에 값을 저장하고 있다. 스프링 세션은 레디스의 엄호하에 있는 구현체로 HttpSession
을 대체한다. 스프링 시큐리티의SecurityContextPersistenceFilter
가 SecurityContext
를 HttpSession
에 저장할때, 이는 레디스안에 저장된다.
새로운 HttpSession
이 만들어질때, 스프링 세션은 사용자의 브라우저에 사용자의 세션ID를 가지고 있는 SESSION이라는 쿠키를 만든다. 계속 진행해서 쿠키를 둘러보자. (크롬이나 파이어폭스에서 쿠키값을 확인해볼수 있다)
redis-cli를 쓰면 세션값을 언제든지 레디스에서 손쉽게 삭제할 수 있다.예를 들면 리눅스 기반의 시스템에서는 다음과 같이 타입하면된다:
$ redis-cli keys '*' | xargs redis-cli del
redis-cli 설치는 레디스 문서를 참고하자. |
또는, 명시적인 키explicit key값을 삭제해도 된다. 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
의 값을 가지는 세션 쿠키를 삭제하려면 다음을 터미널에 타입하자:
$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
이제 다시 http://localhost:8080/ 를 방문해보면 더이상 인증되어있지 않은 걸 확인할 수 있다.