From 5d516c95b602b9dc4f47daf412274fa18524339c Mon Sep 17 00:00:00 2001 From: beaniejoy Date: Sat, 15 Apr 2023 21:20:08 +0900 Subject: [PATCH] =?UTF-8?q?[#43]=20feat:=20client=20ip=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - client ip 후보군 enum 생성 - security, logging에 대한 패키지화(infra) --- .../dongnecafe/common/config/SecurityConfig.kt | 6 +++--- .../security/ApiAuthenticationProvider.kt | 1 + .../security/UserDetailsServiceImpl.kt | 1 + .../infra/{ => logging}/HttpLogMessage.kt | 9 +++------ .../ReqResLoggingFilter.kt} | 10 +++++----- .../infra/logging/constant/HttpClientIp.kt | 17 +++++++++++++++++ .../{ => infra}/security/SecurityUser.kt | 2 +- .../config/JwtAuthenticationConfigurer.kt | 4 ++-- .../security/constant/SecurityConstant.kt | 2 +- .../security/filter/JwtAuthenticationFilter.kt | 6 +++--- .../handler/CustomAccessDeniedHandler.kt | 2 +- .../handler/CustomAuthenticationEntryPoint.kt | 2 +- .../utils/logging/HttpServletExtensions.kt | 13 +++++++++++++ .../dongnecafe/utils/logging/LoggingUtils.kt | 7 ------- .../dongnecafe/utils/security/JwtTokenUtils.kt | 4 ++-- .../utils/security/SecurityExtensions.kt | 4 ++-- .../dongnecafe/common/config/SecurityConfig.kt | 6 +++--- 17 files changed, 59 insertions(+), 37 deletions(-) rename dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/{ => logging}/HttpLogMessage.kt (83%) rename dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/{RequestResponseLoggingFilter.kt => logging/ReqResLoggingFilter.kt} (87%) create mode 100644 dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/constant/HttpClientIp.kt rename dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/{ => infra}/security/SecurityUser.kt (87%) rename dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/{ => infra}/security/config/JwtAuthenticationConfigurer.kt (87%) rename dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/{ => infra}/security/constant/SecurityConstant.kt (80%) rename dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/{ => infra}/security/filter/JwtAuthenticationFilter.kt (89%) rename dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/{ => infra}/security/handler/CustomAccessDeniedHandler.kt (93%) rename dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/{ => infra}/security/handler/CustomAuthenticationEntryPoint.kt (93%) delete mode 100644 dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/logging/LoggingUtils.kt diff --git a/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/common/config/SecurityConfig.kt b/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/common/config/SecurityConfig.kt index 51b459f..cb6feba 100644 --- a/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/common/config/SecurityConfig.kt +++ b/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/common/config/SecurityConfig.kt @@ -1,9 +1,9 @@ package io.beaniejoy.dongnecafe.common.config import io.beaniejoy.dongnecafe.utils.security.JwtTokenUtils -import io.beaniejoy.dongnecafe.security.config.JwtAuthenticationConfigurer -import io.beaniejoy.dongnecafe.security.handler.CustomAccessDeniedHandler -import io.beaniejoy.dongnecafe.security.handler.CustomAuthenticationEntryPoint +import io.beaniejoy.dongnecafe.infra.security.config.JwtAuthenticationConfigurer +import io.beaniejoy.dongnecafe.infra.security.handler.CustomAccessDeniedHandler +import io.beaniejoy.dongnecafe.infra.security.handler.CustomAuthenticationEntryPoint import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.security.servlet.PathRequest import org.springframework.context.annotation.Bean diff --git a/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/security/ApiAuthenticationProvider.kt b/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/security/ApiAuthenticationProvider.kt index 29307ab..9ba37e9 100644 --- a/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/security/ApiAuthenticationProvider.kt +++ b/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/security/ApiAuthenticationProvider.kt @@ -1,6 +1,7 @@ package io.beaniejoy.dongnecafe.security import io.beaniejoy.dongnecafe.common.error.constant.ErrorCode +import io.beaniejoy.dongnecafe.infra.security.SecurityUser import mu.KLogging import org.springframework.security.authentication.AuthenticationProvider import org.springframework.security.authentication.BadCredentialsException diff --git a/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/security/UserDetailsServiceImpl.kt b/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/security/UserDetailsServiceImpl.kt index 8b6d771..a349884 100644 --- a/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/security/UserDetailsServiceImpl.kt +++ b/dongne-account-api/src/main/kotlin/io/beaniejoy/dongnecafe/security/UserDetailsServiceImpl.kt @@ -4,6 +4,7 @@ import io.beaniejoy.dongnecafe.common.error.constant.ErrorCode import io.beaniejoy.dongnecafe.common.error.exception.BusinessException import io.beaniejoy.dongnecafe.domain.member.entity.Member import io.beaniejoy.dongnecafe.domain.member.repository.MemberRepository +import io.beaniejoy.dongnecafe.infra.security.SecurityUser import mu.KLogging import org.springframework.security.core.authority.SimpleGrantedAuthority import org.springframework.security.core.userdetails.UserDetailsService diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/HttpLogMessage.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/HttpLogMessage.kt similarity index 83% rename from dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/HttpLogMessage.kt rename to dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/HttpLogMessage.kt index d5415e4..b6c9269 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/HttpLogMessage.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/HttpLogMessage.kt @@ -1,9 +1,6 @@ -package io.beaniejoy.dongnecafe.infra +package io.beaniejoy.dongnecafe.infra.logging -import io.beaniejoy.dongnecafe.utils.logging.getRequestBody -import io.beaniejoy.dongnecafe.utils.logging.getRequestHeaders -import io.beaniejoy.dongnecafe.utils.logging.getRequestParams -import io.beaniejoy.dongnecafe.utils.logging.getResponseBody +import io.beaniejoy.dongnecafe.utils.logging.* import org.springframework.http.HttpStatus import org.springframework.web.util.ContentCachingRequestWrapper import org.springframework.web.util.ContentCachingResponseWrapper @@ -30,7 +27,7 @@ data class HttpLogMessage( httpMethod = requestWrapper.method, requestUri = requestWrapper.requestURI, httpStatus = HttpStatus.valueOf(responseWrapper.status), - clientIp = requestWrapper.remoteAddr, + clientIp = requestWrapper.getClientIp(), elapsedTime = elapsedTime, headers = requestWrapper.getRequestHeaders(), requestParam = requestWrapper.getRequestParams(), diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/RequestResponseLoggingFilter.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/ReqResLoggingFilter.kt similarity index 87% rename from dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/RequestResponseLoggingFilter.kt rename to dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/ReqResLoggingFilter.kt index e83445c..67fddcc 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/RequestResponseLoggingFilter.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/ReqResLoggingFilter.kt @@ -1,4 +1,4 @@ -package io.beaniejoy.dongnecafe.infra +package io.beaniejoy.dongnecafe.infra.logging import mu.KotlinLogging import org.slf4j.MDC @@ -15,7 +15,7 @@ import javax.servlet.http.HttpServletResponse @Component @Order(Ordered.HIGHEST_PRECEDENCE) -class RequestResponseLoggingFilter : OncePerRequestFilter() { +class ReqResLoggingFilter : OncePerRequestFilter() { private val log = KotlinLogging.logger {} companion object { @@ -49,9 +49,9 @@ class RequestResponseLoggingFilter : OncePerRequestFilter() { cachingResponseWrapper.copyBodyToResponse() } catch (e: Exception) { - log.error(e) { "[RequestResponseLoggingFilter] logging 실패" } - } finally { - MDC.remove(REQUEST_ID) + log.error(e) { "[${this::class.simpleName}] Logging 실패" } } + + MDC.remove(REQUEST_ID) } } \ No newline at end of file diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/constant/HttpClientIp.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/constant/HttpClientIp.kt new file mode 100644 index 0000000..e15ef31 --- /dev/null +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/logging/constant/HttpClientIp.kt @@ -0,0 +1,17 @@ +package io.beaniejoy.dongnecafe.infra.logging.constant + +/** + * http request client ip possible enum list + * (ref. https://blog.yevgnenll.me/posts/find-client-ip-from-http-request-header) + * @property headerName String client ip header name + */ +enum class HttpClientIp( + val headerName: String, +) { + X_FORWARDED_FOR("X-Forwarded-For"), + PROXY_CLIENT_IP("Proxy-Client-IP"), + WL_PROXY_CLIENT_IP("WL-Proxy-Client-IP"), + HTTP_X_FORWARDED("HTTP_X_FORWARDED"), + HTTP_X_FORWARDED_FOR("HTTP_X_FORWARDED_FOR"), + HTTP_CLIENT_IP("HTTP_CLIENT_IP") +} \ No newline at end of file diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/SecurityUser.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/SecurityUser.kt similarity index 87% rename from dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/SecurityUser.kt rename to dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/SecurityUser.kt index 17a705d..5f60611 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/SecurityUser.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/SecurityUser.kt @@ -1,4 +1,4 @@ -package io.beaniejoy.dongnecafe.security +package io.beaniejoy.dongnecafe.infra.security import io.beaniejoy.dongnecafe.domain.member.entity.Member import org.springframework.security.core.GrantedAuthority diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/config/JwtAuthenticationConfigurer.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/config/JwtAuthenticationConfigurer.kt similarity index 87% rename from dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/config/JwtAuthenticationConfigurer.kt rename to dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/config/JwtAuthenticationConfigurer.kt index 524b744..faa1f85 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/config/JwtAuthenticationConfigurer.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/config/JwtAuthenticationConfigurer.kt @@ -1,6 +1,6 @@ -package io.beaniejoy.dongnecafe.security.config +package io.beaniejoy.dongnecafe.infra.security.config -import io.beaniejoy.dongnecafe.security.filter.JwtAuthenticationFilter +import io.beaniejoy.dongnecafe.infra.security.filter.JwtAuthenticationFilter import io.beaniejoy.dongnecafe.utils.security.JwtTokenUtils import org.springframework.security.config.annotation.SecurityConfigurerAdapter import org.springframework.security.config.annotation.web.builders.HttpSecurity diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/constant/SecurityConstant.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/constant/SecurityConstant.kt similarity index 80% rename from dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/constant/SecurityConstant.kt rename to dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/constant/SecurityConstant.kt index 9371644..070313d 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/constant/SecurityConstant.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/constant/SecurityConstant.kt @@ -1,4 +1,4 @@ -package io.beaniejoy.dongnecafe.security.constant +package io.beaniejoy.dongnecafe.infra.security.constant object SecurityConstant { const val BEARER = "Bearer" diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/filter/JwtAuthenticationFilter.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/filter/JwtAuthenticationFilter.kt similarity index 89% rename from dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/filter/JwtAuthenticationFilter.kt rename to dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/filter/JwtAuthenticationFilter.kt index 6adabd5..2d6776a 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/filter/JwtAuthenticationFilter.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/filter/JwtAuthenticationFilter.kt @@ -1,8 +1,8 @@ -package io.beaniejoy.dongnecafe.security.filter +package io.beaniejoy.dongnecafe.infra.security.filter import io.beaniejoy.dongnecafe.utils.security.JwtTokenUtils -import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.BEARER -import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.WHITESPACE +import io.beaniejoy.dongnecafe.infra.security.constant.SecurityConstant.BEARER +import io.beaniejoy.dongnecafe.infra.security.constant.SecurityConstant.WHITESPACE import mu.KotlinLogging import org.springframework.http.HttpHeaders import org.springframework.security.core.context.SecurityContextHolder diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/handler/CustomAccessDeniedHandler.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/handler/CustomAccessDeniedHandler.kt similarity index 93% rename from dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/handler/CustomAccessDeniedHandler.kt rename to dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/handler/CustomAccessDeniedHandler.kt index 5c6701e..8069005 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/handler/CustomAccessDeniedHandler.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/handler/CustomAccessDeniedHandler.kt @@ -1,4 +1,4 @@ -package io.beaniejoy.dongnecafe.security.handler +package io.beaniejoy.dongnecafe.infra.security.handler import mu.KLogging import org.springframework.security.access.AccessDeniedException diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/handler/CustomAuthenticationEntryPoint.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/handler/CustomAuthenticationEntryPoint.kt similarity index 93% rename from dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/handler/CustomAuthenticationEntryPoint.kt rename to dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/handler/CustomAuthenticationEntryPoint.kt index 93b0287..c3361dd 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/security/handler/CustomAuthenticationEntryPoint.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/infra/security/handler/CustomAuthenticationEntryPoint.kt @@ -1,4 +1,4 @@ -package io.beaniejoy.dongnecafe.security.handler +package io.beaniejoy.dongnecafe.infra.security.handler import mu.KLogging import org.springframework.security.core.AuthenticationException diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/logging/HttpServletExtensions.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/logging/HttpServletExtensions.kt index 121ad71..a7a1ef7 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/logging/HttpServletExtensions.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/logging/HttpServletExtensions.kt @@ -1,6 +1,7 @@ package io.beaniejoy.dongnecafe.utils.logging import com.google.gson.Gson +import io.beaniejoy.dongnecafe.infra.logging.constant.HttpClientIp import org.springframework.web.util.ContentCachingRequestWrapper import org.springframework.web.util.ContentCachingResponseWrapper import javax.servlet.http.HttpServletRequest @@ -22,6 +23,18 @@ fun HttpServletRequest.getRequestParams(): String { }.entries.joinToString("&") } +fun HttpServletRequest.getClientIp(): String { + HttpClientIp.values().forEach { clientIpHeader -> + this.getHeader(clientIpHeader.headerName).also { + if (it.isNullOrBlank().not() && "unknown".equals(it, true).not()) { + return it + } + } + } + + return this.remoteAddr +} + fun ContentCachingRequestWrapper.getRequestBody(): String { return this.contentAsByteArray.toString(Charsets.UTF_8) } diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/logging/LoggingUtils.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/logging/LoggingUtils.kt deleted file mode 100644 index 2e8b3c2..0000000 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/logging/LoggingUtils.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.beaniejoy.dongnecafe.utils.logging - -class LoggingUtils { - companion object { - - } -} \ No newline at end of file diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/security/JwtTokenUtils.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/security/JwtTokenUtils.kt index 21e53bf..81c20fd 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/security/JwtTokenUtils.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/security/JwtTokenUtils.kt @@ -1,7 +1,7 @@ package io.beaniejoy.dongnecafe.utils.security -import io.beaniejoy.dongnecafe.security.SecurityUser -import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.JWT_AUTHORITIES_KEY +import io.beaniejoy.dongnecafe.infra.security.SecurityUser +import io.beaniejoy.dongnecafe.infra.security.constant.SecurityConstant.JWT_AUTHORITIES_KEY import io.jsonwebtoken.Claims import io.jsonwebtoken.ExpiredJwtException import io.jsonwebtoken.Jwts diff --git a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/security/SecurityExtensions.kt b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/security/SecurityExtensions.kt index 74250ab..b4b6c7c 100644 --- a/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/security/SecurityExtensions.kt +++ b/dongne-common/src/main/kotlin/io/beaniejoy/dongnecafe/utils/security/SecurityExtensions.kt @@ -1,7 +1,7 @@ package io.beaniejoy.dongnecafe.utils.security -import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.ANONYMOUS_USER -import io.beaniejoy.dongnecafe.security.constant.SecurityConstant.ROLE_ANONYMOUS +import io.beaniejoy.dongnecafe.infra.security.constant.SecurityConstant.ANONYMOUS_USER +import io.beaniejoy.dongnecafe.infra.security.constant.SecurityConstant.ROLE_ANONYMOUS import org.springframework.security.core.Authentication fun Authentication.getAuthPrincipal() : String? { diff --git a/dongne-service-api/src/main/kotlin/io/beaniejoy/dongnecafe/common/config/SecurityConfig.kt b/dongne-service-api/src/main/kotlin/io/beaniejoy/dongnecafe/common/config/SecurityConfig.kt index 8c831d8..8529490 100644 --- a/dongne-service-api/src/main/kotlin/io/beaniejoy/dongnecafe/common/config/SecurityConfig.kt +++ b/dongne-service-api/src/main/kotlin/io/beaniejoy/dongnecafe/common/config/SecurityConfig.kt @@ -1,9 +1,9 @@ package io.beaniejoy.dongnecafe.common.config -import io.beaniejoy.dongnecafe.security.config.JwtAuthenticationConfigurer +import io.beaniejoy.dongnecafe.infra.security.config.JwtAuthenticationConfigurer import io.beaniejoy.dongnecafe.utils.security.JwtTokenUtils -import io.beaniejoy.dongnecafe.security.handler.CustomAccessDeniedHandler -import io.beaniejoy.dongnecafe.security.handler.CustomAuthenticationEntryPoint +import io.beaniejoy.dongnecafe.infra.security.handler.CustomAccessDeniedHandler +import io.beaniejoy.dongnecafe.infra.security.handler.CustomAuthenticationEntryPoint import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.security.servlet.PathRequest import org.springframework.context.annotation.Bean