From 47d37f2c88e136faf814592e9b1fc1ae24621e00 Mon Sep 17 00:00:00 2001 From: swthewhite Date: Mon, 29 Dec 2025 16:15:57 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix/#76:=20=EB=AA=A8=EB=8B=88=ED=84=B0?= =?UTF-8?q?=EB=A7=81=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=97=94=EB=93=9C?= =?UTF-8?q?=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=B6=94=EA=B0=80=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/project/common/util/WebSecurityUrl.java | 5 +++++ .../java/com/project/config/security/SecurityConfig.java | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/com/project/common/util/WebSecurityUrl.java b/src/main/java/com/project/common/util/WebSecurityUrl.java index dc15b21..823f7ca 100644 --- a/src/main/java/com/project/common/util/WebSecurityUrl.java +++ b/src/main/java/com/project/common/util/WebSecurityUrl.java @@ -11,6 +11,7 @@ private WebSecurityUrl() { public static final String LOCAL_LOGIN_ENDPOINT = "/oauth/local/login"; public static final String LOCAL_SIGN_ENDPOINT = "/oauth/local/sign"; private static final String[] HEALTH_CHECK_ENDPOINTS = {"/health", "/actuator/health"}; + private static final String[] ACTUATOR_ENDPOINTS = {"/actuator/prometheus", "/actuator/metrics", "/actuator/info"}; private static final String[] READ_ONLY_PUBLIC_ENDPOINTS = {"/favicon.ico"}; private static final String[] ANONYMOUS_ENDPOINTS = { LOGIN_ENDPOINT, REISSUE_ENDPOINT, LOCAL_LOGIN_ENDPOINT, LOCAL_SIGN_ENDPOINT}; @@ -19,6 +20,10 @@ public static String[] getHealthCheckEndpoints() { return HEALTH_CHECK_ENDPOINTS.clone(); } + public static String[] getActuatorEndpoints() { + return ACTUATOR_ENDPOINTS.clone(); + } + public static String[] getReadOnlyPublicEndpoints() { return READ_ONLY_PUBLIC_ENDPOINTS.clone(); } diff --git a/src/main/java/com/project/config/security/SecurityConfig.java b/src/main/java/com/project/config/security/SecurityConfig.java index 9a32c75..f339017 100644 --- a/src/main/java/com/project/config/security/SecurityConfig.java +++ b/src/main/java/com/project/config/security/SecurityConfig.java @@ -18,6 +18,7 @@ import static com.project.common.util.WebSecurityUrl.getReadOnlyPublicEndpoints; import static com.project.common.util.WebSecurityUrl.getHealthCheckEndpoints; +import static com.project.common.util.WebSecurityUrl.getActuatorEndpoints; import static com.project.common.util.WebSecurityUrl.LOGIN_ENDPOINT; import static com.project.common.util.WebSecurityUrl.REISSUE_ENDPOINT; import static com.project.common.util.WebSecurityUrl.LOCAL_LOGIN_ENDPOINT; @@ -55,6 +56,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .requestMatchers("/slack/**").permitAll() .requestMatchers(HttpMethod.GET, getReadOnlyPublicEndpoints()).permitAll() .requestMatchers(getHealthCheckEndpoints()).permitAll() + .requestMatchers(getActuatorEndpoints()).permitAll() .requestMatchers(LOCAL_LOGIN_ENDPOINT).permitAll() .requestMatchers(LOCAL_SIGN_ENDPOINT).permitAll() .requestMatchers(LOGIN_ENDPOINT).permitAll() From 892560340ad0cf704250a7d4a9f54a4636c171d7 Mon Sep 17 00:00:00 2001 From: swthewhite Date: Mon, 29 Dec 2025 16:35:11 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix/#76:=20JWT=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8=ED=8A=B8=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/common/security/filter/JwtAuthenticationFilter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/project/common/security/filter/JwtAuthenticationFilter.java b/src/main/java/com/project/common/security/filter/JwtAuthenticationFilter.java index 7838b97..72a5387 100644 --- a/src/main/java/com/project/common/security/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/project/common/security/filter/JwtAuthenticationFilter.java @@ -30,6 +30,7 @@ import static com.project.common.util.WebSecurityUrl.getHealthCheckEndpoints; import static com.project.common.util.WebSecurityUrl.getReadOnlyPublicEndpoints; +import static com.project.common.util.WebSecurityUrl.getActuatorEndpoints; import static com.project.common.util.WebSecurityUrl.getAnonymousEndpoints; @Slf4j @@ -44,6 +45,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { protected static final String[] PUBLIC_ENDPOINTS = Stream.of( getHealthCheckEndpoints(), + getActuatorEndpoints(), getReadOnlyPublicEndpoints() ).flatMap(Arrays::stream).toArray(String[]::new); From 38408c7174402b399047d474e4c38dc2bb40f5d5 Mon Sep 17 00:00:00 2001 From: swthewhite Date: Mon, 29 Dec 2025 16:39:42 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix/#76:=20=EB=AA=A8=EB=8B=88=ED=84=B0?= =?UTF-8?q?=EB=A7=81=20=EC=84=9C=EB=B2=84=EB=A7=8C=20actuator=EC=97=90=20?= =?UTF-8?q?=EC=A0=91=EA=B7=BC=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ActuatorAuthorizationManager.java | 35 +++++++++++++++++++ .../config/security/SecurityConfig.java | 3 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/project/config/security/ActuatorAuthorizationManager.java diff --git a/src/main/java/com/project/config/security/ActuatorAuthorizationManager.java b/src/main/java/com/project/config/security/ActuatorAuthorizationManager.java new file mode 100644 index 0000000..ec62559 --- /dev/null +++ b/src/main/java/com/project/config/security/ActuatorAuthorizationManager.java @@ -0,0 +1,35 @@ +package com.project.config.security; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.access.intercept.RequestAuthorizationContext; +import org.springframework.stereotype.Component; + +import java.util.function.Supplier; + +@Component +public class ActuatorAuthorizationManager implements AuthorizationManager { + + private final String monitoringHost; + + public ActuatorAuthorizationManager(@Value("${LOKI_URI:localhost}") String monitoringHost) { + this.monitoringHost = monitoringHost; + } + + @Override + public AuthorizationDecision check(Supplier authenticationSupplier, RequestAuthorizationContext context) { + HttpServletRequest request = context.getRequest(); + String remoteAddr = request.getRemoteAddr(); + + boolean isAllowed = isLocalhost(remoteAddr) || monitoringHost.equals(remoteAddr); + + return new AuthorizationDecision(isAllowed); + } + + private boolean isLocalhost(String ip) { + return "127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip) || "localhost".equals(ip); + } +} diff --git a/src/main/java/com/project/config/security/SecurityConfig.java b/src/main/java/com/project/config/security/SecurityConfig.java index f339017..b0da54a 100644 --- a/src/main/java/com/project/config/security/SecurityConfig.java +++ b/src/main/java/com/project/config/security/SecurityConfig.java @@ -34,6 +34,7 @@ public class SecurityConfig { private final JwtAuthenticationFilter jwtAuthenticationFilter; private final AccessDeniedHandler accessDeniedHandler; private final AuthenticationEntryPoint authenticationEntryPoint; + private final ActuatorAuthorizationManager actuatorAuthorizationManager; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { @@ -56,7 +57,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .requestMatchers("/slack/**").permitAll() .requestMatchers(HttpMethod.GET, getReadOnlyPublicEndpoints()).permitAll() .requestMatchers(getHealthCheckEndpoints()).permitAll() - .requestMatchers(getActuatorEndpoints()).permitAll() + .requestMatchers(getActuatorEndpoints()).access(actuatorAuthorizationManager) .requestMatchers(LOCAL_LOGIN_ENDPOINT).permitAll() .requestMatchers(LOCAL_SIGN_ENDPOINT).permitAll() .requestMatchers(LOGIN_ENDPOINT).permitAll()