diff --git a/src/main/java/com/pawwithu/connectdog/config/SecurityConfig.java b/src/main/java/com/pawwithu/connectdog/config/SecurityConfig.java index 939f4ece..7c86ab9b 100644 --- a/src/main/java/com/pawwithu/connectdog/config/SecurityConfig.java +++ b/src/main/java/com/pawwithu/connectdog/config/SecurityConfig.java @@ -78,6 +78,8 @@ public SecurityFilterChain filterChain(HttpSecurity http, HandlerMappingIntrospe .requestMatchers(mvcMatcherBuilder.pattern("/v3/api-docs/**")).permitAll() .requestMatchers(mvcMatcherBuilder.pattern("/volunteers/nickname/isDuplicated")).permitAll() .requestMatchers(mvcMatcherBuilder.pattern("/fcm-test")).permitAll() + .requestMatchers(mvcMatcherBuilder.pattern("/volunteers/posts/{postId}/applications")).hasRole("AUTH_VOLUNTEER") + .requestMatchers(mvcMatcherBuilder.pattern("/intermediaries/**")).hasRole("AUTH_INTERMEDIARY") .anyRequest().authenticated()) .addFilterAfter(customVolunteerAuthFilter(), LogoutFilter.class) .addFilterAfter(customIntermediaryAuthFilter(), LogoutFilter.class) diff --git a/src/main/java/com/pawwithu/connectdog/error/ErrorCode.java b/src/main/java/com/pawwithu/connectdog/error/ErrorCode.java index 99b5f9aa..ba46bd61 100644 --- a/src/main/java/com/pawwithu/connectdog/error/ErrorCode.java +++ b/src/main/java/com/pawwithu/connectdog/error/ErrorCode.java @@ -12,6 +12,8 @@ public enum ErrorCode { ALREADY_LOGOUT_MEMBER("A3", "이미 로그아웃한 회원입니다"), EMAIL_SEND_ERROR("A4", "이메일 인증 코드 전송을 실패했습니다."), UNKNOWN_PROVIDER("A4", "provider 값이 KAKAO 또는 NAVER가 아닙니다."), + NOT_ALLOWED_MEMBER("A6", "해당 요청에 대한 권한이 없습니다."), + NOT_AUTHENTICATED_REQUEST("A7", "유효한 JWT 토큰이 없습니다."), VOLUNTEER_NOT_FOUND("M1", "해당 이동봉사자를 찾을 수 없습니다."), // Member -> M (이동봉사자, 이동봉사 중개 통일) diff --git a/src/main/java/com/pawwithu/connectdog/jwt/JwtAccessDeniedHandler.java b/src/main/java/com/pawwithu/connectdog/jwt/JwtAccessDeniedHandler.java index 228f5641..62e2fcbc 100644 --- a/src/main/java/com/pawwithu/connectdog/jwt/JwtAccessDeniedHandler.java +++ b/src/main/java/com/pawwithu/connectdog/jwt/JwtAccessDeniedHandler.java @@ -1,5 +1,7 @@ package com.pawwithu.connectdog.jwt; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.pawwithu.connectdog.error.dto.ErrorResponse; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -9,6 +11,8 @@ import java.io.IOException; +import static com.pawwithu.connectdog.error.ErrorCode.NOT_ALLOWED_MEMBER; + /** * 필요한 권한이 존재하지 않는 경우에 403 Forbidden 에러를 리턴 * -> Spring Security가 AccessDeniedHandler 인터페이스의 handle 메서드 호출 @@ -17,10 +21,22 @@ @Component public class JwtAccessDeniedHandler implements AccessDeniedHandler { + private final ObjectMapper objectMapper; + + public JwtAccessDeniedHandler(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + @Override public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException { // 필요한 권한이 없이 접근하려 할때 403 log.info("허가 받지 않은 사용자의 접근입니다."); - response.sendError(HttpServletResponse.SC_FORBIDDEN); + ErrorResponse errorResponse = ErrorResponse.of(NOT_ALLOWED_MEMBER.getCode(), NOT_ALLOWED_MEMBER.getMessage()); + String jsonResponse = objectMapper.writeValueAsString(errorResponse); + + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + response.setStatus(HttpServletResponse.SC_FORBIDDEN); + response.getWriter().write(jsonResponse); } } \ No newline at end of file diff --git a/src/main/java/com/pawwithu/connectdog/jwt/JwtAuthenticationEntryPoint.java b/src/main/java/com/pawwithu/connectdog/jwt/JwtAuthenticationEntryPoint.java index 4befa312..124ee7ba 100644 --- a/src/main/java/com/pawwithu/connectdog/jwt/JwtAuthenticationEntryPoint.java +++ b/src/main/java/com/pawwithu/connectdog/jwt/JwtAuthenticationEntryPoint.java @@ -1,5 +1,7 @@ package com.pawwithu.connectdog.jwt; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.pawwithu.connectdog.error.dto.ErrorResponse; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -10,6 +12,8 @@ import java.io.IOException; +import static com.pawwithu.connectdog.error.ErrorCode.NOT_AUTHENTICATED_REQUEST; + /** * 유효한 자격 증명을 제공하지 않고 접근하려 할 때, 401 UnAuthorized 에러를 리턴 * -> Spring Security가 AuthenticationEntryPoint 인터페이스의 commence 메서드 호출 @@ -18,10 +22,22 @@ @Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + private final ObjectMapper objectMapper; + + public JwtAuthenticationEntryPoint(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { log.info("인증되지 않은 요청입니다."); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + ErrorResponse errorResponse = ErrorResponse.of(NOT_AUTHENTICATED_REQUEST.getCode(), NOT_AUTHENTICATED_REQUEST.getMessage()); + String jsonResponse = objectMapper.writeValueAsString(errorResponse); + + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.getWriter().write(jsonResponse); } } \ No newline at end of file