이전에 진행했던 팀 프로젝트를 살펴보던 중, 협업 툴로 Swagger를 사용했던 프로젝트가 있었습니다.
그런데 Spring 버전이 3가 넘어가면서, 이전에 했던 설정으로는 Swagger를 사용할 수 없더라구요.
그래서 오늘은 Spring 3.x 버전에서 어떻게하면 Swagger를 사용할 수 있는지 살펴보도록 하겠습니다.
변경된 Swagger 설정 방식은 다음의 Swagger 공식 문서를 참고하였습니다.
https://www.bezkoder.com/spring-boot-swagger-3/
이전에 Swagger를 사용하기 위해서는
implementation 'io.springfox:springfox-boot-starter:3.0.0'
다음의 의존성을 사용했지만, 변경된 의존성은 다음과 같습니다.
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
따라서, 기존에 springfox를 사용하시던 분들은 이전 의존성을 제거하시고, 새로운 의존성을 추가해주셔야 Spring 3.x 버전에서 Swagger를 사용하실 수 있습니다.
사실 의존성을 추가한 뒤, /swagger-ui/index.html에 접근하여 Swagger 문서를 사용할 수 있지만, 저는 프로젝트에서 인증 방식으로 Spring Security + JWT를 활용하고 있기 때문에 다음처럼 추가 설정을 해주었습니다.
import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@Configuration
@OpenAPIDefinition(
info = @Info(
title = "index 페이지에 들어갈 제목",
description = "index 페이지에 들어갈 내용"
)
)
public class SwaggerConfig {
@Bean
public OpenAPI openAPI() {
SecurityScheme securityScheme = getSecurityScheme();
SecurityRequirement securityRequirement = getSecurityRequireMent();
return new OpenAPI()
.components(new Components().addSecuritySchemes("bearerAuth", securityScheme))
.security(List.of(securityRequirement));
}
private SecurityScheme getSecurityScheme() {
return new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")
.in(SecurityScheme.In.HEADER).name("Authorization");
}
private SecurityRequirement getSecurityRequireMent() {
return new SecurityRequirement().addList("bearerAuth");
}
}
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
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.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import umc.precending.config.jwt.*;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtAuthenticationEntryPointHandler authenticationEntryPointHandler;
private final JwtAccessDeniedHandler accessDeniedHandler;
private final TokenProvider tokenProvider;
private final String[] swaggerPath = {"/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**", "/error"};
private final String AUTH_PATH = "/api/auth/**";
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
http.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.exceptionHandling(
security -> security
.authenticationEntryPoint(authenticationEntryPointHandler)
.accessDeniedHandler(accessDeniedHandler))
.sessionManagement(
security -> security
.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(
security -> security
.requestMatchers(HttpMethod.POST, AUTH_PATH).permitAll()
.requestMatchers(swaggerPath).permitAll()
.anyRequest().authenticated())
.apply(new JwtSecurityConfig(tokenProvider));
return http.build();
}
}
Spring Security는 버전이 변경됨에 따라서 람다식을 권장하고 있기 때문에 다음처럼 람다식을 사용하였습니다.

그럼 다음처럼 이전에 사용했던 Swagger UI를 확인할 수 있습니다.
의존성을 변경함에 따라, 이전에 사용했던 수많은 어노테이션들이 먹통이 되었을 것입니다.
저 또한 의존성을 변경하니까 자주 사용하던 @ApiOperation, @ApiImplicitParam, @ApiModelProperty와 같은 어노테이션들에서 빨간줄이 떴습니다.
이러한 어노테이션들은 다음으로 변경하여 사용할 수 있습니다.
@Tag -> Swagger에서 Controller에 대한 설명 추가 가능

@Operation -> 기존 @ApiOperation과 동일한 기능 수행

@Schema -> 기존 @ApiModelProperty와 동일한 기능 수행
