Spring Security 6.2.1 버전 기준!

 

1. 어노테이션 추가 (@Configuration, @EnableWebSecurity)

@Configuration
@EnableWebSecurity
public class SecurityConfig {
}

 

@Configuration : 스프링 설정 관련 클래스임을 나타내는 어노테이션

@EnableWebSecurity : SpringSecurity를 활성화해주는 어노테이션, 시큐리티 관련 설정을 커스텀할 수 있게 하는 역할

 

2. SecurityFilterChain 작성 

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

 

스프링 시큐리티는 필터를 기반으로 동작한다. 모든 요청을 시큐리터 필터를 통과하도록 하며, 필터들을 묶어 관리하는 것을 SecurityFilterChain 이라고 함.

 

* 주요 역할: 로그인했는지 확인, 권한이 있는지 확인, CORS, 세션관리 등

 

 

 

3. CSRF(Cross-Site Request Forgery) 비활성화 

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

 

CSRF 공격이란 사용자가 의도하지 않은 요청을 서버가 처리하도록 유도하는 공격이다.
Spring Security는 기본적으로 CSRF 공격을 방어하지만, JWT 방식의 인증 시스템에서는 CSRF 보호가 필요하지 않기 때문에 stateless 상태이고, 따라서 CSRF 보호가 필요 없음.

 

 

 

4. formLogin, httpBasic 비활성화

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

 

JWT 방식으로 인증하기 때문에 일반적 로그인 방식인 폼로그인을 사용하지 않고,

Authorization 헤더에 username과 password를 Base64 인코딩하는 방식인 HTTP Basic도 사용하지 않음.

 

 

 

5. 특정 경로별 접근 권한 설정 

http.authorizeHttpRequests((auth) -> auth
            // 로그인, 메인페이지, 가입페이지는 다 들어갈 수 있게
            .requestMatchers("login", "/", "/join").permitAll()
            // 관리자 페이지는 관리자 권한 가진 사람만
            .requestMatchers("/admin").hasRole("ADMIN")
            // 나머지는 막기
            .anyRequest().authenticated());

 

- permitAll() : 모든 사용자가 로그인하지 않아도 접근가능

- hasRole("권한명") : 특정 권한명을 가진 사용자만 접근 가능

- anyRequest().authenticated() : 위에서 지정한 경로 외에는 모두 로그인해야만 접근 가능

 

 

 

6. 세션 STATELESS 설정

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

 

Spring Security에서는 기본적으로 세션을 생성하여 사용자를 인증하고 관리하나,

 

여기서는JWT 기반 인증 시스템에서는 세션을 사용하지 않고, 토큰을 기반으로 인증하는 방식을 선택.

 

SessionCreationPolicy.STATELESS 설정을 통해 Spring Security가 세션을 생성하지 않도록 설정하여,

 

JWT를 활용한 완전한 무상태(Stateless) 방식의 인증 시스템을 구축할 수 있음

 

 

 

7. 필터체인 반환

return http.build();

 

build() 를 사용해 설정한 시큐리티 필터 체인을 반환한다.

 

 

 

 

8. 비밀번호 암호화 설정

@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}

 

BCryptPasswordEncoder는 Salt 기법을 사용해 같은 비밀번호도 다른 해시 값을 생성하는 암호화 기법을 사용함.

 

 

 

 

전체 코드

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    // 비밀번호를 hash로 암호화하여 검증. 암호화에 사용할 메서드 구현
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws  Exception {
        // csrf disable
        http
                .csrf((auth)  -> auth.disable());
                
        // form 로그인 방식 disable
        http
                .formLogin((auth) -> auth.disable());

        // http basic 인증 방식 disable
        http
                .httpBasic((auth) -> auth.disable());

        // 특정 경로에 인가작업
        http.authorizeHttpRequests((auth) -> auth
                // 로그인, 메인페이지, 가입페이지는 다 들어갈 수 있게
                .requestMatchers("login", "/", "/join").permitAll()
                // 관리자 페이지는 관리자 권한 가진 사람만
                .requestMatchers("/admin").hasRole("ADMIN")
                // 나머지는 막기
                .anyRequest().authenticated());

        // 세션 statless 상태로 설정
        http
                .sessionManagement((session) -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS));


        return http.build();
    }


}