From 56a847d186a373e4de157006dea358e56d6a8753 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 18 Aug 2024 09:49:11 +0900 Subject: [PATCH 1/7] =?UTF-8?q?docs=20:=20README=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 143df28c6..a69b8ed36 100755 --- a/README.md +++ b/README.md @@ -21,19 +21,10 @@ AnDroid + Blossom
**당신만의 매력적인 이미지**로 **움직이는 귀여운 캐릭터 타임캡슐 스킨**을 직접 제작해보세요.
_우리 앱으로 **과거**와 **현재**, **미래**를 연결하는 특별한 경험을 즐기실 수 있습니다._ -## 🎨 Figma -### 작업 중... - - - - - - - - - - - +## 🎨 디자인 + + + ## 🛠 개발 시스템 구성도 @@ -48,7 +39,7 @@ AnDroid + Blossom ## ⚙️ 운용 환경 - + ## 🛢 ERD @@ -57,5 +48,4 @@ AnDroid + Blossom ARchive 위키 ## 🦾 기술 스택 - - + From a833341f838b7cba24ee500cb16c639809e2dd76 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 18 Aug 2024 13:46:22 +0900 Subject: [PATCH 2/7] =?UTF-8?q?fix=20:=20=EC=9A=B4=EC=98=81=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a69b8ed36..cdb534384 100755 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ AnDroid + Blossom -## ⚙️ 운용 환경 - +## ⚙️ 운영 환경 + ## 🛢 ERD From f34aeb5752f3520c006768f75a689aab25a4c5f8 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Mon, 26 Aug 2024 14:10:57 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20=EB=A8=B8=EC=A7=80=20=EC=B6=A9?= =?UTF-8?q?=EB=8F=8C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/notification/src/main/resources/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/notification/src/main/resources/config b/backend/notification/src/main/resources/config index 9340cfd0d..9c68d32c6 160000 --- a/backend/notification/src/main/resources/config +++ b/backend/notification/src/main/resources/config @@ -1 +1 @@ -Subproject commit 9340cfd0d1b8c12cb4ad8a7b786e7e6f3ed99a18 +Subproject commit 9c68d32c612fb9014eeb75bc8efb01ac495bdd24 From d3fd1262978a630ec0482694e9ed8c5414f2d83a Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Mon, 26 Aug 2024 14:40:29 +0900 Subject: [PATCH 4/7] =?UTF-8?q?refact:=20=EB=A1=9C=EA=B7=B8=EB=B0=B1=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/logback-spring.xml | 63 ++++++++++--------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/backend/core/src/main/resources/logback-spring.xml b/backend/core/src/main/resources/logback-spring.xml index 4b25a32da..4e3f1d387 100644 --- a/backend/core/src/main/resources/logback-spring.xml +++ b/backend/core/src/main/resources/logback-spring.xml @@ -1,34 +1,41 @@ + - [%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{36} - %msg%n - + [%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{36} - %msg%n - - ./logs/info.log - - INFO - - - [%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n - - - - ./logs/info.%d{yyyy-MM-dd}.%i.log.gz - - - 100MB - - 180 - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + ./logs/info.log + + INFO + + + [%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n + + + ./logs/info.%d{yyyy-MM-dd}.%i.log.gz + + 100MB + + 180 + + + + + + + + From 42aa7cb55934ecfff73cf0609298f024ff315e70 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Mon, 26 Aug 2024 14:40:58 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20defaultFilter=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/security/SecurityConfig.java | 9 ++- .../core/global/error/ErrorCode.java | 1 + .../filter/DefaultAuthenticationFilter.java | 56 +++++++++++++++++++ .../security/jwt/JwtAuthenticationFilter.java | 2 + .../property/DefaultKeyProperties.java | 10 ++++ 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/global/security/filter/DefaultAuthenticationFilter.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/global/security/property/DefaultKeyProperties.java diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/global/config/security/SecurityConfig.java b/backend/core/src/main/java/site/timecapsulearchive/core/global/config/security/SecurityConfig.java index 9fd7a8826..f71652fc5 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/global/config/security/SecurityConfig.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/global/config/security/SecurityConfig.java @@ -6,7 +6,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -15,10 +14,12 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.util.matcher.NegatedRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.security.web.util.matcher.RequestMatchers; import site.timecapsulearchive.core.domain.member.entity.Role; +import site.timecapsulearchive.core.global.security.filter.DefaultAuthenticationFilter; @EnableWebSecurity @Configuration @@ -28,6 +29,7 @@ public class SecurityConfig { private final AuthenticationProvider jwtAuthenticationProvider; private final ObjectMapper objectMapper; private final AccessDeniedHandler accessDeniedHandler; + private final DefaultAuthenticationFilter defaultAuthenticationFilter; @Bean public PasswordEncoder getPasswordEncoder() { @@ -54,6 +56,11 @@ public SecurityFilterChain filterChainWithJwt(final HttpSecurity http) throws Ex ) .exceptionHandling(error -> error.accessDeniedHandler(accessDeniedHandler)); + http.addFilterBefore( + defaultAuthenticationFilter, + UsernamePasswordAuthenticationFilter.class + ); + http.apply( JwtDsl.jwtDsl( jwtAuthenticationProvider, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/global/error/ErrorCode.java b/backend/core/src/main/java/site/timecapsulearchive/core/global/error/ErrorCode.java index da198085d..72de9db89 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/global/error/ErrorCode.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/global/error/ErrorCode.java @@ -13,6 +13,7 @@ public enum ErrorCode { INPUT_INVALID_TYPE_ERROR(400, "GLOBAL-003", "잘못된 입력 타입입니다."), REQUEST_PARAMETER_NOT_FOUND_ERROR(400, "GLOBAL-004", "입력 파라미터가 존재하지 않습니다."), REQUEST_PARAMETER_TYPE_NOT_MATCH_ERROR(400, "GLOBAL-005", "입력 파라미터의 타입이 올바르지 않습니다."), + REQUEST_DEFAULT_KEY_ERROR(400, "GLOBAL-006", "앱에서 발생한 요청이 아닙니다."), //jwt INVALID_TOKEN_ERROR(400, "AUTH-001", "jwt 토큰이 유효하지 않습니다."), diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/global/security/filter/DefaultAuthenticationFilter.java b/backend/core/src/main/java/site/timecapsulearchive/core/global/security/filter/DefaultAuthenticationFilter.java new file mode 100644 index 000000000..8db5276fa --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/global/security/filter/DefaultAuthenticationFilter.java @@ -0,0 +1,56 @@ +package site.timecapsulearchive.core.global.security.filter; + +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.Order; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import site.timecapsulearchive.core.global.error.ErrorCode; +import site.timecapsulearchive.core.global.error.ErrorResponse; +import site.timecapsulearchive.core.global.security.property.DefaultKeyProperties; + +@Slf4j +@Component +@RequiredArgsConstructor +public class DefaultAuthenticationFilter extends OncePerRequestFilter { + + private final DefaultKeyProperties defaultKeyProperties; + + @Override + @Order(1) + protected void doFilterInternal( + HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain + ) throws ServletException, IOException { + String requestKey = request.getHeader("Default-Key"); + + if (requestKey == null || !requestKey.equals(defaultKeyProperties.defaultKey())) { + log.warn("Invalid default key provided: {}", requestKey); + + final ErrorResponse errorResponse = ErrorResponse.fromErrorCode( + ErrorCode.REQUEST_DEFAULT_KEY_ERROR + ); + + response.setStatus(ErrorCode.REQUEST_DEFAULT_KEY_ERROR.getStatus()); + response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); + + response.getWriter().write( + new ObjectMapper().writeValueAsString( + errorResponse + ) + ); + + return; + } + + filterChain.doFilter(request, response); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/global/security/jwt/JwtAuthenticationFilter.java b/backend/core/src/main/java/site/timecapsulearchive/core/global/security/jwt/JwtAuthenticationFilter.java index 3f6b0387f..f5410ab62 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/global/security/jwt/JwtAuthenticationFilter.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/global/security/jwt/JwtAuthenticationFilter.java @@ -8,6 +8,7 @@ import java.io.IOException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.core.annotation.Order; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationManager; @@ -32,6 +33,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { private final RequestMatcher notRequireAuthenticationMatcher; @Override + @Order(2) protected void doFilterInternal( final HttpServletRequest request, final HttpServletResponse response, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/global/security/property/DefaultKeyProperties.java b/backend/core/src/main/java/site/timecapsulearchive/core/global/security/property/DefaultKeyProperties.java new file mode 100644 index 000000000..408bd3938 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/global/security/property/DefaultKeyProperties.java @@ -0,0 +1,10 @@ +package site.timecapsulearchive.core.global.security.property; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "app") +public record DefaultKeyProperties( + String defaultKey +) { + +} From 82e51f889be9baf01d8f91552cd9cad4e489b23b Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Mon, 26 Aug 2024 14:42:01 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20application.yml=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/core/src/main/resources/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/core/src/main/resources/config b/backend/core/src/main/resources/config index 10bd3becb..92430a653 160000 --- a/backend/core/src/main/resources/config +++ b/backend/core/src/main/resources/config @@ -1 +1 @@ -Subproject commit 10bd3becb428fd412e8cec1bcb108b98444a8e3a +Subproject commit 92430a6534f7b84d7e61429f700723f153fef3fe From 44113dbb472974f188bc24da4957b2f955320e6e Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Mon, 26 Aug 2024 15:24:19 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20JWT=20filter=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/TestMockMvcSecurityConfig.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/config/TestMockMvcSecurityConfig.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/config/TestMockMvcSecurityConfig.java index 794d15700..b74fa25bd 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/common/config/TestMockMvcSecurityConfig.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/config/TestMockMvcSecurityConfig.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; +import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.ProviderManager; @@ -27,8 +28,10 @@ import site.timecapsulearchive.core.global.api.limit.ApiLimitCheckInterceptor; import site.timecapsulearchive.core.global.api.limit.ApiLimitProperties; import site.timecapsulearchive.core.global.api.limit.ApiUsageCacheRepository; +import site.timecapsulearchive.core.global.security.filter.DefaultAuthenticationFilter; import site.timecapsulearchive.core.global.security.jwt.JwtAuthenticationFilter; import site.timecapsulearchive.core.global.security.jwt.JwtAuthenticationProvider; +import site.timecapsulearchive.core.global.security.property.DefaultKeyProperties; @EnableWebSecurity @TestConfiguration @@ -56,6 +59,7 @@ public SecurityFilterChain filterChainWithJwt(final HttpSecurity http) throws Ex .anyRequest().hasRole(Role.USER.name()) ) .authenticationProvider(jwtAuthenticationProvider()) + .addFilterBefore(testDefaultAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore( jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class @@ -78,6 +82,19 @@ public JwtAuthenticationProvider jwtAuthenticationProvider() { } @Bean + public DefaultKeyProperties testDefaultKeyProperties() { + return new DefaultKeyProperties("testDefaultKey"); + } + + @Bean + @Order(1) + public DefaultAuthenticationFilter testDefaultAuthenticationFilter( + ) { + return new DefaultAuthenticationFilter(testDefaultKeyProperties()); + } + + @Bean + @Order(2) public JwtAuthenticationFilter jwtAuthenticationFilter() { return new JwtAuthenticationFilter(authenticationManager(), new ObjectMapper(), notRequireAuthenticationMatcher());