spring security - permit all 무시안되는 경우

김가빈·2023년 12월 12일
0

springsecurity

목록 보기
16/23

spring security를 설정하던 중 정적자원이나, swagger관련된 resources들은 필터가 설정되지 않도록 할 필요가 있었다.

처음에 security config에 다음과 같이 설정했으나 적용되지 않았다.

	@Bean
	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
		http
			.authorizeHttpRequests(authorizeRequests ->
				authorizeRequests
					.requestMatchers("/", 
									 "/api/u/v1/social-login",
									 "/api-docs", 
									 "/api-docs/**",
									 "/swagger-ui/**",
									 "/api/u/v1/token",
									 "/error",
									 "/",
									 "/swagger-config",
									 "/swagger.yaml", 
									 "/requestBodies/**",
									 "/swagger-*.yaml"
								).permitAll()
					.requestMatchers(
						"/api/u/v1/user"	
					).hasAnyRole("USER", "MANAGER")
			)
			.csrf(csrf -> {
				csrf.disable();
			})
			.cors(cors -> {
				cors.disable();
			})
			.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class)
			.logout(logout -> logout.logoutSuccessUrl("/").permitAll());
			
		
		return http.build();
	}
	

방법은 websecuritycustomizer를 통해서 ignore설정을 해주는 것

package com.project.bookforeast.common.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.project.bookforeast.common.security.filter.JwtAuthorizationFilter;



@Configuration
@EnableWebSecurity
public class SecurityConfig {
	
	JwtAuthorizationFilter jwtAuthorizationFilter;
	
	
	@Autowired
	public SecurityConfig(JwtAuthorizationFilter jwtAuthorizationFilter) {
		this.jwtAuthorizationFilter = jwtAuthorizationFilter;
	}
	
	@Bean
	SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
		http
			.authorizeHttpRequests(authorizeRequests ->
				authorizeRequests
					.requestMatchers("/", 
									 "/api/u/v1/social-login",
									 "/api-docs", 
									 "/api-docs/**",
									 "/swagger-ui/**",
									 "/api/u/v1/token",
									 "/error",
									 "/",
									 "/swagger-config",
									 "/swagger.yaml", 
									 "/requestBodies/**",
									 "/swagger-*.yaml"
								).permitAll()
					.requestMatchers(
						"/api/u/v1/user"	
					).hasAnyRole("USER", "MANAGER")
			)
			.csrf(csrf -> {
				csrf.disable();
			})
			.cors(cors -> {
				cors.disable();
			})
			.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class)
			.logout(logout -> logout.logoutSuccessUrl("/").permitAll());
			
		
		return http.build();
	}
	

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web.ignoring().requestMatchers(
        											    "/favicon.ico",
        											    "/swagger-ui/**",
        											    "/",
        											    "/swagger-config",
        											    "/swagger.yaml", 
        											    "/requestBodies/**",
        											    "/swagger-*.yaml",
        											    "/error"
        											   );
    }

}

이는 securityFilterchain과 websecuritycustomizer의 차이에서 나오는데 WebSecurityCustomizer에서는 리소스에 대해서 Spring security가 적용되지 않도록 한다. 반면 SecurityFilterchaing의 permitAll의 경우 인증 결과와 상관없이 무조건 통과시키는 역할을 한다.


이 인증정보와 상관없이 무조건 통과시킨다는 부분이 좀 재미있는데, permitAll을 할 때 처음에는 내가 설정한 filter도 안탈꺼라고 생각했다. (인증 하는 부분을 permitAll로 해두었고, 인증과 관련된 내용을 jwtAuthorizationFilter에 설정했기 때문이었다.)


하지만 permitAll과 상관없이 jwtAuthorizationFilter가 돌았고, "/api/u/v1/social-login"와 같이 accessToken을 가지지 않은 엔드포인트에 대해서 에러가 발생했다. 이를 해결하기 위한 방법은 또 필터에 다음과 같이 설정해 주는 것

@Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        String[] excludePath = {
                "/api-docs/json",
                "/api-docs",
                "/api/u/v1/social-login",
                "/swagger-ui/",
                "/swagger-config",
                "/swagger.yaml", 
                "/requestBodies",
                "/swagger-",
                "/error"
        		};
        String path = request.getRequestURI();
        
        System.out.println(path);
        System.out.println(Arrays.toString(excludePath));
        boolean shouldNotFilter = Arrays.stream(excludePath).anyMatch(path::startsWith);
        
        return shouldNotFilter;
    }

excludedPath에 포함되어 있으면 true를 반환하고 해당 필터를 타지 않도록 설정했다.


시큐리티는 할수록 더 어렵다

profile
신입 웹개발자입니다.

0개의 댓글