fix: STT 서비스 인증 제거 및 DTO 역직렬화 문제 해결

- SecurityConfig에서 JWT 인증 제거하여 모든 요청 허용
- RecordingDto에 Jackson 역직렬화를 위한 어노테이션 추가
  - @NoArgsConstructor, @AllArgsConstructor 추가
  - @JsonDeserialize, @JsonPOJOBuilder 추가
- 프론트엔드에서 토큰 없이 API 호출 가능하도록 수정

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Minseo-Jo 2025-10-29 11:30:08 +09:00
parent 92c18f71c0
commit c85845a7ee
2 changed files with 36 additions and 32 deletions

View File

@ -1,8 +1,5 @@
package com.unicorn.hgzero.stt.config; package com.unicorn.hgzero.stt.config;
import com.unicorn.hgzero.common.security.JwtTokenProvider;
import com.unicorn.hgzero.common.security.filter.JwtAuthenticationFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -11,7 +8,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource; import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
@ -20,15 +16,12 @@ import java.util.Arrays;
/** /**
* Spring Security 설정 * Spring Security 설정
* JWT 기반 인증 API 보안 설정 * CORS 설정 API 보안 설정 (인증 없음)
*/ */
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig { public class SecurityConfig {
private final JwtTokenProvider jwtTokenProvider;
@Value("${cors.allowed-origins:http://localhost:3000,http://localhost:8080,http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084}") @Value("${cors.allowed-origins:http://localhost:3000,http://localhost:8080,http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084}")
private String allowedOrigins; private String allowedOrigins;
@ -39,19 +32,9 @@ public class SecurityConfig {
.cors(cors -> cors.configurationSource(corsConfigurationSource())) .cors(cors -> cors.configurationSource(corsConfigurationSource()))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
// Actuator endpoints // 모든 요청 허용 (인증 없음)
.requestMatchers("/actuator/**").permitAll() .anyRequest().permitAll()
// Swagger UI endpoints - context path와 상관없이 접근 가능하도록 설정
.requestMatchers("/swagger-ui/**", "/swagger-ui.html", "/v3/api-docs/**", "/swagger-resources/**", "/webjars/**").permitAll()
// Health check
.requestMatchers("/health").permitAll()
// WebSocket endpoints
.requestMatchers("/ws/**").permitAll()
// All other requests require authentication
.anyRequest().authenticated()
) )
.addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider),
UsernamePasswordAuthenticationFilter.class)
.build(); .build();
} }

View File

@ -1,8 +1,8 @@
package com.unicorn.hgzero.stt.dto; package com.unicorn.hgzero.stt.dto;
import lombok.Builder; import lombok.*;
import lombok.Getter; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.ToString; import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@ -23,6 +23,9 @@ public class RecordingDto {
@Getter @Getter
@Builder @Builder
@ToString @ToString
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@JsonDeserialize(builder = PrepareRequest.PrepareRequestBuilder.class)
public static class PrepareRequest { public static class PrepareRequest {
@NotBlank(message = "회의 ID는 필수입니다") @NotBlank(message = "회의 ID는 필수입니다")
@ -36,6 +39,10 @@ public class RecordingDto {
@Min(value = 1, message = "참석자 수는 1명 이상이어야 합니다") @Min(value = 1, message = "참석자 수는 1명 이상이어야 합니다")
@Max(value = 50, message = "참석자 수는 50명을 초과할 수 없습니다") @Max(value = 50, message = "참석자 수는 50명을 초과할 수 없습니다")
private final Integer attendeeCount; private final Integer attendeeCount;
@JsonPOJOBuilder(withPrefix = "")
public static class PrepareRequestBuilder {
}
} }
/** /**
@ -59,12 +66,19 @@ public class RecordingDto {
@Getter @Getter
@Builder @Builder
@ToString @ToString
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@JsonDeserialize(builder = StartRequest.StartRequestBuilder.class)
public static class StartRequest { public static class StartRequest {
@NotBlank(message = "시작자 ID는 필수입니다") @NotBlank(message = "시작자 ID는 필수입니다")
private final String startedBy; private final String startedBy;
private final String recordingMode; private final String recordingMode;
@JsonPOJOBuilder(withPrefix = "")
public static class StartRequestBuilder {
}
} }
/** /**
@ -73,12 +87,19 @@ public class RecordingDto {
@Getter @Getter
@Builder @Builder
@ToString @ToString
@NoArgsConstructor(access = AccessLevel.PRIVATE, force = true)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@JsonDeserialize(builder = StopRequest.StopRequestBuilder.class)
public static class StopRequest { public static class StopRequest {
@NotBlank(message = "중지자 ID는 필수입니다") @NotBlank(message = "중지자 ID는 필수입니다")
private final String stoppedBy; private final String stoppedBy;
private final String reason; private final String reason;
@JsonPOJOBuilder(withPrefix = "")
public static class StopRequestBuilder {
}
} }
/** /**