Framework/Spring

[Spring] Security 설정 클래스 생성(세션 Stateless)

JM Lee 2024. 4. 17. 03:00
728x90

일반적으로 아래 파일은 config 패키지 안에 생성하여 관리한다.

JWT 환경에서 스프링 시큐리티를 실습하기 위해 간단히 보안 config를 설정했다. 

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {

        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {


        http
                .csrf((auth) -> auth.disable());

        http
                .formLogin((auth) -> auth.disable());

        http
                .httpBasic((auth) -> auth.disable());

        http
                .authorizeHttpRequests((auth) -> auth
                        .antMatchers("/login", "/", "/join").permitAll()
                        .anyRequest().authenticated());

				//필터 추가 LoginFilter()는 인자를 받음 (AuthenticationManager() 메소드에 authenticationConfiguration 객체를 넣어야 함) 따라서 등록 필요
        http
                .addFilterAt(new LoginFilter(), UsernamePasswordAuthenticationFilter.class);

        http
                .sessionManagement((session) -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS));

        return http.build();
    }
}

 

첫 코드는 비밀번호를 해싱하는 함수다.

 

이어서 각 HTTP 설정 별로 설정 근거가 있다.

1. CSRF 비활성화 : 세션이 항상 고정되기 때문에 CSRF 공격에 필수적으로 방어하게 된다. 그러나 JWT는 세션을 Stateless 상태로 두기 때문에 방어하지 않아도 되어서 disable 상태로 만든다.

2, 3. JWT 방식으로 로그인 등을 하므로 Form 로그인 방식과 HTTP Basic 로그인 방식을 비활성화한다.

4. 경로 별 인가 작업을 수행한다. authorizeHttpRequests 함수를 Lambda 형식으로 구현한다.

5. 로그인 필터를 설정한다.

6. 세션 매니지먼트를 Stateless 상태로 설정한다. (매우 중요)

 

그런 다음 HTTP를 빌드하면 JWT 환경에 맞는 스프링 시큐리티가 설정된다.

 

 

6번을 강조하고 또 강조하는 이유는 stateless 개념만 이해해도 어렵지 않다. 풀어서 정리하면 아래와 같다.

  1. 보안성: stateless한 세션은 서버가 클라이언트의 상태를 기억하지 않으므로, 세션 하이재킹(세션을 탈취하여 다른 사용자로 위장하는 공격)과 관련된 위험을 줄일 수 있다. 각 요청은 인증 토큰을 포함하고 있으며, 이 토큰은 클라이언트의 상태를 서버에 저장하는 대신, 각 요청에서 검증된다.
  2. 확장성과 성능: stateless한 아키텍처는 서버의 확장성과 성능을 향상시킬 수 있다. 서버가 클라이언트의 상태를 저장할 필요가 없으므로, 서버 간의 상태 공유 문제가 사라지게 된다. 이는 수평 확장이 가능하고, 요청을 처리하는 데 필요한 리소스를 줄여주어 전반적인 성능을 향상시킨다.
  3. 클라이언트 독립성: stateless한 세션은 클라이언트가 서버와의 통신을 더 자유롭게 제어할 수 있도록 한다. 클라이언트가 특정 서버에 종속되지 않고 로드 밸런서 등을 통해 여러 서버에 요청을 분산시킬 수 있다.
  4. 캐싱과 캐시 효율성: stateless한 아키텍처는 캐싱을 효율적으로 사용할 수 있다. 클라이언트의 상태가 없으므로, 응답을 캐싱하여 동일한 요청에 대한 처리 속도를 높일 수 있다.

 

Stateless : 서버에서 HTTP와 같은 클라이언트의 이전 상태를 기록하지 않는 접속!!