diff --git a/src/main/java/com/sparta/spring_deep/_delivery/config/WebSecurityConfig.java b/src/main/java/com/sparta/spring_deep/_delivery/config/WebSecurityConfig.java index 9e820c2..6a56633 100644 --- a/src/main/java/com/sparta/spring_deep/_delivery/config/WebSecurityConfig.java +++ b/src/main/java/com/sparta/spring_deep/_delivery/config/WebSecurityConfig.java @@ -5,19 +5,35 @@ import com.sparta.spring_deep._delivery.domain.user.jwt.JwtAuthorizationFilter; import com.sparta.spring_deep._delivery.domain.user.jwt.JwtUtil; import com.sparta.spring_deep._delivery.domain.user.repository.UserRepository; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.ObjectSchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; +import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.responses.ApiResponses; +import java.util.Optional; import lombok.RequiredArgsConstructor; +import org.springdoc.core.customizers.OpenApiCustomizer; import org.springframework.boot.autoconfigure.security.servlet.PathRequest; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; @Configuration @EnableWebSecurity @@ -214,4 +230,50 @@ public JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception { public JwtAuthorizationFilter jwtAuthorizationFilter() { return new JwtAuthorizationFilter(jwtUtil, userDetailsService); } + + @Bean + OpenApiCustomizer springSecurityLoginEndpointCustomizer(ApplicationContext applicationContext) { + FilterChainProxy filterChainProxy = applicationContext.getBean( + AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, FilterChainProxy.class); + return openAPI -> { + for (SecurityFilterChain filterChain : filterChainProxy.getFilterChains()) { + Optional optionalFilter = + filterChain.getFilters().stream() + .filter(UsernamePasswordAuthenticationFilter.class::isInstance) + .map(UsernamePasswordAuthenticationFilter.class::cast) + .findAny(); + if (optionalFilter.isPresent()) { + UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter = optionalFilter.get(); + Operation operation = new Operation(); + Schema schema = new ObjectSchema() + .addProperties(usernamePasswordAuthenticationFilter.getUsernameParameter(), + new StringSchema()._default("username")) + .addProperties(usernamePasswordAuthenticationFilter.getPasswordParameter(), + new StringSchema()._default("password")); + RequestBody requestBody = new RequestBody().content(new Content().addMediaType( + org.springframework.http.MediaType.APPLICATION_JSON_VALUE, + new MediaType().schema(schema))); + operation.requestBody(requestBody); + ApiResponses apiResponses = new ApiResponses(); + apiResponses.addApiResponse(String.valueOf(HttpStatus.OK.value()), + new ApiResponse().description(HttpStatus.OK.getReasonPhrase()) + .content(new Content().addMediaType( + org.springframework.http.MediaType.APPLICATION_JSON_VALUE, + new MediaType().example("{\"token\":\"sample-jwt-token\"}")))); + + apiResponses.addApiResponse(String.valueOf(HttpStatus.UNAUTHORIZED.value()), + new ApiResponse().description(HttpStatus.UNAUTHORIZED.getReasonPhrase()) + .content(new Content().addMediaType( + org.springframework.http.MediaType.APPLICATION_JSON_VALUE, + new MediaType().example("{\"error\":\"UNAUTHORIZED\"}")))); + + operation.responses(apiResponses); + operation.addTagsItem("user-controller"); + + PathItem pathItem = new PathItem().post(operation); + openAPI.getPaths().addPathItem("/api/users/login", pathItem); + } + } + }; + } }