From 4f125550109d2c8a891a9dc441dd840e48bb0fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=95=88=EC=A0=95=ED=9B=84?= Date: Thu, 7 Nov 2024 17:39:13 +0900 Subject: [PATCH] fix: security error handling --- .github/workflows/cd.yml | 2 +- .../jwt/JwtAuthenticationEntryPoint.java | 24 ++++++------- .../com/pocket/outbound/util/JwtFilter.java | 36 +++++++++++++------ .../com/pocket/outbound/util/JwtUtil.java | 7 ++-- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index b5352cd..0e318f8 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -2,7 +2,7 @@ name: Backend CD # actions 이름 on: push: - branches: [ develop ] + branches: [ refactor/#66 ] jobs: deploy: diff --git a/core/src/main/java/com/pocket/core/exception/jwt/JwtAuthenticationEntryPoint.java b/core/src/main/java/com/pocket/core/exception/jwt/JwtAuthenticationEntryPoint.java index 0e18359..f01cf4c 100644 --- a/core/src/main/java/com/pocket/core/exception/jwt/JwtAuthenticationEntryPoint.java +++ b/core/src/main/java/com/pocket/core/exception/jwt/JwtAuthenticationEntryPoint.java @@ -19,20 +19,16 @@ @Component public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { - @Override - public void commence(HttpServletRequest request, HttpServletResponse response, - AuthenticationException authException) - throws IOException { - HttpStatus httpStatus; - ApiResponse errorResponse; + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { + HttpStatus httpStatus = HttpStatus.UNAUTHORIZED; + ApiResponse errorResponse = ApiResponse.onFailure( + SecurityErrorCode.UNAUTHORIZED.getCode(), + SecurityErrorCode.UNAUTHORIZED.getMessage(), + authException.getMessage() + ); - log.error(">>>>>> AuthenticationException: ", authException); - httpStatus = HttpStatus.UNAUTHORIZED; - errorResponse = ApiResponse.onFailure( - SecurityErrorCode.UNAUTHORIZED.getCode(), - SecurityErrorCode.UNAUTHORIZED.getMessage(), - authException.getMessage()); + HttpResponseUtil.setErrorResponse(response, httpStatus, errorResponse); + } - HttpResponseUtil.setErrorResponse(response, httpStatus, errorResponse); - } } diff --git a/outbound/src/main/java/com/pocket/outbound/util/JwtFilter.java b/outbound/src/main/java/com/pocket/outbound/util/JwtFilter.java index 936ebee..ba88221 100644 --- a/outbound/src/main/java/com/pocket/outbound/util/JwtFilter.java +++ b/outbound/src/main/java/com/pocket/outbound/util/JwtFilter.java @@ -1,5 +1,9 @@ package com.pocket.outbound.util; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.pocket.core.exception.common.ApiResponse; +import com.pocket.core.exception.jwt.JwtAuthenticationEntryPoint; +import com.pocket.core.exception.jwt.SecurityCustomException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; @@ -7,6 +11,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; @@ -19,23 +24,34 @@ public class JwtFilter extends OncePerRequestFilter { private final JwtUtil jwtUtil; + private final JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { - - String jwt = jwtUtil.resolveToken(request); - - if (jwt != null) { - jwtUtil.validateToken(jwt); - setAuthentication(jwt); + try { + String jwt = jwtUtil.resolveToken(request); + if (jwt != null) { + jwtUtil.validateToken(jwt); // 여기서 예외 발생 가능 + setAuthentication(jwt); + } + chain.doFilter(request, response); + } catch (SecurityCustomException e) { + log.error("Custom security exception: {}", e.getMessage()); + response.setStatus(e.getErrorCode().getHttpStatus().value()); + response.setContentType("application/json; charset=UTF-8"); + response.setCharacterEncoding("UTF-8"); + response.getWriter().write( + new ObjectMapper().writeValueAsString( + ApiResponse.onFailure(e.getErrorCode().getCode(), e.getErrorCode().getMessage(), e.getMessage()) + ) + ); + } catch (AuthenticationException e) { + jwtAuthenticationEntryPoint.commence(request, response, e); } - - chain.doFilter(request, response); } private void setAuthentication(String accessToken) { Authentication authentication = jwtUtil.resolveToken(accessToken); SecurityContextHolder.getContext().setAuthentication(authentication); } - -} \ No newline at end of file +} diff --git a/outbound/src/main/java/com/pocket/outbound/util/JwtUtil.java b/outbound/src/main/java/com/pocket/outbound/util/JwtUtil.java index eaa5acf..fc61c17 100644 --- a/outbound/src/main/java/com/pocket/outbound/util/JwtUtil.java +++ b/outbound/src/main/java/com/pocket/outbound/util/JwtUtil.java @@ -188,8 +188,11 @@ public boolean validateToken(String token) { JwtParser jwtParser = Jwts.parserBuilder().setSigningKey(secretKey).build(); jwtParser.parseClaimsJws(token); return true; - } catch (SecurityException | MalformedJwtException | IllegalArgumentException | UnsupportedJwtException | - ExpiredJwtException e) { + } catch (ExpiredJwtException e) { + log.warn("[*] Token has expired: {}", e.getMessage()); + throw new SecurityCustomException(TOKEN_EXPIRED); + } catch (SecurityException | MalformedJwtException | IllegalArgumentException | UnsupportedJwtException e) { + log.warn("[*] Invalid token: {}", e.getMessage()); throw new SecurityCustomException(INVALID_TOKEN); } }