우선 Security를 커스텀하기 위한 Config 파일을 보자.

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SpringSecurityConfig {

	private final OauthUserService oauthUserService;
	private final JwtAuthFilter jwtAuthFilter;
	private final JwtExceptionFilter jwtExceptionFilter;
	private final AuthenticationSuccessHandler oAuth2LoginSuccessHandler;
	private final AuthenticationFailureHandler oAuth2LoginFailureHandler;

	@Bean
	public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		http.csrf(CsrfConfigurer::disable)
			.cors(CorsConfigurer::disable)
			.sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
			.authorizeHttpRequests(auth ->
				auth.requestMatchers("/token/**", "/api-docs", "/swagger-ui/**", "/v3/api-docs/swagger-config",
					"/v3/api-docs"
				).permitAll()
					.anyRequest().authenticated()
			)
			.httpBasic(withDefaults());

		http.oauth2Login(oauth2 -> oauth2
			.redirectionEndpoint(redirection -> redirection.baseUri("/oauth2/callback/**"))
			.userInfoEndpoint(userInfo -> userInfo.userService(oauthUserService))
			.successHandler(oAuth2LoginSuccessHandler)
			.failureHandler(oAuth2LoginFailureHandler));

		return http.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
			.addFilterBefore(jwtExceptionFilter, JwtAuthFilter.class)
			.build();
	}
}
  1. csrf()

해당 옵션은 csrf 토큰이 없는 경우에 요청을 거부한다. 그러나 spring security documentation에 non-browser clients 만을 위한 서비스라면 csrf를 disable 하여도 좋다고 한다.

일반 사용자가 브라우저에서 처리할 수 있는 모든 요청에 CSRF 보호를 사용할 것을 권장합니다.
브라우저를 사용하지않는 클라이언트만 사용하는 서비스를 만드는 경우 CSRF 보호를 비활성화하는 것이 좋습니다.

따라서 Rest API 를 쓰는 서버에서는 disable을 하는게 일반적이다.(사실 아직 잘 이해안감…)

  1. cors()

CORS 규정 생기면 적용하면 될 듯하다.

  1. sessionManagement()

Spring Security Framework에서는 인증된 사용자를 세션(Security에서 사용하는 세션이 있는 듯)에 저장해두고 인증 인가를 진행한다. 그런데 우리 서버의 경우 jwt 토큰을 이용하기 때문에 세션이 필요하지 않다. 따라서 정책을 Stateless하게 가져갔다.

  1. authorizeHttpRequests()

해당 부분은 security의 인가 과정에 포함되거나 되지 않을 uri를 지정하는 부분이다.

.authorizeHttpRequests(auth ->
				auth.requestMatchers("/token/**", "/api-docs", "/swagger-ui/**", "/v3/api-docs/swagger-config",
					"/v3/api-docs"
				).permitAll()
					.anyRequest().authenticated()
			)

우리 서비스의 경우 Swagger와 토큰 발급(혹은 재발급)의 경우 인가과정을 거치지 않게 열어주었다. 나머지 요청에 관해서는 막아두었다. 만약 다른 요청에 대해서도 열고자 한다면 "/user" 와 같이 추가해주면 된다. 참고로 우리는 사용하지 않았지만 hasRole() 과 같은 메서드들이 있다.