-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor : auths 단 refactoring (#56)
1. JwtExceptionHandlerFilter.java 추가 - JwtAuthenticationFilter.java 와 역할 분리 2. AuthService.java 단 예외 처리 구체화 - JwtExceptionAdvice.java 에서 처리 3. JwtAuthenticationFilter.java - shouldNotFilter 조건 추가 - 로컬에서 h2 console 을 이용하여 테스트 시, accessToken null 예외가 발생해서 필터링 되지 않도록 처리 4. 로그 추가
- Loading branch information
1 parent
958f4eb
commit 5558bff
Showing
10 changed files
with
178 additions
and
77 deletions.
There are no files selected for viewing
48 changes: 48 additions & 0 deletions
48
server/src/main/java/seb4141preproject/security/auth/advice/JwtExceptionAdvice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package seb4141preproject.security.auth.advice; | ||
|
||
import io.jsonwebtoken.ExpiredJwtException; | ||
import io.jsonwebtoken.MalformedJwtException; | ||
import io.jsonwebtoken.UnsupportedJwtException; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
import seb4141preproject.utils.ErrorResponse; | ||
|
||
@Slf4j | ||
@RestControllerAdvice | ||
public class JwtExceptionAdvice { | ||
|
||
@ExceptionHandler | ||
@ResponseStatus(HttpStatus.UNAUTHORIZED) | ||
public ErrorResponse handleExpiredJwtException(ExpiredJwtException e) { | ||
log.error("만료된 Refresh Token 입니다.", e); | ||
|
||
return ErrorResponse.of(HttpStatus.UNAUTHORIZED, e.getMessage()); | ||
} | ||
|
||
@ExceptionHandler | ||
@ResponseStatus(HttpStatus.UNAUTHORIZED) | ||
public ErrorResponse handleMalformedJwtException(MalformedJwtException e) { | ||
log.error("잘못된 Refresh Token 서명입니다.", e); | ||
|
||
return ErrorResponse.of(HttpStatus.UNAUTHORIZED, e.getMessage()); | ||
} | ||
|
||
@ExceptionHandler | ||
@ResponseStatus(HttpStatus.UNAUTHORIZED) | ||
public ErrorResponse handleUnsupportedJwtException(UnsupportedJwtException e) { | ||
log.error("지원되지 않는 Access Token 입니다.", e); | ||
|
||
return ErrorResponse.of(HttpStatus.UNAUTHORIZED, e.getMessage()); | ||
} | ||
|
||
@ExceptionHandler | ||
@ResponseStatus(HttpStatus.UNAUTHORIZED) | ||
public ErrorResponse handleIllegalArgumentException(IllegalArgumentException e) { | ||
log.error("Refresh Token 이 잘못되었습니다.", e); | ||
|
||
return ErrorResponse.of(HttpStatus.UNAUTHORIZED, e.getMessage()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
server/src/main/java/seb4141preproject/security/auth/filter/JwtExceptionHandlerFilter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package seb4141preproject.security.auth.filter; | ||
|
||
import io.jsonwebtoken.ExpiredJwtException; | ||
import io.jsonwebtoken.MalformedJwtException; | ||
import io.jsonwebtoken.UnsupportedJwtException; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.util.StringUtils; | ||
import org.springframework.web.filter.OncePerRequestFilter; | ||
import seb4141preproject.security.auth.dto.TokenDto; | ||
import seb4141preproject.security.auth.provider.JwtTokenizer; | ||
import seb4141preproject.security.auth.service.AuthService; | ||
import seb4141preproject.security.auth.utils.ErrorResponder; | ||
import seb4141preproject.security.auth.utils.HeaderMapRequestWrapper; | ||
|
||
import javax.servlet.FilterChain; | ||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
public class JwtExceptionHandlerFilter extends OncePerRequestFilter { | ||
|
||
private final JwtTokenizer jwtTokenizer; | ||
private final AuthService authService; | ||
|
||
@Override | ||
protected void doFilterInternal(HttpServletRequest request, | ||
HttpServletResponse response, | ||
FilterChain filterChain) throws ServletException, IOException { | ||
|
||
HeaderMapRequestWrapper wrapper = new HeaderMapRequestWrapper(request); // (reissue 시) header 값 덮어쓰기를 위한 wrapper 객체 생성 | ||
|
||
try { | ||
filterChain.doFilter(request, response); | ||
|
||
log.info("Exception Filter filterChain 실행"); | ||
|
||
} catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) { | ||
log.error("잘못된 Access Token 서명입니다.", e); | ||
ErrorResponder.sendJwtErrorResponse(response, e.getMessage()); | ||
|
||
} catch (UnsupportedJwtException e) { | ||
ErrorResponder.sendJwtErrorResponse(response, e.getMessage()); | ||
log.error("지원되지 않는 Access Token 입니다.", e); | ||
|
||
} catch (IllegalArgumentException e) { | ||
ErrorResponder.sendJwtErrorResponse(response, e.getMessage()); | ||
log.error("Access Token 이 잘못되었습니다.", e); | ||
|
||
} catch (ExpiredJwtException e) { | ||
log.error("만료된 Access Token 입니다. 재발급을 진행합니다."); | ||
|
||
String refreshToken = resolveRefreshToken(request); // request header 에서 refreshToken 추출 | ||
|
||
Authentication authentication = jwtTokenizer.getAuthentication(refreshToken); // refreshToken 으로 authentication 생성 | ||
// -> 만료된 accessToken 으로는 getAuthentication 불가능하기 때문 | ||
SecurityContextHolder.getContext().setAuthentication(authentication); | ||
|
||
TokenDto tokenDto = authService.reissue(request, authentication); // 토큰 재발급 | ||
setHeaderResponse(wrapper, response, tokenDto); // header, response 값 재설정 | ||
|
||
log.error("Access Token, Refresh Token 재발급이 완료되었습니다."); | ||
|
||
filterChain.doFilter(wrapper, response); | ||
} | ||
} | ||
|
||
private String resolveRefreshToken(HttpServletRequest request) { | ||
String bearerToken = request.getHeader("RefreshToken"); | ||
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { | ||
return bearerToken.substring(7); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
private void setHeaderResponse(HeaderMapRequestWrapper wrapper, | ||
HttpServletResponse response, | ||
TokenDto tokenDto) { | ||
// accessToken, refreshToken Header 값 새로 덮어쓰기 | ||
wrapper.addHeader("Authorization", tokenDto.getAccessToken()); | ||
wrapper.addHeader("RefreshToken", tokenDto.getRefreshToken()); | ||
|
||
// reissue 후 response header 에 새로운 accessToken, refreshToken 값 추가 | ||
response.addHeader("Authorization", tokenDto.getAccessToken()); | ||
response.addHeader("RefreshToken", tokenDto.getRefreshToken()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters