[JWT] JWT를 위한 시큐리티 설정

devkwon·2024년 1월 18일

SecurityConfig 설정

@Configuration
@EnableWebSecurity //스프링 시큐리티 필터(SecurityConfig)가 스프링 필터체인에 등록됨.
public class SecurityConfig {
    // 스프링 부트 2.7.0 이상부턴 WebSecurityConfigurerAdapter가 deprecated됨.
    // 아예 자체적으로 SecurityFilterChain Bean을 생성하는 방식으로 바뀌었다.

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

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
                .csrf(AbstractHttpConfigurer::disable)
                .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 세션을 stateless로 관리
                .httpBasic(AbstractHttpConfigurer::disable) // 기본적인 로그인 기능 사용 x
                .formLogin(AbstractHttpConfigurer::disable)
                // 특정 URL에 대한 권한 설정.
                .authorizeHttpRequests((authorizeRequests) -> {
                    authorizeRequests.requestMatchers("/api/v1/user/**").hasAnyRole("ADMIN", "MANAGER","USER");

                    authorizeRequests.requestMatchers("/api/v1/manager/**")
                            .hasAnyRole("ADMIN", "MANAGER");

                    authorizeRequests.requestMatchers("/api/v1/admin/**")
                            .hasRole("ADMIN");

                    authorizeRequests.anyRequest().permitAll();
                })


                .build();
    }
}

httpBasic(AbstractHttpConfigurer::disable)

클라이언트 서버 방식은 원래 stateless기 때문에 상태를 가지지 않음.
하지만 세션이나 쿠키를 통해 stateful처럼 사용할 수 있다.

httpBasic(AbstractHttpConfigurer::disable)은 해당 방식을 사용하지 않겠다는 것이다.

.formLogin(AbstractHttpConfigurer::disable)

form 방식의 로그인을 하지 않겠다는 것을 의미한다.

cors 설정

@CrossOrigin 어노테이션은 인증이 필요한 부분에서는 동작하지 않음.
따라서 필터를 만들고 등록해서 cors 설정을 해줘야함.

filterChain에 추가

.cors((cors)->{
                    CorsConfiguration config = new CorsConfiguration();
                    config.setAllowedOrigins(List.of("*")); // 모든 ip에 응답을 허용
                    config.setAllowedHeaders(List.of("*")); // 모든 header에 대해 응답을 허용
                    config.setAllowedMethods(List.of("*"));// 모든 http method에 대해 허용
                    config.setAllowCredentials(true);// 내 서버가 응답을 할 때 json을 자바스크립트에서 처리할 수 있게 할지 설정
                    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                    source.registerCorsConfiguration("/api/**",config);
                    cors.configurationSource(source);
                })

필터 등록

필터 생성

public class MYFilter1 implements Filter {


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("filter 1");
        chain.doFilter(request,response);

    }
}

필터를 만들고 SecurityFilterChain에 등록

filterChain에 필터 등록

.addFilterBefore(new MYFilter1(),BasicAuthenticationFilter.class)

FilterConfig를 만들고 등록

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MYFilter1> filter1(){
        FilterRegistrationBean<MYFilter1> bean = new FilterRegistrationBean<>(new MYFilter1());
        bean.addUrlPatterns("/*");
        bean.setOrder(0); // 낮은 번호가 우선순위가 높음
        return bean;
    }

    @Bean
    public FilterRegistrationBean<MYFilter2> filter2(){
        FilterRegistrationBean<MYFilter2> bean = new FilterRegistrationBean<>(new MYFilter2());
        bean.addUrlPatterns("/*");
        bean.setOrder(1); 
        return bean;
    }
}

우선순위대로 나오는 것을 확인할 수 있다.

SecurityFilter vs SpringFilter

FilterChain에 필터3를 걸어보자

FilterChain이 먼저 나오는 것을 확인할 수 있다.

즉, SecurityFilter가 SpringFilter보다 먼저 실행된다.

만약 가장 먼저 실행되고 싶다면,가장 먼저 실행되는 필터인 SecurityContextPersistenceFilter에 걸면 된다.

0개의 댓글