From e31cf9b973910de5cad6277684977f2db5effd41 Mon Sep 17 00:00:00 2001 From: binchoo <079111w@gmail.com> Date: Sat, 24 Sep 2022 12:49:05 +0900 Subject: [PATCH] Use spring security for api-key validation --- .../paimonganyu-skill/build.gradle | 2 +- .../configs/security/SecurityConfig.java | 31 ++++++++++++++ .../securities/ApiKeyValidationFilter.java | 42 +++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 PaimonGanyu/paimonganyu-app/paimonganyu-skill/src/main/java/org/binchoo/paimonganyu/chatbot/configs/security/SecurityConfig.java create mode 100644 PaimonGanyu/paimonganyu-app/paimonganyu-skill/src/main/java/org/binchoo/paimonganyu/chatbot/securities/ApiKeyValidationFilter.java diff --git a/PaimonGanyu/paimonganyu-app/paimonganyu-skill/build.gradle b/PaimonGanyu/paimonganyu-app/paimonganyu-skill/build.gradle index bb3c147..33389e7 100644 --- a/PaimonGanyu/paimonganyu-app/paimonganyu-skill/build.gradle +++ b/PaimonGanyu/paimonganyu-app/paimonganyu-skill/build.gradle @@ -7,7 +7,7 @@ dependencies { implementation project(':paimonganyu-infra') implementation project(':ikakao') - implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-security' testImplementation(testFixtures(project(':paimonganyu-domain'))) testImplementation('org.springframework.boot:spring-boot-starter-test') { diff --git a/PaimonGanyu/paimonganyu-app/paimonganyu-skill/src/main/java/org/binchoo/paimonganyu/chatbot/configs/security/SecurityConfig.java b/PaimonGanyu/paimonganyu-app/paimonganyu-skill/src/main/java/org/binchoo/paimonganyu/chatbot/configs/security/SecurityConfig.java new file mode 100644 index 0000000..327cc11 --- /dev/null +++ b/PaimonGanyu/paimonganyu-app/paimonganyu-skill/src/main/java/org/binchoo/paimonganyu/chatbot/configs/security/SecurityConfig.java @@ -0,0 +1,31 @@ +package org.binchoo.paimonganyu.chatbot.configs.security; + +import org.binchoo.paimonganyu.chatbot.securities.ApiKeyValidationFilter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; + +/** + * @author jbinchoo + * @since 2022/09/24 + */ +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Value("${auth.apikey}") + private String expectedApiKey; + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/ikakao/**") + .authorizeRequests().anyRequest().permitAll() + .and() + .addFilterBefore(new ApiKeyValidationFilter(expectedApiKey), BasicAuthenticationFilter.class) + .csrf().disable(); + } +} diff --git a/PaimonGanyu/paimonganyu-app/paimonganyu-skill/src/main/java/org/binchoo/paimonganyu/chatbot/securities/ApiKeyValidationFilter.java b/PaimonGanyu/paimonganyu-app/paimonganyu-skill/src/main/java/org/binchoo/paimonganyu/chatbot/securities/ApiKeyValidationFilter.java new file mode 100644 index 0000000..5faa698 --- /dev/null +++ b/PaimonGanyu/paimonganyu-app/paimonganyu-skill/src/main/java/org/binchoo/paimonganyu/chatbot/securities/ApiKeyValidationFilter.java @@ -0,0 +1,42 @@ +package org.binchoo.paimonganyu.chatbot.securities; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * @author jbinchoo + * @since 2022/09/24 + */ +public class ApiKeyValidationFilter implements Filter { + + private static final Logger logger = LoggerFactory.getLogger(ApiKeyValidationFilter.class); + private static final String HEADER_X_API_KEY = "X-Api-Key"; + private static final String HEADER_X_FORWARDED_FOR = "X-Forwarded-For"; + + private final String expectedApiKey; + + public ApiKeyValidationFilter(String apiKey) { + this.expectedApiKey = apiKey; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + var httpRequest = (HttpServletRequest) request; + var httpResponse = (HttpServletResponse) response; + + String actualApiKey = httpRequest.getHeader(HEADER_X_API_KEY); + + if (expectedApiKey.equals(actualApiKey)) { + chain.doFilter(request, response); + } else { + httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + String clientIp = httpRequest.getHeader(HEADER_X_FORWARDED_FOR); + logger.warn("[Security] Unauthorized api-key: {} from {}", actualApiKey, clientIp); + } + } +}