diff --git a/src/main/java/com/kamco/cd/kamcoback/auth/CustomUserDetails.java b/src/main/java/com/kamco/cd/kamcoback/auth/CustomUserDetails.java index 8efb073a..54802e13 100644 --- a/src/main/java/com/kamco/cd/kamcoback/auth/CustomUserDetails.java +++ b/src/main/java/com/kamco/cd/kamcoback/auth/CustomUserDetails.java @@ -2,8 +2,9 @@ package com.kamco.cd.kamcoback.auth; import com.kamco.cd.kamcoback.postgres.entity.MemberEntity; import java.util.Collection; -import java.util.Collections; +import java.util.List; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; public class CustomUserDetails implements UserDetails { @@ -16,7 +17,7 @@ public class CustomUserDetails implements UserDetails { @Override public Collection getAuthorities() { - return Collections.emptyList(); + return List.of(new SimpleGrantedAuthority("ROLE_" + member.getUserRole())); } @Override diff --git a/src/main/java/com/kamco/cd/kamcoback/common/enums/RoleType.java b/src/main/java/com/kamco/cd/kamcoback/common/enums/RoleType.java index 58d0c15e..1aeb0269 100644 --- a/src/main/java/com/kamco/cd/kamcoback/common/enums/RoleType.java +++ b/src/main/java/com/kamco/cd/kamcoback/common/enums/RoleType.java @@ -7,9 +7,9 @@ import lombok.Getter; @Getter @AllArgsConstructor public enum RoleType implements EnumType { - ROLE_ADMIN("관리자"), - ROLE_LABELER("라벨러"), - ROLE_REVIEWER("검수자"); + ADMIN("관리자"), + LABELER("라벨러"), + REVIEWER("검수자"); private final String desc; diff --git a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java index 2fecb1cd..ccd51586 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/SecurityConfig.java @@ -30,33 +30,46 @@ public class SecurityConfig { public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.cors(cors -> cors.configurationSource(corsConfigurationSource())) - .csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화 - .sessionManagement( - sm -> - sm.sessionCreationPolicy( - SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증 - .formLogin(form -> form.disable()) // react에서 로그인 요청 관리 - .httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용 - .logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음 - .authenticationProvider( - customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용 - .authorizeHttpRequests( - auth -> - auth.requestMatchers(HttpMethod.OPTIONS, "/**") - .permitAll() // preflight 허용 - .requestMatchers( - "/api/auth/signin", - "/api/auth/refresh", - "/swagger-ui/**", - "/api/members/{memberId}/password", - "/v3/api-docs/**") - .permitAll() - .anyRequest() - .authenticated()) - .addFilterBefore( - jwtAuthenticationFilter, - UsernamePasswordAuthenticationFilter - .class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장. + .csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화 + .sessionManagement( + sm -> + sm.sessionCreationPolicy( + SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증 + .formLogin(form -> form.disable()) // react에서 로그인 요청 관리 + .httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용 + .logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음 + .authenticationProvider( + customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용 + .authorizeHttpRequests( + auth -> + auth + // ADMIN만 접근 + .requestMatchers("/api/test/admin") + .hasRole("ADMIN") + + // ADMIN, LABELER 접근 + .requestMatchers("/api/test/label") + .hasAnyRole("ADMIN", "LABELER") + + // ADMIN, REVIEWER 접근 + .requestMatchers("/api/test/review") + .hasAnyRole("ADMIN", "REVIEWER") + + .requestMatchers(HttpMethod.OPTIONS, "/**") + .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(); @@ -64,7 +77,7 @@ public class SecurityConfig { @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) - throws Exception { + throws Exception { return configuration.getAuthenticationManager(); } diff --git a/src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java b/src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java index 1142fa6b..c5d3af36 100644 --- a/src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java +++ b/src/main/java/com/kamco/cd/kamcoback/members/dto/MembersDto.java @@ -88,7 +88,7 @@ public class MembersDto { public static class SearchReq { @Schema( - description = "전체, 관리자(ROLE_ADMIN), 라벨러(ROLE_LABELER), 검수자(ROLE_REVIEWER)", + description = "전체, 관리자(ADMIN), 라벨러(LABELER), 검수자(REVIEWER)", example = "") private String userRole; @@ -111,7 +111,7 @@ public class MembersDto { @Setter public static class AddReq { - @Schema(description = "관리자 유형", example = "ROLE_ADMIN") + @Schema(description = "관리자 유형", example = "ADMIN") @NotBlank @Size(max = 50) private String userRole; diff --git a/src/main/java/com/kamco/cd/kamcoback/test/TestApiController.java b/src/main/java/com/kamco/cd/kamcoback/test/TestApiController.java index ca2dfe53..2e843964 100644 --- a/src/main/java/com/kamco/cd/kamcoback/test/TestApiController.java +++ b/src/main/java/com/kamco/cd/kamcoback/test/TestApiController.java @@ -1,5 +1,6 @@ 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.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -21,48 +22,48 @@ public class TestApiController { @Operation(summary = "admin test", description = "admin test api") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "조회", - content = @Content(schema = @Schema(implementation = String.class))), + responseCode = "200", + description = "조회", + content = @Content(schema = @Schema(implementation = String.class))), @ApiResponse( - responseCode = "403", - description = "권한 없음", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + responseCode = "403", + description = "권한 없음", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) @GetMapping("/admin") - public String admin() { - return "I am administrator"; + public ApiResponseDto admin() { + return ApiResponseDto.ok("I am administrator"); } @Operation(summary = "label test", description = "label test api") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "조회", - content = @Content(schema = @Schema(implementation = String.class))), + responseCode = "200", + description = "조회", + content = @Content(schema = @Schema(implementation = String.class))), @ApiResponse( - responseCode = "403", - description = "권한 없음", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + responseCode = "403", + description = "권한 없음", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) @GetMapping("/label") - public String label() { - return "Labeling is available."; + public ApiResponseDto label() { + return ApiResponseDto.ok("Labeling is available."); } @Operation(summary = "review test", description = "review test api") @ApiResponses({ @ApiResponse( - responseCode = "200", - description = "조회", - content = @Content(schema = @Schema(implementation = String.class))), + responseCode = "200", + description = "조회", + content = @Content(schema = @Schema(implementation = String.class))), @ApiResponse( - responseCode = "403", - description = "권한 없음", - content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + responseCode = "403", + description = "권한 없음", + content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) @GetMapping("/review") - public String review() { - return "Review is available."; + public ApiResponseDto review() { + return ApiResponseDto.ok("Review is available."); } }