Skip to content

Commit

Permalink
Merge pull request #654 from tukcomCD2024/fix/filter-B-#653
Browse files Browse the repository at this point in the history
fix: 앱 요청 식별 필터 추가
  • Loading branch information
seokho-1116 authored Aug 29, 2024
2 parents 5ae9518 + 44113db commit 449f5ef
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 48 deletions.
24 changes: 7 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,10 @@ An<u>Droid</u> + <u>Blossom</u> </h2>
<br>**당신만의 매력적인 이미지****움직이는 귀여운 캐릭터 타임캡슐 스킨**을 직접 제작해보세요.
<br>_우리 앱으로 **과거****현재**, **미래**를 연결하는 특별한 경험을 즐기실 수 있습니다._

## 🎨 Figma
### 작업 중...
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/0666eae8-fca0-4f01-8bbd-57a82b988a5d" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/755eee1f-5d0d-4219-addd-e82865183c65" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/89d71e74-1790-42e7-878b-2c5ef354229b" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/1553ac60-466c-4bf8-b2ef-4cb43001ee2e" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/8d1ec9e0-9993-4379-9324-a69ab6c19ed6" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/82c76117-14f0-4621-9638-47e5142256f6" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/4d1f7a0a-14ea-4762-81ab-3063c953a120" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/fe886e4d-7d59-417e-8bd8-156e493a97a9" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/f32c9b95-3b4b-4109-93e8-0f4969fe283c" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/2d595cb4-8654-4a33-b024-da59b1451e9a" width="190px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/66acc665-0f44-4de7-ac0e-421f5ecefc47" width="190px" height="400px">
## 🎨 디자인
<img src="https://github.com/user-attachments/assets/f93e805b-749d-4128-b2ce-b32df4a8fb29" width="230px" height="440px">
<img src="https://github.com/user-attachments/assets/d39044b2-2a6e-4974-b769-26a7cbd3ab21" width="230px" height="440px">
<img src="https://github.com/user-attachments/assets/5042e84e-6642-41a1-82c2-ced5303069bf" width="230px" height="440px">

## 🛠 개발 시스템 구성도
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/1932a1c6-d8f2-4c11-82f4-1a602852bcd3">
Expand All @@ -47,8 +38,8 @@ An<u>Droid</u> + <u>Blossom</u> </h2>
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/f7e3625c-389b-4a7b-95b7-b56117309e79" width="260px" height="350px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/68e6f0f5-5281-469e-b637-d343ac7fcfc7" width="260px" height="350px">

## ⚙️ 운용 환경
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/243bd68b-80f4-47ae-872c-a0e921c211f4">
## ⚙️ 운영 환경
<img src="https://github.com/user-attachments/assets/fcba2bff-1807-41d6-b4e2-2db8e240c4e5">

## 🛢 ERD
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/59e02146-a89c-4a71-b31a-debef38cb30d">
Expand All @@ -57,5 +48,4 @@ An<u>Droid</u> + <u>Blossom</u> </h2>
<a href="https://github.com/tukcomCD2024/DroidBlossom/wiki" style="font-size: 25px">ARchive 위키</a>

## 🦾 기술 스택
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/10a4a325-7e95-43eb-877c-c8e6f81e9d91" width="400px" height="400px">
<img src="https://github.com/tukcomCD2024/DroidBlossom/assets/68144059/ce1b280f-622f-48bb-8f1d-7ad05732f533" width="400px" height="400px">
<img src="https://github.com/user-attachments/assets/2a68bbc1-bdb9-456d-b3f7-abcbd5d8c619">
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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() {
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 토큰이 유효하지 않습니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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
) {

}
2 changes: 1 addition & 1 deletion backend/core/src/main/resources/config
63 changes: 35 additions & 28 deletions backend/core/src/main/resources/logback-spring.xml
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 콘솔 출력 설정 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{36} - %msg%n
</Pattern>
<Pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
<appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/info.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n
</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/info.%d{yyyy-MM-dd}.%i.log.gz
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>180</maxHistory>
</rollingPolicy>
</appender>
<root level="INFO">
<logger name="org.hibernate" level="error" additivity="false">
<appender-ref ref="INFO_LOG"/>
</logger>
<appender-ref ref="INFO_LOG"/>
</root>
</configuration>

<!-- local 프로파일일 때 콘솔에만 로그 출력 -->
<springProfile name="local">
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</springProfile>

<!-- local 프로파일이 아닐 때 로그를 파일로 출력 -->
<springProfile name="!local">
<appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/info.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>180</maxHistory>
</rollingPolicy>
</appender>

<root level="INFO">
<appender-ref ref="INFO_LOG" />
</root>
</springProfile>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion backend/notification/src/main/resources/config

0 comments on commit 449f5ef

Please sign in to comment.