안녕하세요! 오늘은 Spring Security와 함께 사용되는 세션 관리 방법, 특히 server.servlet.session.timeout
설정에 대해 자세히 알아보겠습니다. "보안도 챙기고 사용자 경험도 챙기고 싶으신가요?" 이 글에서 그 해답을 찾아보세요!
🌟 Spring Security와 세션의 관계
Spring Security는 기본적으로 세션 기반 인증을 사용합니다. 사용자가 로그인하면 Spring Security는 SecurityContext
를 세션에 저장하고, 이를 통해 사용자의 인증 정보를 유지합니다.
주요 개념
- SecurityContext: 현재 인증된 사용자의 정보를 담고 있는 컨테이너
- SecurityContextHolder: SecurityContext를 저장하고 접근하는 방법을 제공
- HttpSession: 실제 세션을 관리하는 객체
🔧 세션 타임아웃 설정 방법
1. application.properties 설정
# 세션 타임아웃 설정
server.servlet.session.timeout=30m
# 세션 쿠키 설정
server.servlet.session.cookie.name=SESSIONID
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
2. Spring Security 설정
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.maximumSessions(1) // 동시 세션 제한
.maxSessionsPreventsLogin(true) // 새 로그인 차단
.expiredUrl("/login?expired") // 세션 만료시 리다이렉트
.and()
.invalidSessionUrl("/login?invalid") // 유효하지 않은 세션
.and()
.sessionFixation().newSession(); // 세션 고정 공격 방지
}
}
🎯 실제 활용 예시
1. 기본적인 보안 설정이 필요한 웹 서비스
@Configuration
public class BasicSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("/login")
.maximumSessions(1);
}
}
2. 금융 서비스를 위한 엄격한 보안 설정
@Configuration
public class StrictSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.expiredUrl("/login?expired")
.and()
.sessionFixation().migrateSession()
.and()
.requiresChannel()
.anyRequest().requiresSecure();
// 세션 이벤트 리스너 설정
http.addListener(new HttpSessionEventPublisher());
}
}
💡 세션 관련 주요 기능 구현
1. 세션 이벤트 리스너
@Component
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
logger.info("New session created: " + se.getSession().getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
logger.info("Session destroyed: " + se.getSession().getId());
}
}
2. 커스텀 세션 만료 처리
@Controller
public class SessionController {
@GetMapping("/session-expired")
public String handleSessionExpired(Model model) {
model.addAttribute("message", "세션이 만료되었습니다. 다시 로그인해주세요.");
return "login";
}
}
⚠️ 보안 관련 주의사항
- 세션 하이재킹 방지
- HTTPS 사용 필수
- 세션 ID를 URL에 노출하지 않기
server.servlet.session.tracking-modes=cookie
- 동시 세션 제어
http.sessionManagement() .maximumSessions(1) .maxSessionsPreventsLogin(true);
- 세션 고정 공격 방지
http.sessionManagement() .sessionFixation().changeSessionId();
🚀 실전 팁
- 개발 환경별 세션 설정
# application-dev.properties server.servlet.session.timeout=1h security.session.maximum-concurrent-sessions=2
application-prod.properties
server.servlet.session.timeout=30m
security.session.maximum-concurrent-sessions=1
2. **Remember Me 기능 구현**
```java
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe()
.key("uniqueAndSecret")
.tokenValiditySeconds(86400); // 24시간
}
}
📝 마무리
Spring Security와 세션 관리는 떼려야 뗄 수 없는 관계입니다. 적절한 세션 관리는 보안과 사용자 경험 모두에 큰 영향을 미치므로, 서비스의 특성에 맞게 잘 설정하는 것이 중요합니다.
특히 Spring Security의 다양한 세션 관리 기능을 활용하면, 더욱 안전하고 신뢰성 있는 웹 애플리케이션을 구축할 수 있습니다.
더 궁금한 점이 있으시다면 댓글로 남겨주세요! 💬