From ebaffb0d0ea8715a6a4e6a46ff59c8888968367f Mon Sep 17 00:00:00 2001 From: kimnamgyu Date: Tue, 12 Nov 2024 13:56:59 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=ED=94=8C=EB=9F=AC=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=ED=99=98=EA=B2=BD=EC=9C=BC=EB=A1=9C=20=EC=9E=91=EB=8F=99?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/WebSecurityConfig.java | 4 +- .../global/jwt/JwtAuthenticationFilter.java | 12 ++-- .../syu/capsbe/global/jwt/JwtProvider.java | 72 ++++++++----------- 3 files changed, 36 insertions(+), 52 deletions(-) diff --git a/src/main/java/com/syu/capsbe/global/config/WebSecurityConfig.java b/src/main/java/com/syu/capsbe/global/config/WebSecurityConfig.java index c952045..34db4b4 100644 --- a/src/main/java/com/syu/capsbe/global/config/WebSecurityConfig.java +++ b/src/main/java/com/syu/capsbe/global/config/WebSecurityConfig.java @@ -22,7 +22,7 @@ @RequiredArgsConstructor(access = AccessLevel.PROTECTED) public class WebSecurityConfig { - private final JwtProvider jwtTokenProvider; + private final JwtProvider jwtProvider; @Bean public CorsConfigurationSource corsConfigurationSource() { @@ -52,7 +52,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .requestMatchers("/swagger-ui.html", "/swagger-ui/**", "/api-docs/json", "/v3/api-docs/**", "/v2/api-docs/**", "/v1/api-docs/**", "/swagger-resources/**", "/webjars/**").permitAll() .anyRequest().permitAll() ) - .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider), + .addFilterBefore(new JwtAuthenticationFilter(jwtProvider), UsernamePasswordAuthenticationFilter.class); return http.build(); } diff --git a/src/main/java/com/syu/capsbe/global/jwt/JwtAuthenticationFilter.java b/src/main/java/com/syu/capsbe/global/jwt/JwtAuthenticationFilter.java index 8cd9799..dad2b5e 100644 --- a/src/main/java/com/syu/capsbe/global/jwt/JwtAuthenticationFilter.java +++ b/src/main/java/com/syu/capsbe/global/jwt/JwtAuthenticationFilter.java @@ -16,7 +16,7 @@ public class JwtAuthenticationFilter extends GenericFilterBean { private static final String AUTHORIZATION_HEADER = "Authorization"; - private static final String TOKEN_PREFIX = "Bearer "; + private static final String TOKEN_PREFIX = "Bearer"; private final JwtProvider jwtProvider; @Override @@ -26,19 +26,17 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha if (token != null && jwtProvider.validateToken(token)) { Authentication authentication = jwtProvider.getAuthentication(token); - if (authentication != null) { - SecurityContextHolder.getContext().setAuthentication(authentication); - } - } + SecurityContextHolder.getContext().setAuthentication(authentication); - chain.doFilter(request, response); + chain.doFilter(request, response); + } } private String resolveToken(HttpServletRequest request) { String bearerToken = request.getHeader(AUTHORIZATION_HEADER); if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) { - return bearerToken.substring(TOKEN_PREFIX.length()); + return bearerToken.substring(7); } return null; diff --git a/src/main/java/com/syu/capsbe/global/jwt/JwtProvider.java b/src/main/java/com/syu/capsbe/global/jwt/JwtProvider.java index d0301ad..ab93cd3 100644 --- a/src/main/java/com/syu/capsbe/global/jwt/JwtProvider.java +++ b/src/main/java/com/syu/capsbe/global/jwt/JwtProvider.java @@ -1,18 +1,16 @@ package com.syu.capsbe.global.jwt; -import com.auth0.jwk.Jwk; -import com.auth0.jwk.JwkProvider; -import com.auth0.jwk.UrlJwkProvider; -import com.auth0.jwt.JWT; -import com.auth0.jwt.interfaces.DecodedJWT; import com.syu.capsbe.global.jwt.dto.JwtResponseDto; import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.Keys; import java.nio.charset.StandardCharsets; import java.security.Key; -import java.security.interfaces.RSAPublicKey; import java.util.Date; import java.util.List; import lombok.extern.slf4j.Slf4j; @@ -27,20 +25,14 @@ @Component public class JwtProvider { - private final String issuer; - private final UserDetailsService userDetailsService; - private final JwkProvider jwkProvider; private static final long TOKEN_VALID_TIME = 30 * 60 * 1000L; // 30 minutes + private final UserDetailsService userDetailsService; private final Key secretKey; - public JwtProvider( - @Value("${auth0.domain}") String issuer, UserDetailsService userDetailsService, - @Value("${JWT_KEY}") String secretKey + public JwtProvider(UserDetailsService userDetailsService, @Value("${JWT_KEY}") String secretKey ) { this.secretKey = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8)); - this.issuer = issuer; this.userDetailsService = userDetailsService; - this.jwkProvider = new UrlJwkProvider(issuer); } public JwtResponseDto generateToken(String email, List roles) { @@ -60,40 +52,34 @@ public JwtResponseDto generateToken(String email, List roles) { return JwtResponseDto.of(accessToken, expiresAt); } - public Authentication getAuthentication(String token) { - try { - DecodedJWT jwt = verifyToken(token); - String email = jwt.getSubject(); - - UserDetails userDetails = userDetailsService.loadUserByUsername(email); - return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities()); - } catch (Exception e) { - log.error("JWT 검증 실패", e); - return null; - } + public Authentication getAuthentication(String accessToken) { + UserDetails userDetails = userDetailsService.loadUserByUsername( + this.getUserEmailByToken(accessToken)); + return new UsernamePasswordAuthenticationToken(userDetails, "", + userDetails.getAuthorities()); } - public DecodedJWT verifyToken(String token) throws Exception { - DecodedJWT decodedJWT = JWT.decode(token); - - Jwk jwk = jwkProvider.get(decodedJWT.getKeyId()); - RSAPublicKey publicKey = (RSAPublicKey) jwk.getPublicKey(); - - com.auth0.jwt.algorithms.Algorithm algorithm = com.auth0.jwt.algorithms.Algorithm.RSA256(publicKey, null); - com.auth0.jwt.JWTVerifier verifier = JWT.require(algorithm) - .withIssuer(issuer) - .build(); - - return verifier.verify(token); - } public boolean validateToken(String token) { try { - verifyToken(token); - return true; - } catch (Exception e) { - log.error("Invalid JWT Token", e); - return false; + Jws claims = Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token); + return !claims.getBody().getExpiration().before(new Date()); + } catch (SecurityException | MalformedJwtException e) { + log.info("Invalid JWT Token", e); + } catch (ExpiredJwtException e) { + log.info("Expired JWT Token", e); + } catch (UnsupportedJwtException e) { + log.info("Unsupported JWT Token", e); + } catch (IllegalArgumentException e) { + log.info("JWT claims string is empty.", e); } + return false; + } + + public String getUserEmailByToken(String token) { + return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject(); } } From 3a495881849118dc81c72fcb66e73c210828f0a0 Mon Sep 17 00:00:00 2001 From: kimnamgyu Date: Tue, 12 Nov 2024 13:57:10 +0900 Subject: [PATCH 2/2] =?UTF-8?q?delete:=20=ED=94=8C=EB=9F=AC=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 7 ------- 1 file changed, 7 deletions(-) diff --git a/build.gradle b/build.gradle index fd16139..dbace21 100644 --- a/build.gradle +++ b/build.gradle @@ -50,13 +50,6 @@ dependencies { testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' - // auth0 - implementation group: 'com.auth0', name: 'java-jwt', version: '3.18.2' - // https://mvnrepository.com/artifact/com.auth0/auth0-spring-security-api - implementation 'com.auth0:auth0-spring-security-api:1.5.3' - - // import javax.servlet.http.*; - implementation 'javax.servlet:javax.servlet-api:4.0.1' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client:3.2.4' implementation 'org.springframework.security:spring-security-oauth2-client:6.2.3'