diff --git a/src/main/java/com/somemore/global/auth/annotation/RoleId.java b/src/main/java/com/somemore/global/auth/annotation/RoleId.java index 606153df..6d948a7a 100644 --- a/src/main/java/com/somemore/global/auth/annotation/RoleId.java +++ b/src/main/java/com/somemore/global/auth/annotation/RoleId.java @@ -1,5 +1,7 @@ package com.somemore.global.auth.annotation; +import io.swagger.v3.oas.annotations.Hidden; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -7,5 +9,6 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) +@Hidden public @interface RoleId { } diff --git a/src/main/java/com/somemore/global/auth/annotation/UserId.java b/src/main/java/com/somemore/global/auth/annotation/UserId.java index bf258d59..1927016e 100644 --- a/src/main/java/com/somemore/global/auth/annotation/UserId.java +++ b/src/main/java/com/somemore/global/auth/annotation/UserId.java @@ -1,5 +1,7 @@ package com.somemore.global.auth.annotation; +import io.swagger.v3.oas.annotations.Hidden; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -7,5 +9,6 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) +@Hidden public @interface UserId { } diff --git a/src/main/java/com/somemore/global/auth/idpw/provider/CustomAuthenticationProvider.java b/src/main/java/com/somemore/global/auth/idpw/provider/CustomAuthenticationProvider.java index e1514e53..7ae7e45e 100644 --- a/src/main/java/com/somemore/global/auth/idpw/provider/CustomAuthenticationProvider.java +++ b/src/main/java/com/somemore/global/auth/idpw/provider/CustomAuthenticationProvider.java @@ -6,6 +6,7 @@ import com.somemore.global.auth.jwt.domain.EncodedToken; import com.somemore.global.auth.jwt.domain.TokenType; import com.somemore.global.auth.jwt.usecase.JwtUseCase; +import com.somemore.global.util.encoder.BCryptPasswordEncoderUtil; import com.somemore.user.domain.User; import com.somemore.user.domain.UserRole; import com.somemore.user.usecase.UserQueryUseCase; @@ -16,7 +17,6 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; -import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -28,7 +28,6 @@ public class CustomAuthenticationProvider implements AuthenticationProvider { private final JwtUseCase jwtUseCase; - private final PasswordEncoder passwordEncoder; private final UserQueryUseCase userQueryUseCase; private final NEWVolunteerQueryUseCase volunteerQueryUseCase; private final NEWCenterQueryUseCase centerQueryUseCase; @@ -73,7 +72,7 @@ private EncodedToken generateAccessToken(UserIdentity userIdentity) { } private void validatePassword(String rawPassword, String encodedPassword) { - if (!passwordEncoder.matches(rawPassword, encodedPassword)) { + if (!BCryptPasswordEncoderUtil.matches(rawPassword, encodedPassword)) { throw new BadCredentialsException("비밀번호가 일치하지 않습니다."); } diff --git a/src/main/java/com/somemore/global/util/encoder/BCryptPasswordEncoderUtil.java b/src/main/java/com/somemore/global/util/encoder/BCryptPasswordEncoderUtil.java new file mode 100644 index 00000000..1e335966 --- /dev/null +++ b/src/main/java/com/somemore/global/util/encoder/BCryptPasswordEncoderUtil.java @@ -0,0 +1,21 @@ +package com.somemore.global.util.encoder; + +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; + +public class BCryptPasswordEncoderUtil { + + private static final PasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder(); + + private BCryptPasswordEncoderUtil() { + throw new UnsupportedOperationException("유틸리티 클래스는 인스턴스화할 수 없습니다."); + } + + public static String encode(String rawPassword) { + return PASSWORD_ENCODER.encode(rawPassword); + } + + public static boolean matches(String rawPassword, String encodedPassword) { + return PASSWORD_ENCODER.matches(rawPassword, encodedPassword); + } +} diff --git a/src/main/java/com/somemore/user/dto/UserAuthInfo.java b/src/main/java/com/somemore/user/dto/UserAuthInfo.java index 674dc26a..09685fc8 100644 --- a/src/main/java/com/somemore/user/dto/UserAuthInfo.java +++ b/src/main/java/com/somemore/user/dto/UserAuthInfo.java @@ -1,11 +1,17 @@ package com.somemore.user.dto; import com.somemore.global.auth.oauth.domain.OAuthProvider; +import com.somemore.global.util.encoder.BCryptPasswordEncoderUtil; import java.util.UUID; public record UserAuthInfo(String accountId, String accountPassword) { + public UserAuthInfo(String accountId, + String accountPassword) { + this.accountId = accountId; + this.accountPassword = BCryptPasswordEncoderUtil.encode(accountPassword); + } public static UserAuthInfo of(String accountId, String accountPassword) { return new UserAuthInfo(accountId, accountPassword); diff --git a/src/test/java/com/somemore/global/util/encoder/BCryptPasswordEncoderUtilTest.java b/src/test/java/com/somemore/global/util/encoder/BCryptPasswordEncoderUtilTest.java new file mode 100644 index 00000000..c2004229 --- /dev/null +++ b/src/test/java/com/somemore/global/util/encoder/BCryptPasswordEncoderUtilTest.java @@ -0,0 +1,53 @@ +package com.somemore.global.util.encoder; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.InvocationTargetException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class BCryptPasswordEncoderUtilTest { + + @Test + @DisplayName("비밀번호를 성공적으로 인코딩할 수 있다") + void testEncode() { + // given + String rawPassword = "password123"; + + // when + String encodedPassword = BCryptPasswordEncoderUtil.encode(rawPassword); + + // then + assertThat(encodedPassword).isNotNull(); + + } + + @Test + @DisplayName("비밀번호를 성공적으로 매칭시킬 수 있다") + void testMatches() { + // given + String rawPassword = "password123"; + + // when + String encodedPassword = BCryptPasswordEncoderUtil.encode(rawPassword); + + // then + assertThat(BCryptPasswordEncoderUtil.matches(rawPassword, encodedPassword)).isTrue(); + } + + @Test + @DisplayName("인스턴스화 할 수 없다.") + void testConstruct() throws Exception { + // given + var constructor = BCryptPasswordEncoderUtil.class.getDeclaredConstructor(); + constructor.setAccessible(true); + + // when & then + assertThatThrownBy(constructor::newInstance) + .isInstanceOf(InvocationTargetException.class) + .extracting(Throwable::getCause) + .isInstanceOf(UnsupportedOperationException.class); + } +}