권한 테스트 api 수정

This commit is contained in:
2025-12-12 10:02:08 +09:00
parent 79267e82d7
commit 970d08ba44
5 changed files with 74 additions and 59 deletions

View File

@@ -2,8 +2,9 @@ package com.kamco.cd.kamcoback.auth;
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity; import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.List;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
public class CustomUserDetails implements UserDetails { public class CustomUserDetails implements UserDetails {
@@ -16,7 +17,7 @@ public class CustomUserDetails implements UserDetails {
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.emptyList(); return List.of(new SimpleGrantedAuthority("ROLE_" + member.getUserRole()));
} }
@Override @Override

View File

@@ -7,9 +7,9 @@ import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum RoleType implements EnumType { public enum RoleType implements EnumType {
ROLE_ADMIN("관리자"), ADMIN("관리자"),
ROLE_LABELER("라벨러"), LABELER("라벨러"),
ROLE_REVIEWER("검수자"); REVIEWER("검수자");
private final String desc; private final String desc;

View File

@@ -30,33 +30,46 @@ public class SecurityConfig {
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.cors(cors -> cors.configurationSource(corsConfigurationSource())) http.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화 .csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화
.sessionManagement( .sessionManagement(
sm -> sm ->
sm.sessionCreationPolicy( sm.sessionCreationPolicy(
SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증 SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증
.formLogin(form -> form.disable()) // react에서 로그인 요청 관리 .formLogin(form -> form.disable()) // react에서 로그인 요청 관리
.httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용 .httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용
.logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음 .logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음
.authenticationProvider( .authenticationProvider(
customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용 customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용
.authorizeHttpRequests( .authorizeHttpRequests(
auth -> auth ->
auth.requestMatchers(HttpMethod.OPTIONS, "/**") auth
.permitAll() // preflight 허용 // ADMIN만 접근
.requestMatchers( .requestMatchers("/api/test/admin")
"/api/auth/signin", .hasRole("ADMIN")
"/api/auth/refresh",
"/swagger-ui/**", // ADMIN, LABELER 접근
"/api/members/{memberId}/password", .requestMatchers("/api/test/label")
"/v3/api-docs/**") .hasAnyRole("ADMIN", "LABELER")
.permitAll()
.anyRequest() // ADMIN, REVIEWER 접근
.authenticated()) .requestMatchers("/api/test/review")
.addFilterBefore( .hasAnyRole("ADMIN", "REVIEWER")
jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter .requestMatchers(HttpMethod.OPTIONS, "/**")
.class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장. .permitAll() // preflight 허용
.requestMatchers(
"/api/auth/signin",
"/api/auth/refresh",
"/swagger-ui/**",
"/api/members/*/password",
"/v3/api-docs/**")
.permitAll()
.anyRequest()
.authenticated())
.addFilterBefore(
jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter
.class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장.
; ;
return http.build(); return http.build();
@@ -64,7 +77,7 @@ public class SecurityConfig {
@Bean @Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration)
throws Exception { throws Exception {
return configuration.getAuthenticationManager(); return configuration.getAuthenticationManager();
} }

View File

@@ -88,7 +88,7 @@ public class MembersDto {
public static class SearchReq { public static class SearchReq {
@Schema( @Schema(
description = "전체, 관리자(ROLE_ADMIN), 라벨러(ROLE_LABELER), 검수자(ROLE_REVIEWER)", description = "전체, 관리자(ADMIN), 라벨러(LABELER), 검수자(REVIEWER)",
example = "") example = "")
private String userRole; private String userRole;
@@ -111,7 +111,7 @@ public class MembersDto {
@Setter @Setter
public static class AddReq { public static class AddReq {
@Schema(description = "관리자 유형", example = "ROLE_ADMIN") @Schema(description = "관리자 유형", example = "ADMIN")
@NotBlank @NotBlank
@Size(max = 50) @Size(max = 50)
private String userRole; private String userRole;

View File

@@ -1,5 +1,6 @@
package com.kamco.cd.kamcoback.test; package com.kamco.cd.kamcoback.test;
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
@@ -21,48 +22,48 @@ public class TestApiController {
@Operation(summary = "admin test", description = "admin test api") @Operation(summary = "admin test", description = "admin test api")
@ApiResponses({ @ApiResponses({
@ApiResponse( @ApiResponse(
responseCode = "200", responseCode = "200",
description = "조회", description = "조회",
content = @Content(schema = @Schema(implementation = String.class))), content = @Content(schema = @Schema(implementation = String.class))),
@ApiResponse( @ApiResponse(
responseCode = "403", responseCode = "403",
description = "권한 없음", description = "권한 없음",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))) content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
}) })
@GetMapping("/admin") @GetMapping("/admin")
public String admin() { public ApiResponseDto<String> admin() {
return "I am administrator"; return ApiResponseDto.ok("I am administrator");
} }
@Operation(summary = "label test", description = "label test api") @Operation(summary = "label test", description = "label test api")
@ApiResponses({ @ApiResponses({
@ApiResponse( @ApiResponse(
responseCode = "200", responseCode = "200",
description = "조회", description = "조회",
content = @Content(schema = @Schema(implementation = String.class))), content = @Content(schema = @Schema(implementation = String.class))),
@ApiResponse( @ApiResponse(
responseCode = "403", responseCode = "403",
description = "권한 없음", description = "권한 없음",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))) content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
}) })
@GetMapping("/label") @GetMapping("/label")
public String label() { public ApiResponseDto<String> label() {
return "Labeling is available."; return ApiResponseDto.ok("Labeling is available.");
} }
@Operation(summary = "review test", description = "review test api") @Operation(summary = "review test", description = "review test api")
@ApiResponses({ @ApiResponses({
@ApiResponse( @ApiResponse(
responseCode = "200", responseCode = "200",
description = "조회", description = "조회",
content = @Content(schema = @Schema(implementation = String.class))), content = @Content(schema = @Schema(implementation = String.class))),
@ApiResponse( @ApiResponse(
responseCode = "403", responseCode = "403",
description = "권한 없음", description = "권한 없음",
content = @Content(schema = @Schema(implementation = ErrorResponse.class))) content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
}) })
@GetMapping("/review") @GetMapping("/review")
public String review() { public ApiResponseDto<String> review() {
return "Review is available."; return ApiResponseDto.ok("Review is available.");
} }
} }