Swagger와 Spring Security 충돌 해결하기

peace w·2024년 11월 20일

API 명세서를 일일히 작성하기 번거로워서 Swagger를 통해서 API 명세서를 작성하고 있었다.

Swagger 사용방법에 대해서는 추후에 정리할 예정이다.

Spring Security

프로젝트에서 카카오 Oauth를 통해 회원 로그인을 구현하기 위해 oauth 의존성을 build.gradle에 추가해주었다.

// oauth
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-security")
testImplementation("org.springframework.security:spring-security-test")

application.yml에도 정보를 추가해주었다.

spring:
	security:
    	oauth2:
        	client:
            	registration:
                	kakao:
                    	clientId: '{카카오 client-id}'
            			clientSecret: '{카카오 client-secret}'
            			client-authentication-method: post
            			authorization-grant-type: authorization_code
            			redirect-uri: "{url}"
            			## 서버에서 인증을 마치고 돌아가는 callback uri
            			scope:
              				- account_email
            			client-name: Kakao
        		provider:
          			kakao:
            			authorization-uri: https://kauth.kakao.com/oauth/authorize
            			token-uri: https://kauth.kakao.com/oauth/token
            			user-info-uri: https://kapi.kakao.com/v2/user/me
            			user-name-attribute: id

문제

당시, 서버와 로컬 두 곳에서 프로젝트를 돌리고 있었고 로컬에서 spring security 추가 이후에 실행이 잘 되는 것을 확인하고 서버에서도 똑같이 실행했다.
(로컬에서는 swagger를 쓰지 않았다.)

서버에서도 문제 없이 api가 응답하는 것을 확인했고 swagger api문서를 들어갔는데 swagger api failed to load remote configuration. 라고 뜨면서 페이지가 로딩이 안 됐다...

해결방안

원인을 찾는 것은 어렵지 않았다. spring security 설정 시, 환경설정을 구성하기 위해 작성하는 SecurityConfig에서 requestMatchers()로 swagger에 관한 보안설정도 지정해줘야한다. 설정하지 않은 url 요청은 전부 거부된다.

requestMathcers()"/swagger-ui/**", "/v3/api-docs/**" 를 추가했다. swagger api failed to load remote configuration. 는 사라졌으나 swagger 페이지가 무한 로딩되는 상황에 빠졌다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable);

        http.authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/swagger", "/swagger-ui.html", "/swagger-ui/**", "/api-docs", "/api-docs/**", "/v3/api-docs/**").permitAll()
                .requestMatchers("/api/**").permitAll()
                .anyRequest().authenticated());

        http.oauth2Login(Customizer.withDefaults());

        return http.build();
    }
}

맨 위에는 swagger와 관련된 url을 전부 허용해주고,
그 아래에 프로젝트 내에서 사용하는 api url을 분리하여 허용해주었다.

그렇게 하니 swagger api 문서가 잘 보였다!
spring security 사용 시에는 보안 설정을 꼼꼼히 해야겠다는 생각이 들었다.

profile
더 성장하자.

0개의 댓글