From 9d19b7e080ab1e92b09e451768cc22c62777652d Mon Sep 17 00:00:00 2001 From: choidongkuen Date: Thu, 4 Jan 2024 20:50:11 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EC=9D=91=EB=8B=B5=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20TokenResponse=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B8=B0=ED=83=80=20=EA=B5=AC=ED=98=84=20(#17)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/net/teumteum/Application.java | 2 + .../teumteum/core/property/JwtProperty.java | 4 +- .../teumteum/core/security/Authenticated.java | 1 + .../core/security/SecurityConfig.java | 6 +-- .../teumteum/core/security/SecurityUtil.java | 25 ---------- .../core/security/UserAuthentication.java | 6 ++- .../core/security/dto/TokenResponse.java | 18 +++++++ .../core/security/service/AuthService.java | 19 +++++++ .../user/controller/UserController.java | 8 ++- .../teumteum/core/property/PropertyTest.java | 49 +++++++++++++++++++ .../teumteum/integration/IntegrationTest.java | 6 +-- .../teumteum/integration/SecurityUtil.java | 36 ++++++++++++++ .../integration/TestLoginContext.java | 21 -------- .../integration/UserIntegrationTest.java | 4 +- 14 files changed, 142 insertions(+), 63 deletions(-) delete mode 100644 src/main/java/net/teumteum/core/security/SecurityUtil.java create mode 100644 src/main/java/net/teumteum/core/security/dto/TokenResponse.java create mode 100644 src/main/java/net/teumteum/core/security/service/AuthService.java create mode 100644 src/test/java/net/teumteum/core/property/PropertyTest.java create mode 100644 src/test/java/net/teumteum/integration/SecurityUtil.java delete mode 100644 src/test/java/net/teumteum/integration/TestLoginContext.java diff --git a/src/main/java/net/teumteum/Application.java b/src/main/java/net/teumteum/Application.java index 6be054d8..dc5589e9 100644 --- a/src/main/java/net/teumteum/Application.java +++ b/src/main/java/net/teumteum/Application.java @@ -2,8 +2,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + @SpringBootApplication public class Application { diff --git a/src/main/java/net/teumteum/core/property/JwtProperty.java b/src/main/java/net/teumteum/core/property/JwtProperty.java index 6957e76a..71a5869c 100644 --- a/src/main/java/net/teumteum/core/property/JwtProperty.java +++ b/src/main/java/net/teumteum/core/property/JwtProperty.java @@ -17,7 +17,7 @@ public class JwtProperty { @Getter @Setter - static class Access{ + public static class Access{ private long expiration; private String header; @@ -25,7 +25,7 @@ static class Access{ @Getter @Setter - static class Refresh { + public static class Refresh { private long expiration; private String header; } diff --git a/src/main/java/net/teumteum/core/security/Authenticated.java b/src/main/java/net/teumteum/core/security/Authenticated.java index 1aac5fbf..26ba3f84 100644 --- a/src/main/java/net/teumteum/core/security/Authenticated.java +++ b/src/main/java/net/teumteum/core/security/Authenticated.java @@ -1,5 +1,6 @@ package net.teumteum.core.security; +/* 소셜 OAuth 로그인 타입 */ public enum Authenticated { 카카오,네이버; } diff --git a/src/main/java/net/teumteum/core/security/SecurityConfig.java b/src/main/java/net/teumteum/core/security/SecurityConfig.java index 54ab014d..86bf2318 100644 --- a/src/main/java/net/teumteum/core/security/SecurityConfig.java +++ b/src/main/java/net/teumteum/core/security/SecurityConfig.java @@ -30,10 +30,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrosp http .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(request - -> request.requestMatchers(allowedUrl).permitAll() - .requestMatchers(PathRequest.toH2Console()).permitAll() - .anyRequest().authenticated() - ) + -> request.requestMatchers("/**").permitAll() + .requestMatchers(PathRequest.toH2Console()).permitAll()) .httpBasic(AbstractHttpConfigurer::disable) .formLogin(AbstractHttpConfigurer::disable) .sessionManagement(sessionManagement diff --git a/src/main/java/net/teumteum/core/security/SecurityUtil.java b/src/main/java/net/teumteum/core/security/SecurityUtil.java deleted file mode 100644 index cea15d85..00000000 --- a/src/main/java/net/teumteum/core/security/SecurityUtil.java +++ /dev/null @@ -1,25 +0,0 @@ -package net.teumteum.core.security; - -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.stereotype.Component; - -@Component -public class SecurityUtil { - public void clearSecurityContext() { - SecurityContextHolder.clearContext(); - } - - /* 해당 요청에서 로그인한 회원 id 반환 */ - public Long getCurrentUserId() { - UserAuthentication userAuthentication - = (UserAuthentication) SecurityContextHolder.getContext().getAuthentication(); - return userAuthentication.getId(); - } - - /* 해당 요청에서 로그인한 회원 OAuth id 반환 */ - public String getCurrentUserOAuthId() { - UserAuthentication userAuthentication - = (UserAuthentication) SecurityContextHolder.getContext().getAuthentication(); - return userAuthentication.getOauthId(); - } -} diff --git a/src/main/java/net/teumteum/core/security/UserAuthentication.java b/src/main/java/net/teumteum/core/security/UserAuthentication.java index 3769fae6..0a2f8907 100644 --- a/src/main/java/net/teumteum/core/security/UserAuthentication.java +++ b/src/main/java/net/teumteum/core/security/UserAuthentication.java @@ -17,7 +17,7 @@ @Getter public class UserAuthentication extends AbstractAuthenticationToken { - private final Long id; + private Long id; private final String oauthId; public UserAuthentication(User user) { @@ -45,4 +45,8 @@ public Object getPrincipal() { public boolean isAuthenticated() { return true; } + + public void setUserId(Long userId) { + id = userId; + } } diff --git a/src/main/java/net/teumteum/core/security/dto/TokenResponse.java b/src/main/java/net/teumteum/core/security/dto/TokenResponse.java new file mode 100644 index 00000000..df88e24c --- /dev/null +++ b/src/main/java/net/teumteum/core/security/dto/TokenResponse.java @@ -0,0 +1,18 @@ +package net.teumteum.core.security.dto; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class TokenResponse { + private String accessToken; + private String refreshToken; + + @Builder + public TokenResponse(String accessToken, String refreshToken) { + this.accessToken = accessToken; + this.refreshToken = refreshToken; + } +} diff --git a/src/main/java/net/teumteum/core/security/service/AuthService.java b/src/main/java/net/teumteum/core/security/service/AuthService.java new file mode 100644 index 00000000..df2b9a4a --- /dev/null +++ b/src/main/java/net/teumteum/core/security/service/AuthService.java @@ -0,0 +1,19 @@ +package net.teumteum.core.security.service; + +import lombok.RequiredArgsConstructor; +import net.teumteum.user.domain.User; +import net.teumteum.user.domain.UserConnector; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class AuthService { + private final JwtService jwtService; + private final UserConnector userConnector; + public Optional findUserByToken(String accessToken) { + Long id = Long.parseLong(jwtService.getUserIdFromToken(accessToken)); + return userConnector.findUserById(id); + } +} diff --git a/src/main/java/net/teumteum/user/controller/UserController.java b/src/main/java/net/teumteum/user/controller/UserController.java index e55207bc..4f7b753f 100644 --- a/src/main/java/net/teumteum/user/controller/UserController.java +++ b/src/main/java/net/teumteum/user/controller/UserController.java @@ -3,7 +3,7 @@ import java.util.Arrays; import lombok.RequiredArgsConstructor; import net.teumteum.core.error.ErrorResponse; -import net.teumteum.core.security.SecurityUtil; +import net.teumteum.core.security.service.SecurityService; import net.teumteum.user.domain.request.UserUpdateRequest; import net.teumteum.user.domain.response.UserGetResponse; import net.teumteum.user.domain.response.UsersGetByIdResponse; @@ -20,15 +20,13 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -import javax.security.auth.login.LoginContext; - @RestController @RequiredArgsConstructor @RequestMapping("/users") public class UserController { private final UserService userService; - private final SecurityUtil securityUtil; + private final SecurityService securityService; /* userId 로 회원 조회 */ @GetMapping("/{userId}") @@ -68,6 +66,6 @@ public ErrorResponse handleIllegalArgumentException(IllegalArgumentException ill } private Long getCurrentUserId() { - return securityUtil.getCurrentUserId(); + return securityService.getCurrentUserId(); } } diff --git a/src/test/java/net/teumteum/core/property/PropertyTest.java b/src/test/java/net/teumteum/core/property/PropertyTest.java new file mode 100644 index 00000000..0b74c6d7 --- /dev/null +++ b/src/test/java/net/teumteum/core/property/PropertyTest.java @@ -0,0 +1,49 @@ +package net.teumteum.core.property; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; + +import static org.assertj.core.api.Assertions.assertThat; +@DisplayName("property 관련 테스트의 ") +@TestPropertySource(locations = { + "classpath:application-auth.yml", + "classpath:application-redis.yml" +}) +@SpringBootTest +class PropertyTest { + + @Autowired + private JwtProperty jwtProperty; + + @Autowired + private RedisProperty redisProperty; + + @Nested + @DisplayName("jwtProperty 주입 테스트가") + class JwtPropertyTest { + + @Test + @DisplayName("정상적으로 성공한다.") + void test(){ + String bearer = jwtProperty.getBearer(); + System.out.println(bearer); + } + + } + + @Nested + @DisplayName("redisProperty 주입 테스트가") + class RedisPropertyTest { + @Test + @DisplayName("정상적으로 성공한다.") + void test(){ + String host = redisProperty.getHost(); + System.out.println(host); + } + } + +} \ No newline at end of file diff --git a/src/test/java/net/teumteum/integration/IntegrationTest.java b/src/test/java/net/teumteum/integration/IntegrationTest.java index 7cd0b6e6..1c2bfc1a 100644 --- a/src/test/java/net/teumteum/integration/IntegrationTest.java +++ b/src/test/java/net/teumteum/integration/IntegrationTest.java @@ -1,7 +1,7 @@ package net.teumteum.integration; import net.teumteum.Application; -import net.teumteum.core.security.SecurityUtil; +import net.teumteum.core.security.service.SecurityService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; @@ -10,7 +10,7 @@ import org.springframework.test.context.ContextConfiguration; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -@ContextConfiguration(classes = {Application.class, Api.class, Repository.class, TestLoginContext.class}) +@ContextConfiguration(classes = {Application.class, Api.class, Repository.class}) abstract public class IntegrationTest { @Autowired @@ -20,7 +20,7 @@ abstract public class IntegrationTest { protected Repository repository; @Autowired - protected SecurityUtil securityUtil; + protected SecurityService securityService; @AfterEach @BeforeEach diff --git a/src/test/java/net/teumteum/integration/SecurityUtil.java b/src/test/java/net/teumteum/integration/SecurityUtil.java new file mode 100644 index 00000000..5b9144f6 --- /dev/null +++ b/src/test/java/net/teumteum/integration/SecurityUtil.java @@ -0,0 +1,36 @@ +package net.teumteum.integration; + +import net.teumteum.core.security.UserAuthentication; +import org.springframework.boot.test.context.TestComponent; +import org.springframework.security.core.context.SecurityContextHolder; + +import javax.security.auth.login.LoginContext; + +@TestComponent +public class SecurityUtil { + + public void clearSecurityContext() { + SecurityContextHolder.clearContext(); + } + + /* 해당 요청에서 로그인한 회원 id 반환 */ + public Long getCurrentUserId() { + UserAuthentication userAuthentication = getUserAuthentication(); + return userAuthentication.getId(); + } + + /* 해당 요청에서 로그인한 회원 OAuth id 반환 */ + public String getCurrentUserOAuthId() { + UserAuthentication userAuthentication = getUserAuthentication(); + return userAuthentication.getOauthId(); + } + + public void setUserId(Long userId) { + UserAuthentication userAuthentication = getUserAuthentication(); + userAuthentication.setUserId(userId); + } + + private static UserAuthentication getUserAuthentication() { + return (UserAuthentication) SecurityContextHolder.getContext().getAuthentication(); + } +} diff --git a/src/test/java/net/teumteum/integration/TestLoginContext.java b/src/test/java/net/teumteum/integration/TestLoginContext.java deleted file mode 100644 index 1a9ff387..00000000 --- a/src/test/java/net/teumteum/integration/TestLoginContext.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.teumteum.integration; - -import org.springframework.boot.test.context.TestComponent; - -import javax.security.auth.login.LoginContext; - -//@TestComponent -//public class TestLoginContext implements LoginContext { -// -// private Long userId; -// -// @Override -// public void setUserId(Long userId) { -// this.userId = userId; -// } -// -// @Override -// public Long getUserId() { -// return this.userId; -// } -//} diff --git a/src/test/java/net/teumteum/integration/UserIntegrationTest.java b/src/test/java/net/teumteum/integration/UserIntegrationTest.java index f57e1b56..0561eb9a 100644 --- a/src/test/java/net/teumteum/integration/UserIntegrationTest.java +++ b/src/test/java/net/teumteum/integration/UserIntegrationTest.java @@ -113,7 +113,7 @@ void Update_user_info() { var existUser = repository.saveAndGetUser(); var updateUser = RequestFixture.userUpdateRequest(existUser); - loginContext.setUserId(existUser.getId()); + securityService.setUserId(existUser.getId()); // when var result = api.updateUser(VALID_TOKEN, updateUser); @@ -135,7 +135,7 @@ void Return_200_ok_with_success_make_friends() { var myToken = "JWT MY_TOKEN"; var friend = repository.saveAndGetUser(); - loginContext.setUserId(me.getId()); + securityService.setUserId(me.getId()); // when var result = api.addFriends(myToken, friend.getId());