스프링부트 세션 타임아웃 가이드(Spring Security)

안녕하세요! 오늘은 Spring Security와 함께 사용되는 세션 관리 방법, 특히 server.servlet.session.timeout 설정에 대해 자세히 알아보겠습니다. "보안도 챙기고 사용자 경험도 챙기고 싶으신가요?" 이 글에서 그 해답을 찾아보세요!

스프링부트 세션 타임아웃 가이드(Spring Security)스프링부트 세션 타임아웃 가이드(Spring Security)

🌟 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";
    }
}

⚠️ 보안 관련 주의사항

  1. 세션 하이재킹 방지
    • HTTPS 사용 필수
    • 세션 ID를 URL에 노출하지 않기
      server.servlet.session.tracking-modes=cookie
  2. 동시 세션 제어
  3. http.sessionManagement() .maximumSessions(1) .maxSessionsPreventsLogin(true);
  4. 세션 고정 공격 방지
  5. http.sessionManagement() .sessionFixation().changeSessionId();

🚀 실전 팁

  1. 개발 환경별 세션 설정
    # 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의 다양한 세션 관리 기능을 활용하면, 더욱 안전하고 신뢰성 있는 웹 애플리케이션을 구축할 수 있습니다.

더 궁금한 점이 있으시다면 댓글로 남겨주세요! 💬

참고 문서