diff --git a/module-application/src/main/java/com/devtoon/jtoon/security/application/JwtService.java b/module-application/src/main/java/com/devtoon/jtoon/security/application/JwtService.java index 6c905065..38180dc8 100644 --- a/module-application/src/main/java/com/devtoon/jtoon/security/application/JwtService.java +++ b/module-application/src/main/java/com/devtoon/jtoon/security/application/JwtService.java @@ -46,9 +46,7 @@ public class JwtService { private long REFRESH_EXPIRE; private Key secretKey; - private final CustomUserDetailsService userDetailsService; - private final RefreshTokenRepository refreshTokenRepository; @PostConstruct @@ -91,6 +89,7 @@ public boolean isTokenValid(String token) { .setSigningKey(secretKey) .build() .parseClaimsJws(token); + return true; } catch (ExpiredJwtException e) { log.error("Expired access Token", e); diff --git a/module-application/src/main/java/com/devtoon/jtoon/security/config/SecurityConfig.java b/module-application/src/main/java/com/devtoon/jtoon/security/config/SecurityConfig.java index 0a650da6..48738495 100644 --- a/module-application/src/main/java/com/devtoon/jtoon/security/config/SecurityConfig.java +++ b/module-application/src/main/java/com/devtoon/jtoon/security/config/SecurityConfig.java @@ -4,7 +4,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -18,7 +17,6 @@ import com.devtoon.jtoon.security.filter.JwtAuthenticationFilter; import com.devtoon.jtoon.security.handler.OAuth2FailureHandler; import com.devtoon.jtoon.security.handler.OAuth2SuccessHandler; - import lombok.RequiredArgsConstructor; @Configuration @@ -37,13 +35,6 @@ public PasswordEncoder encoder() { return new BCryptPasswordEncoder(); } - @Bean - public WebSecurityCustomizer webSecurityCustomizer() { - return web -> web.ignoring() - .requestMatchers("/members/sign-up") - .requestMatchers("/login"); - } - @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http diff --git a/module-application/src/main/java/com/devtoon/jtoon/security/config/WebConfig.java b/module-application/src/main/java/com/devtoon/jtoon/security/config/WebConfig.java index 3e8bbf97..c4d1ffd0 100644 --- a/module-application/src/main/java/com/devtoon/jtoon/security/config/WebConfig.java +++ b/module-application/src/main/java/com/devtoon/jtoon/security/config/WebConfig.java @@ -5,7 +5,6 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import com.devtoon.jtoon.global.util.RegExp; import com.devtoon.jtoon.security.interceptor.MemberInterceptor; @Configuration @@ -22,7 +21,7 @@ public void addInterceptors(InterceptorRegistry registry) { @Override public void addCorsMappings(final CorsRegistry registry) { registry.addMapping("/**") - .allowedOriginPatterns(RegExp.ALLOW_ORIGIN_PATTERN) + .allowedOriginPatterns("*") .allowedMethods(ALLOWED_METHOD_NAMES.split(",")) .allowedHeaders("*") .allowCredentials(true) diff --git a/module-application/src/main/java/com/devtoon/jtoon/security/filter/JwtAuthenticationFilter.java b/module-application/src/main/java/com/devtoon/jtoon/security/filter/JwtAuthenticationFilter.java index 0e04ee8b..f98bc6b7 100644 --- a/module-application/src/main/java/com/devtoon/jtoon/security/filter/JwtAuthenticationFilter.java +++ b/module-application/src/main/java/com/devtoon/jtoon/security/filter/JwtAuthenticationFilter.java @@ -2,10 +2,8 @@ import static com.devtoon.jtoon.security.util.SecurityConstant.*; -import java.io.IOException; -import java.util.Arrays; - import org.jetbrains.annotations.NotNull; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.filter.OncePerRequestFilter; @@ -15,12 +13,14 @@ import com.devtoon.jtoon.security.application.JwtService; import com.devtoon.jtoon.security.domain.jwt.CustomUserDetails; import com.devtoon.jtoon.security.util.TokenCookie; - +import io.jsonwebtoken.MalformedJwtException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Arrays; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -37,26 +37,32 @@ protected void doFilterInternal( @NotNull HttpServletResponse response, @NotNull FilterChain filterChain ) throws ServletException, IOException { - String accessToken = Arrays.stream(request.getCookies()) - .filter(coo -> coo.getName().equals(ACCESS_TOKEN_HEADER)) - .map(Cookie::getValue) - .findFirst() - .orElse(null); + try { + String accessToken = Arrays.stream(request.getCookies()) + .filter(coo -> coo.getName().equals(ACCESS_TOKEN_HEADER)) + .map(Cookie::getValue) + .findFirst() + .orElse(null); - if (accessToken != null && accessToken.startsWith(BEARER_VALUE)) { - try { + if (accessToken != null && accessToken.startsWith(BEARER_VALUE)) { accessToken = accessToken.split(SPLIT_DATA)[1]; + if (!jwtService.isTokenValid(accessToken)) { String refreshToken = validateAndGetRefreshToken(request); accessToken = regenerateTokens(refreshToken, response); } + authenticate(accessToken); - } catch (RuntimeException e) { - log.error("Token validation failed", e); - handlerExceptionResolver.resolveException(request, response, null, e); - return; } + } catch (MalformedJwtException | BadCredentialsException e) { + log.error("Token validation failed", e); + handlerExceptionResolver.resolveException(request, response, null, e); + + return; + } catch (NullPointerException e) { + log.error("Cookie is null", e); } + filterChain.doFilter(request, response); } @@ -66,7 +72,6 @@ private String validateAndGetRefreshToken(HttpServletRequest request) { .map(Cookie::getValue) .findFirst() .orElse(null); - refreshToken = refreshToken.split(SPLIT_DATA)[1]; jwtService.isTokenValid(refreshToken); jwtService.verifyRefreshTokenDb(refreshToken); diff --git a/module-application/src/main/java/com/devtoon/jtoon/security/util/SecurityConstant.java b/module-application/src/main/java/com/devtoon/jtoon/security/util/SecurityConstant.java index b649f169..989cdb17 100644 --- a/module-application/src/main/java/com/devtoon/jtoon/security/util/SecurityConstant.java +++ b/module-application/src/main/java/com/devtoon/jtoon/security/util/SecurityConstant.java @@ -8,7 +8,8 @@ public final class SecurityConstant { public static final String ACCESS_TOKEN_HEADER = "Access_Token"; public static final String REFRESH_TOKEN_HEADER = "Refresh_Token"; - public static final String BEARER_VALUE = "Bearer+"; + public static final String BEARER_VALUE = "Bearer"; + public static final String BLANK = " "; public static final String SPLIT_DATA = "\\+"; public static final int MINUTE = 1000 * 60; } diff --git a/module-application/src/main/java/com/devtoon/jtoon/security/util/TokenCookie.java b/module-application/src/main/java/com/devtoon/jtoon/security/util/TokenCookie.java index 3de9302f..25851b03 100644 --- a/module-application/src/main/java/com/devtoon/jtoon/security/util/TokenCookie.java +++ b/module-application/src/main/java/com/devtoon/jtoon/security/util/TokenCookie.java @@ -2,10 +2,11 @@ import static com.devtoon.jtoon.security.util.SecurityConstant.*; -import jakarta.servlet.http.Cookie; import java.net.URLEncoder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; + +import jakarta.servlet.http.Cookie; import lombok.AccessLevel; import lombok.NoArgsConstructor; @@ -15,9 +16,10 @@ public class TokenCookie { private static final Charset charSet = StandardCharsets.UTF_8; public static Cookie of(String name, String value) { - Cookie cookie = new Cookie(name, URLEncoder.encode(BEARER_VALUE + value, charSet)); + Cookie cookie = new Cookie(name, URLEncoder.encode(BEARER_VALUE + BLANK + value, charSet)); cookie.setSecure(true); cookie.setHttpOnly(true); + return cookie; } }