From e4d1f5a4df6419aa8a2563f7d35c2dc989937721 Mon Sep 17 00:00:00 2001 From: Kwak Seong Joon Date: Mon, 27 May 2024 16:53:42 +0900 Subject: [PATCH] =?UTF-8?q?[Feat]=20JwtAuthenticationFilter=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springFirstSeminar/common/Constant.java | 6 +++ .../common/jwt/JwtTokenGenerator.java | 12 +++-- .../auth/filter/JwtAuthenticationFilter.java | 51 +++++++++++-------- 3 files changed, 43 insertions(+), 26 deletions(-) create mode 100644 springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/Constant.java diff --git a/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/Constant.java b/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/Constant.java new file mode 100644 index 0000000..9f22ce4 --- /dev/null +++ b/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/Constant.java @@ -0,0 +1,6 @@ +package org.sopt.springFirstSeminar.common; + +public class Constant { + public static final String AUTHORIZATION = "Authorization"; + public static final String BEARER = "Bearer "; +} diff --git a/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/jwt/JwtTokenGenerator.java b/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/jwt/JwtTokenGenerator.java index 423f5b9..c8a5fdb 100644 --- a/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/jwt/JwtTokenGenerator.java +++ b/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/jwt/JwtTokenGenerator.java @@ -1,9 +1,6 @@ package org.sopt.springFirstSeminar.common.jwt; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Header; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.*; import io.jsonwebtoken.security.Keys; import org.sopt.springFirstSeminar.common.jwt.dto.TokenResponse; import org.springframework.beans.factory.annotation.Value; @@ -36,6 +33,12 @@ public String generateToken(final Long userId, boolean isAccessToken) { .compact(); } + public JwtParser getJwtParser() { + return Jwts.parserBuilder() + .setSigningKey(getSigningKey()) + .build(); + } + private Date generateExpireDataByToken(final boolean isAccessToken, Date presentDate) { return new Date(presentDate.getTime() + setExpireTimeByToken(isAccessToken)); } @@ -53,5 +56,4 @@ public SecretKey getSigningKey() { String encodedKey = Base64.getEncoder().encodeToString(secretKey.getBytes()); //SecretKey 통해 서명 생성 return Keys.hmacShaKeyFor(encodedKey.getBytes()); //일반적으로 HMAC (Hash-based Message Authentication Code) 알고리즘 사용 } - } diff --git a/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/jwt/auth/filter/JwtAuthenticationFilter.java b/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/jwt/auth/filter/JwtAuthenticationFilter.java index cc4c8f2..7986701 100644 --- a/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/jwt/auth/filter/JwtAuthenticationFilter.java +++ b/springFirstSeminar/src/main/java/org/sopt/springFirstSeminar/common/jwt/auth/filter/JwtAuthenticationFilter.java @@ -6,12 +6,15 @@ import jakarta.servlet.http.HttpServletResponse; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import org.sopt.springFirstSeminar.common.Constant; import org.sopt.springFirstSeminar.common.dto.ErrorMessage; import org.sopt.springFirstSeminar.common.jwt.JwtTokenProvider; import org.sopt.springFirstSeminar.common.jwt.JwtTokenValidator; import org.sopt.springFirstSeminar.common.jwt.UserAuthentication; import org.sopt.springFirstSeminar.exception.UnauthorizedException; +import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; @@ -19,7 +22,7 @@ import java.io.IOException; -import static org.sopt.springFirstSeminar.common.jwt.JwtValidationType.VALID_JWT; +import static org.sopt.springFirstSeminar.common.jwt.UserAuthentication.createUserAuthentication; @Component @RequiredArgsConstructor @@ -28,29 +31,35 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private final JwtTokenProvider jwtTokenProvider; private final JwtTokenValidator jwtTokenValidator; + @Override - protected void doFilterInternal(@NonNull HttpServletRequest request, - @NonNull HttpServletResponse response, - @NonNull FilterChain filterChain) throws ServletException, IOException { - try { - final String token = getJwtFromRequest(request); - if (jwtTokenValidator.validateToken(token) == VALID_JWT) { - Long memberId = jwtTokenProvider.getUserFromJwt(token); - UserAuthentication authentication = UserAuthentication.createUserAuthentication(memberId); - authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); - SecurityContextHolder.getContext().setAuthentication(authentication); - } - } catch (Exception exception) { - throw new UnauthorizedException(ErrorMessage.JWT_UNAUTHORIZED_EXCEPTION); - } + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + final String accessToken = getAccessToken(request); + jwtTokenValidator.validateAccessToken(accessToken); + doAuthentication(request, jwtTokenProvider.getSubject(accessToken)); filterChain.doFilter(request, response); } - private String getJwtFromRequest(HttpServletRequest request) { - String bearerToken = request.getHeader("Authorization"); - if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { - return bearerToken.substring("Bearer ".length()); + //userId로 UserAuthentication 객체 생성 + private void doAuthentication(HttpServletRequest request, Long userId) { + UserAuthentication authentication = createUserAuthentication(userId); + createAndSetWebAuthenticationDetails(request, authentication); + SecurityContext securityContext = SecurityContextHolder.getContext(); + securityContext.setAuthentication(authentication); + } + + private void createAndSetWebAuthenticationDetails(HttpServletRequest request, UserAuthentication authentication) { + WebAuthenticationDetailsSource webAuthenticationDetailsSource = new WebAuthenticationDetailsSource(); + WebAuthenticationDetails webAuthenticationDetails = webAuthenticationDetailsSource.buildDetails(request); + authentication.setDetails(webAuthenticationDetails); + } + + //accessToken 가져오기 + private String getAccessToken(final HttpServletRequest request) { + String accessToken = request.getHeader(Constant.AUTHORIZATION); + if (StringUtils.hasText(accessToken) && accessToken.startsWith(Constant.BEARER)) { + return accessToken.substring(Constant.BEARER.length()); } - return null; + throw new UnauthorizedException(ErrorMessage.INVALID_ACCESS_TOKEN); } -} \ No newline at end of file +}