Browse Source

feat: security 구성

pull/6/head
지대한 8 months ago
parent
commit
36d78d82c5
  1. 5
      app/kac-app/build.gradle
  2. 3
      app/kac-app/src/main/java/kr/co/palnet/kac/app/KacAppApplication.java
  3. 53
      app/kac-app/src/main/java/kr/co/palnet/kac/app/core/security/AppSecurityConfig.java
  4. 7
      app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrBasRepository.java
  5. 6
      common/core/src/main/java/kr/co/palnet/kac/core/exception/BaseException.java
  6. 11
      common/security/build.gradle
  7. 90
      common/security/src/main/java/kr/co/palnet/kac/config/security/SecurityConfig.java
  8. 23
      common/security/src/main/java/kr/co/palnet/kac/config/security/exception/BaseAccessDeniedHandler.java
  9. 25
      common/security/src/main/java/kr/co/palnet/kac/config/security/exception/BaseAuthenticationEntryPoint.java
  10. 84
      common/security/src/main/java/kr/co/palnet/kac/config/security/exception/BaseAuthenticationException.java
  11. 83
      common/security/src/main/java/kr/co/palnet/kac/config/security/exception/BaseAuthenticationExceptionHandler.java
  12. 75
      common/security/src/main/java/kr/co/palnet/kac/config/security/filter/JwtCheckFilter.java
  13. 66
      common/security/src/main/java/kr/co/palnet/kac/config/security/filter/JwtLoginFilter.java
  14. 26
      common/security/src/main/java/kr/co/palnet/kac/config/security/message/AuthErrorMessageSourceConfig.java
  15. 19
      common/security/src/main/java/kr/co/palnet/kac/config/security/model/AuthErrorRS.java
  16. 49
      common/security/src/main/java/kr/co/palnet/kac/config/security/model/BaseAuthErrorCode.java
  17. 89
      common/security/src/main/java/kr/co/palnet/kac/config/security/model/BaseUserDetails.java
  18. 15
      common/security/src/main/java/kr/co/palnet/kac/config/security/model/UserLoginForm.java
  19. 28
      common/security/src/main/java/kr/co/palnet/kac/config/security/service/BaseUserDetailsService.java
  20. 75
      common/security/src/main/java/kr/co/palnet/kac/config/security/util/JwtUtil.java
  21. 1
      common/security/src/main/java/lombok.config
  22. 6
      common/security/src/main/resources/messages/errors/auth_error.properties
  23. 6
      common/security/src/main/resources/messages/errors/auth_error_en.properties
  24. 3
      common/util/build.gradle
  25. 52
      common/util/src/main/java/kr/co/palnet/kac/util/ObjectMapperUtils.java
  26. 1
      data/com/build.gradle
  27. 27
      data/pty/build.gradle
  28. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCrtfyhpBas.java
  29. 5
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrBas.java
  30. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrConectHist.java
  31. 11
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrDtl.java
  32. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrGroup.java
  33. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyGroupBas.java
  34. 1
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtySnsLoginRel.java
  35. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsAgreeTxn.java
  36. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsBas.java
  37. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsDtl.java
  38. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCrtfyhpBasRepository.java
  39. 11
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrBasRepository.java
  40. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrConectHistRepository.java
  41. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrDtlRepository.java
  42. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrGroupRepository.java
  43. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java
  44. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtySnsLoginRelRepository.java
  45. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsAgreeTxnRepository.java
  46. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsBasRepository.java
  47. 0
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsDtlRepository.java
  48. 19
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyCstmrDomainService.java
  49. 6
      data/user/build.gradle
  50. 5
      http-client/http-client.env.json
  51. 19
      http-client/http/auth.http
  52. 27
      http-client/http/code.http
  53. 2
      web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeDTO.java
  54. 2
      web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeGroupDTO.java
  55. 2
      web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeGroupRS.java
  56. 2
      web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeLangDTO.java
  57. 2
      web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeRS.java
  58. 20
      web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/service/ComCodeService.java

5
app/kac-app/build.gradle

@ -12,12 +12,12 @@ dependencies {
implementation "$boot:spring-boot-starter-web"
// security
implementation "$boot:spring-boot-starter-security"
implementation "com.auth0:java-jwt:4.4.0"
// implementation "com.auth0:java-jwt:4.4.0"
// db
runtimeOnly "com.mysql:mysql-connector-j"
implementation "org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4:1.16"
// jpa
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation "$boot:spring-boot-starter-data-jpa"
// querydsl
implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta"
@ -36,6 +36,7 @@ dependencies {
implementation project(":common-core")
implementation project(":common-util")
implementation project(":common-security")
implementation project(":web-api-com")
// TDOO: ...
compileOnly project(":data-com")

3
app/kac-app/src/main/java/kr/co/palnet/kac/app/KacAppApplication.java

@ -7,7 +7,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = {
"kr.co.palnet.kac.app",
"kr.co.palnet.kac.data",
"kr.co.palnet.kac.api"
"kr.co.palnet.kac.api",
"kr.co.palnet.kac.config"
})
public class KacAppApplication {
public static void main(String[] args) {

53
app/kac-app/src/main/java/kr/co/palnet/kac/app/core/security/AppSecurityConfig.java

@ -0,0 +1,53 @@
package kr.co.palnet.kac.app.core.security;
import kr.co.palnet.kac.config.security.SecurityConfig;
import kr.co.palnet.kac.config.security.exception.BaseAccessDeniedHandler;
import kr.co.palnet.kac.config.security.exception.BaseAuthenticationEntryPoint;
import kr.co.palnet.kac.config.security.service.BaseUserDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
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.WebSecurityCustomizer;
import org.springframework.security.web.SecurityFilterChain;
@Slf4j
@EnableWebSecurity
@Configuration
public class AppSecurityConfig extends SecurityConfig {
// 시큐리티 적용 안하는 URL 목록
private final String[] IGNORE_URL = {};
private final String[] USER_URL = {};
public AppSecurityConfig(BaseUserDetailsService baseUserDetailsService, BaseAuthenticationEntryPoint baseAuthenticationEntryPoint, BaseAccessDeniedHandler baseAccessDeniedHandler) {
super(baseUserDetailsService, baseAuthenticationEntryPoint, baseAccessDeniedHandler);
}
@Override
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
this.setDefaultHttpSecurity(http);
http
.authorizeHttpRequests(authz ->
authz
.requestMatchers(USER_URL).hasRole("USER")
.anyRequest().authenticated()
)
;
return http.build();
}
@Bean
public WebSecurityCustomizer appWebSecurityCustomizer() {
return web -> web.ignoring()
.requestMatchers(IGNORE_URL);
}
}

7
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrBasRepository.java

@ -1,7 +0,0 @@
package kr.co.palnet.kac.data.pty.repository;
import kr.co.palnet.kac.data.pty.model.PtyCstmrBas;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PtyCstmrBasRepository extends JpaRepository<PtyCstmrBas, Integer> {
}

6
common/core/src/main/java/kr/co/palnet/kac/core/exception/BaseException.java

@ -7,7 +7,6 @@ import org.springframework.context.MessageSource;
import java.util.Locale;
@Getter
@Slf4j
public class BaseException extends RuntimeException {
@ -126,11 +125,6 @@ public class BaseException extends RuntimeException {
if (ms == null) {
return BaseErrorCode.UNKNOWN.message();
}
log.debug("############ getErrorMessage : {}", ms);
log.debug("############ getErrorCode : {}", getCode());
log.debug("############ getParamArray : {}", getParamArray());
log.debug("############ ErrorCode.NOT_REGIST_ERROR_CODE.message() : {}", BaseErrorCode.UNKNOWN.message());
log.debug("############ Locale.getDefault() : {}", Locale.getDefault());
return ms.getMessage(getCode(), getParamArray(), BaseErrorCode.UNKNOWN.message(), Locale.getDefault());
}

11
common/security/build.gradle

@ -0,0 +1,11 @@
dependencies {
implementation "$boot:spring-boot-starter-web"
implementation "$boot:spring-boot-starter-security"
implementation "com.auth0:java-jwt:4.4.0"
implementation project(":common-util")
implementation project(":data-pty")
}

90
common/security/src/main/java/kr/co/palnet/kac/config/security/SecurityConfig.java

@ -0,0 +1,90 @@
package kr.co.palnet.kac.config.security;
import kr.co.palnet.kac.config.security.exception.BaseAccessDeniedHandler;
import kr.co.palnet.kac.config.security.exception.BaseAuthenticationEntryPoint;
import kr.co.palnet.kac.config.security.filter.JwtCheckFilter;
import kr.co.palnet.kac.config.security.filter.JwtLoginFilter;
import kr.co.palnet.kac.config.security.service.BaseUserDetailsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
@RequiredArgsConstructor
public abstract class SecurityConfig {
private final BaseUserDetailsService baseUserDetailsService;
private final BaseAuthenticationEntryPoint baseAuthenticationEntryPoint;
private final BaseAccessDeniedHandler baseAccessDeniedHandler;
private final String[] SWAGGER_URI = {
"/swagger-ui/index.html",
"/v3/api-docs",
"/swagger-resources/**",
"/webjars/**",
"/swagger-ui/**"
};
@Bean
PasswordEncoder passwordEncoder() {
// return new BCryptPasswordEncoder();
// TODO 테스트 후 BCryptPasswordEncoder 로 변경
return NoOpPasswordEncoder.getInstance();
}
@Bean
public AuthenticationManager authenticationManager() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(baseUserDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return new ProviderManager(authProvider);
}
@Bean
protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
setDefaultHttpSecurity(http);
http
.authorizeHttpRequests(authz ->
authz
.anyRequest().authenticated()
);
return http.build();
}
public void setDefaultHttpSecurity(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.httpBasic(httpSecurityHttpBasicConfigurer -> httpSecurityHttpBasicConfigurer.authenticationEntryPoint(baseAuthenticationEntryPoint))
.addFilterAt(new JwtLoginFilter(authenticationManager(), baseUserDetailsService), UsernamePasswordAuthenticationFilter.class)
.addFilterAt(new JwtCheckFilter(authenticationManager(), baseUserDetailsService, baseAuthenticationEntryPoint), BasicAuthenticationFilter.class)
.exceptionHandling(exceptionHandlingconfig ->
exceptionHandlingconfig
.authenticationEntryPoint(baseAuthenticationEntryPoint)
.accessDeniedHandler(baseAccessDeniedHandler)
);
}
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return web -> web.ignoring()
.requestMatchers(SWAGGER_URI);
}
}

23
common/security/src/main/java/kr/co/palnet/kac/config/security/exception/BaseAccessDeniedHandler.java

@ -0,0 +1,23 @@
package kr.co.palnet.kac.config.security.exception;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;
import java.io.IOException;
@RequiredArgsConstructor
@Component
public class BaseAccessDeniedHandler implements AccessDeniedHandler {
private final BaseAuthenticationExceptionHandler baseAuthenticationExceptionHandler;
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
baseAuthenticationExceptionHandler.handle(request, response, accessDeniedException);
}
}

25
common/security/src/main/java/kr/co/palnet/kac/config/security/exception/BaseAuthenticationEntryPoint.java

@ -0,0 +1,25 @@
package kr.co.palnet.kac.config.security.exception;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Slf4j
@RequiredArgsConstructor
@Component
public class BaseAuthenticationEntryPoint implements AuthenticationEntryPoint {
private final BaseAuthenticationExceptionHandler baseAuthenticationExceptionHandler;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
baseAuthenticationExceptionHandler.handle(request, response, authException);
}
}

84
common/security/src/main/java/kr/co/palnet/kac/config/security/exception/BaseAuthenticationException.java

@ -0,0 +1,84 @@
package kr.co.palnet.kac.config.security.exception;
import kr.co.palnet.kac.config.security.model.BaseAuthErrorCode;
import lombok.Getter;
import org.springframework.security.core.AuthenticationException;
@Getter
public class BaseAuthenticationException extends AuthenticationException {
private final BaseAuthErrorCode errorCode;
private final Object[] paramArray;
public BaseAuthenticationException() {
this(null, BaseAuthErrorCode.UNAUTHORIZED, (Object[]) null);
}
public BaseAuthenticationException(BaseAuthErrorCode errorCode) {
this(null, errorCode, (Object[]) null);
}
public BaseAuthenticationException(Object[] paramArray) {
this(null, BaseAuthErrorCode.UNAUTHORIZED, paramArray);
}
public BaseAuthenticationException(BaseAuthErrorCode errorCode, Object[] paramArray) {
this(null, errorCode, paramArray);
}
public BaseAuthenticationException(String msg) {
this(msg, BaseAuthErrorCode.UNAUTHORIZED, (Object[]) null);
}
public BaseAuthenticationException(String msg, Object[] paramArray) {
this(msg, BaseAuthErrorCode.UNAUTHORIZED, paramArray);
}
public BaseAuthenticationException(String msg, BaseAuthErrorCode errorCode) {
this(msg, errorCode, (Object[]) null);
}
public BaseAuthenticationException(String msg, BaseAuthErrorCode errorCode, Object[] paramArray) {
super(msg);
this.errorCode = errorCode;
this.paramArray = paramArray;
}
public BaseAuthenticationException(Throwable cause) {
this(null, BaseAuthErrorCode.UNAUTHORIZED, null, cause);
}
public BaseAuthenticationException(String msg, BaseAuthErrorCode errorCode, Throwable cause) {
this(msg, errorCode, null, cause);
}
public BaseAuthenticationException(String msg, Throwable cause) {
this(msg, BaseAuthErrorCode.UNAUTHORIZED, null, cause);
}
public BaseAuthenticationException(Object[] paramArray, Throwable cause) {
this(null, BaseAuthErrorCode.UNAUTHORIZED, paramArray, cause);
}
public BaseAuthenticationException(String msg, Object[] paramArray, Throwable cause) {
this(msg, BaseAuthErrorCode.UNAUTHORIZED, paramArray, cause);
}
public BaseAuthenticationException(BaseAuthErrorCode errorCode, Throwable cause) {
this(null, errorCode, null, cause);
}
public BaseAuthenticationException(BaseAuthErrorCode errorCode, Object[] paramArray, Throwable cause) {
this(null, errorCode, paramArray, cause);
}
public BaseAuthenticationException(String msg, BaseAuthErrorCode errorCode, Object[] paramArray, Throwable cause) {
super(msg, cause);
this.errorCode = errorCode;
this.paramArray = paramArray;
}
public String getCode() {
return errorCode.code();
}
}

83
common/security/src/main/java/kr/co/palnet/kac/config/security/exception/BaseAuthenticationExceptionHandler.java

@ -0,0 +1,83 @@
package kr.co.palnet.kac.config.security.exception;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import kr.co.palnet.kac.config.security.model.BaseAuthErrorCode;
import kr.co.palnet.kac.config.security.model.AuthErrorRS;
import kr.co.palnet.kac.util.ObjectMapperUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.time.Instant;
@Slf4j
@RequiredArgsConstructor
@Component
public class BaseAuthenticationExceptionHandler {
@Qualifier("authErrorMessageSourceAccessor")
private final MessageSourceAccessor authErrorMessageSourceAccessor;
public void handle(HttpServletRequest request, HttpServletResponse response, Exception authException) throws IOException, ServletException {
Object excpetion = request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
if (excpetion == null) {
excpetion = authException;
}
String reqURI = (String) request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI);
if (reqURI == null) {
reqURI = request.getRequestURI();
}
BaseAuthErrorCode errorCode = BaseAuthErrorCode.UNAUTHORIZED;
if (excpetion instanceof BaseAuthenticationException) {
log.debug("BaseAuthenticationException : {}", excpetion.getClass());
BaseAuthenticationException bae = (BaseAuthenticationException) excpetion;
BaseAuthErrorCode baseAuthErrorCode = bae.getErrorCode();
if (baseAuthErrorCode != null) {
errorCode = baseAuthErrorCode;
}
}
if (excpetion instanceof AuthenticationException) {
log.debug("AuthenticationException : {}", excpetion.getClass());
errorCode = BaseAuthErrorCode.INVALID_TOKEN;
AuthenticationException ae = (AuthenticationException) excpetion;
// TODO 종류 별로 ErrrorCode 분기 처리
} else if (excpetion instanceof AccessDeniedException) {
log.debug("AccessDeniedException : {}", excpetion.getClass());
errorCode = BaseAuthErrorCode.UNAUTHORIZED;
AccessDeniedException ad = (AccessDeniedException) excpetion;
// TODO 종류 별로 ErrrorCode 분기 처리
}
AuthErrorRS rs = AuthErrorRS.builder()
.timestamp(Instant.now().toString())
.path(reqURI)
.status(errorCode.status().value())
.error(errorCode.status().getReasonPhrase())
.code(errorCode.code())
.message(authErrorMessageSourceAccessor.getMessage(errorCode.code()))
.build();
response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getOutputStream().write(ObjectMapperUtils.getObjectMapper().writeValueAsBytes(rs));
}
}

75
common/security/src/main/java/kr/co/palnet/kac/config/security/filter/JwtCheckFilter.java

@ -0,0 +1,75 @@
package kr.co.palnet.kac.config.security.filter;
import com.auth0.jwt.exceptions.TokenExpiredException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import kr.co.palnet.kac.config.security.util.JwtUtil;
import kr.co.palnet.kac.config.security.exception.BaseAuthenticationException;
import kr.co.palnet.kac.config.security.model.BaseAuthErrorCode;
import kr.co.palnet.kac.config.security.model.BaseUserDetails;
import kr.co.palnet.kac.config.security.service.BaseUserDetailsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import java.io.IOException;
@Slf4j
public class JwtCheckFilter extends BasicAuthenticationFilter {
private BaseUserDetailsService baseUserDetailsService;
public JwtCheckFilter(AuthenticationManager authenticationManager, BaseUserDetailsService baseUserDetailsService) {
super(authenticationManager);
this.baseUserDetailsService = baseUserDetailsService;
}
public JwtCheckFilter(AuthenticationManager authenticationManager, BaseUserDetailsService baseUserDetailsService, AuthenticationEntryPoint authenticationEntryPoint) {
super(authenticationManager, authenticationEntryPoint);
this.baseUserDetailsService = baseUserDetailsService;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
// super.doFilterInternal(request, response, chain);
String bearer = request.getHeader(HttpHeaders.AUTHORIZATION);
if (bearer == null || !bearer.startsWith("Bearer ")) {
chain.doFilter(request, response);
return;
}
String token = bearer.substring("Bearer ".length());
BaseUserDetails userDetails;
try {
userDetails = JwtUtil.verify(token, "AUTH");
} catch (TokenExpiredException e) {
throw new BaseAuthenticationException(BaseAuthErrorCode.EXPIRED_TOKEN);
} catch (Exception e) {
log.debug(">>> e : {}", e.getClass().getName());
throw new BaseAuthenticationException(BaseAuthErrorCode.INVALID_TOKEN);
}
/*
실시간 처리가 필요할 경우 사용
access token(auth token) 짧게 잡고 refresh token으로 재발급시 DB조회 하도록 구성
UserDetails newUserDetails = baseUserDetailsService.loadUserByUsername(userDetails.getUserId());
*/
// 토큰 자체를 신뢰함.
UsernamePasswordAuthenticationToken userToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities()
);
SecurityContextHolder.getContext().setAuthentication(userToken);
chain.doFilter(request, response);
}
}

66
common/security/src/main/java/kr/co/palnet/kac/config/security/filter/JwtLoginFilter.java

@ -0,0 +1,66 @@
package kr.co.palnet.kac.config.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 kr.co.palnet.kac.config.security.util.JwtUtil;
import kr.co.palnet.kac.config.security.model.UserLoginForm;
import kr.co.palnet.kac.config.security.exception.BaseAuthenticationException;
import kr.co.palnet.kac.config.security.model.BaseAuthErrorCode;
import kr.co.palnet.kac.config.security.model.BaseUserDetails;
import kr.co.palnet.kac.config.security.service.BaseUserDetailsService;
import kr.co.palnet.kac.util.ObjectMapperUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import java.io.IOException;
public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter {
private BaseUserDetailsService baseUserDetailsService;
private ObjectMapper objectMapper = ObjectMapperUtils.getObjectMapper();
public JwtLoginFilter(BaseUserDetailsService baseUserDetailsService) {
setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/v1/login", "POST"));
}
public JwtLoginFilter(AuthenticationManager authenticationManager, BaseUserDetailsService baseUserDetailsService) {
super(authenticationManager);
this.baseUserDetailsService = baseUserDetailsService;
setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/v1/login", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
UserLoginForm userLogin = objectMapper.readValue(request.getInputStream(), UserLoginForm.class);
// TODO 로그인 처리
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
userLogin.getUserId(), userLogin.getPassword(), null
);
return getAuthenticationManager().authenticate(token);
} catch (IOException e) {
throw new BaseAuthenticationException(BaseAuthErrorCode.INVALID_LOGIN);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
BaseUserDetails user = (BaseUserDetails) authResult.getPrincipal();
response.setHeader("Auth-Token", JwtUtil.makeAuthToken(user));
response.setHeader("Refresh-Token", JwtUtil.makeRefreshToken(user));
response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
response.getOutputStream().write(ObjectMapperUtils.getObjectMapper().writeValueAsBytes(user.toMap()));
}
}

26
common/security/src/main/java/kr/co/palnet/kac/config/security/message/AuthErrorMessageSourceConfig.java

@ -0,0 +1,26 @@
package kr.co.palnet.kac.config.security.message;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
@Configuration
public class AuthErrorMessageSourceConfig {
@Bean(name = "authErrorMessageSource")
public MessageSource getAuthErrorMessageSource() {
ReloadableResourceBundleMessageSource authErrorMessageSource = new ReloadableResourceBundleMessageSource();
authErrorMessageSource.setBasenames("classpath:messages/errors/auth_error");
authErrorMessageSource.setDefaultEncoding("UTF-8");
authErrorMessageSource.setCacheSeconds(300);
return authErrorMessageSource;
}
@Bean(name = "authErrorMessageSourceAccessor")
public MessageSourceAccessor authErrorMessageSourceAccessor(@Qualifier("authErrorMessageSource") MessageSource authErrorMessageSource) {
return new MessageSourceAccessor(authErrorMessageSource);
}
}

19
common/security/src/main/java/kr/co/palnet/kac/config/security/model/AuthErrorRS.java

@ -0,0 +1,19 @@
package kr.co.palnet.kac.config.security.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AuthErrorRS {
private String timestamp;
private int status;
private String error;
private String path;
private String message;
private String code;
}

49
common/security/src/main/java/kr/co/palnet/kac/config/security/model/BaseAuthErrorCode.java

@ -0,0 +1,49 @@
package kr.co.palnet.kac.config.security.model;
import org.springframework.http.HttpStatus;
public enum BaseAuthErrorCode {
// 비밀번호를 10회 이상 틀렸습니다. 관리자에게 문의하길 바랍니다.
PASSWORD_OVER_INPUT("AT001", HttpStatus.BAD_REQUEST, "패스워드 입력 제한횟수 초과"),
// 로그인 정보가 올바르지 않습니다.
INVALID_LOGIN("AT002", HttpStatus.BAD_REQUEST, "잘못된 로그인 정보"),
// TODO 로그인 상태에 따른 에러코드 정의 필요
// 로그인이 필요한 서비스 입니다.
NON_TOKEN("AT100", HttpStatus.UNAUTHORIZED, "토큰 없음"),
// 토큰 정보가 올바르지 않습니다.
INVALID_TOKEN("AT101", HttpStatus.UNAUTHORIZED, "잘못된 토큰"),
// 토큰이 만료되었습니다.
EXPIRED_TOKEN("AT102", HttpStatus.UNAUTHORIZED, "만료된 토큰"),
// 권한이 없습니다.
UNAUTHORIZED("AT103", HttpStatus.UNAUTHORIZED, "권한 없음");
private final String code;
private final HttpStatus status;
private final String message;
private BaseAuthErrorCode(String code, HttpStatus status, String message) {
this.code = code;
this.status = status;
this.message = message;
}
public String code() {
return this.code;
}
public String message() {
return this.message;
}
public HttpStatus status() {
return this.status;
}
}

89
common/security/src/main/java/kr/co/palnet/kac/config/security/model/BaseUserDetails.java

@ -0,0 +1,89 @@
package kr.co.palnet.kac.config.security.model;
import kr.co.palnet.kac.data.pty.model.PtyCstmrBas;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.List;
import java.util.Map;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BaseUserDetails implements UserDetails {
// 유저 기본 정보
// sno
private Long cstmrSno;
// id
private String userId;
// password
private String userPswd;
// authorities(role) - 추후 여러권한을 가질 수 있도록 설계 필요
private String cstmrDivCd;
// 계정상태
private String cstmrStatusCd;
@Override
public List<SimpleGrantedAuthority> getAuthorities() {
String role = String.format("ROLE_%s", this.cstmrDivCd);
SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role);
return List.of(authority);
}
@Override
public String getPassword() {
return this.userPswd;
}
@Override
public String getUsername() {
return this.userId;
}
@Override
public boolean isAccountNonExpired() {
return !"DORMANT".equals(this.cstmrStatusCd);
}
@Override
public boolean isAccountNonLocked() {
return !"LOCK".equals(this.cstmrStatusCd);
}
@Override
public boolean isCredentialsNonExpired() {
return !"PWD_EXPIRED".equals(this.cstmrStatusCd);
}
@Override
public boolean isEnabled() {
return "ACTIVE".equals(this.cstmrStatusCd);
}
public static BaseUserDetails toUserDetails(PtyCstmrBas ptyCstmrBas) {
return BaseUserDetails.builder()
.cstmrSno(ptyCstmrBas.getCstmrSno())
.userId(ptyCstmrBas.getUserId())
.userPswd(ptyCstmrBas.getUserPswd())
.cstmrDivCd(ptyCstmrBas.getCstmrDivCd())
.cstmrStatusCd(ptyCstmrBas.getCstmrStatusCd())
.build();
}
public Map<String, Object> toMap() {
return Map.of(
"cstmrSno", this.cstmrSno,
// "cstmrDivCd", this.cstmrDivCd,
// "cstmrStatusCd", this.cstmrStatusCd
"userId", this.userId
);
}
}

15
common/security/src/main/java/kr/co/palnet/kac/config/security/model/UserLoginForm.java

@ -0,0 +1,15 @@
package kr.co.palnet.kac.config.security.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserLoginForm {
private String userId;
private String password;
}

28
common/security/src/main/java/kr/co/palnet/kac/config/security/service/BaseUserDetailsService.java

@ -0,0 +1,28 @@
package kr.co.palnet.kac.config.security.service;
import kr.co.palnet.kac.config.security.model.BaseUserDetails;
import kr.co.palnet.kac.data.pty.model.PtyCstmrBas;
import kr.co.palnet.kac.data.pty.service.PtyCstmrDomainService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@RequiredArgsConstructor
@Service
public class BaseUserDetailsService implements UserDetailsService {
private final PtyCstmrDomainService ptyCstmrDomainService;
@Override
public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
PtyCstmrBas cstmrInfoByUserId = ptyCstmrDomainService.getCstmrInfoByUserId(userId);
if(cstmrInfoByUserId == null){
throw new UsernameNotFoundException("사용자 정보가 없습니다.");
}
BaseUserDetails userDetails = BaseUserDetails.toUserDetails(cstmrInfoByUserId);
return userDetails;
}
}

75
common/security/src/main/java/kr/co/palnet/kac/config/security/util/JwtUtil.java

@ -0,0 +1,75 @@
package kr.co.palnet.kac.config.security.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import kr.co.palnet.kac.config.security.model.BaseUserDetails;
import kr.co.palnet.kac.util.KisaEncryptUtil;
import lombok.extern.slf4j.Slf4j;
import java.time.Instant;
@Slf4j
public class JwtUtil {
// TODO key는 properties에서 가져올수 있도록 처리
private static final Algorithm ALGORITHM = Algorithm.HMAC512("pal-networks");
// 1시간
// private static final long AUTH_TIME = 60 * 60;
private static final long AUTH_TIME = 10;
// 7일
private static final long REFRESH_TIME = 60 * 60 * 24 * 7;
public static String makeAuthToken(BaseUserDetails user) {
String encCstmrSno = KisaEncryptUtil.CbcEncrypt.encrypt(String.valueOf(user.getCstmrSno()));
// List<SimpleGrantedAuthority> authorities = user.getAuthorities();
// String authStr = String.join(",", authorities.stream().map(GrantedAuthority::getAuthority).map(str -> str.replaceFirst("ROLE_", "")).toArray(String[]::new));
String authStr = user.getCstmrDivCd();
return JWT.create()
.withSubject("AUTH")
.withAudience("kac")
.withIssuer("palnet")
.withIssuedAt(Instant.now())
.withExpiresAt(Instant.ofEpochMilli(Instant.now().plusSeconds(AUTH_TIME).toEpochMilli()))
.withClaim("userId", user.getUserId())
.withClaim("sno", encCstmrSno)
.withClaim("role", authStr)
.sign(ALGORITHM);
}
public static String makeRefreshToken(BaseUserDetails user) {
String encCstmrSno = KisaEncryptUtil.CbcEncrypt.encrypt(String.valueOf(user.getCstmrSno()));
// List<SimpleGrantedAuthority> authorities = user.getAuthorities();
// String authStr = String.join(",", authorities.stream().map(GrantedAuthority::getAuthority).map(str -> str.replaceFirst("ROLE_", "")).toArray(String[]::new));
String authStr = user.getCstmrDivCd();
return JWT.create()
.withSubject("REFRESH")
.withAudience("kac")
.withIssuer("palnet")
.withIssuedAt(Instant.now())
.withExpiresAt(Instant.ofEpochMilli(Instant.now().plusSeconds(REFRESH_TIME).toEpochMilli()))
.withClaim("userId", user.getUserId())
.withClaim("sno", encCstmrSno)
.withClaim("role", authStr)
.sign(ALGORITHM);
}
public static BaseUserDetails verify(String token, String type) {
DecodedJWT decodeJwt = JWT.require(ALGORITHM).build().verify(token);
String sub = decodeJwt.getSubject();
if (!type.equals(sub)) {
throw new JWTVerificationException("Token is not valid - sub(type)");
}
String decCstmrSno = KisaEncryptUtil.CbcEncrypt.decrypt(decodeJwt.getClaim("sno").asString());
String decRole = decodeJwt.getClaim("role").asString();
BaseUserDetails userDetails = BaseUserDetails.builder()
.userId(decodeJwt.getClaim("userId").asString())
.cstmrSno(Long.parseLong(decCstmrSno))
.cstmrDivCd(decRole)
.build();
return userDetails;
}
}

1
common/security/src/main/java/lombok.config

@ -0,0 +1 @@
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier

6
common/security/src/main/resources/messages/errors/auth_error.properties

@ -0,0 +1,6 @@
AT001=\uBE44\uBC00\uBC88\uD638\uB97C 10\uD68C \uC774\uC0C1 \uD2C0\uB838\uC2B5\uB2C8\uB2E4. \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758\uD558\uAE38 \uBC14\uB78D\uB2C8\uB2E4.
AT002=\uB85C\uADF8\uC778 \uC815\uBCF4\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
AT100=\uB85C\uADF8\uC778\uC774 \uD544\uC694\uD55C \uC11C\uBE44\uC2A4 \uC785\uB2C8\uB2E4.
AT101=\uD1A0\uD070 \uC815\uBCF4\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
AT102=\uD1A0\uD070\uC774 \uB9CC\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
AT103=\uAD8C\uD55C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.

6
common/security/src/main/resources/messages/errors/auth_error_en.properties

@ -0,0 +1,6 @@
AT001=Password incorrect more than 10 times, please contact your administrator.
AT002=The login information is not valid.
AT100=This service requires login.
AT101=Token information is incorrect.
AT102=Token has expired.
AT103=You do not have permission.

3
common/util/build.gradle

@ -1,6 +1,7 @@
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
// implementation "$boot:spring-boot-starter"
implementation "$boot:spring-boot-starter-json"
}

52
common/util/src/main/java/kr/co/palnet/kac/util/ObjectMapperUtils.java

@ -0,0 +1,52 @@
package kr.co.palnet.kac.util;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
/**
* packageName : com.sumair.common.core.utils
* fileName : ObjectMapperUtils
* author : dhji
* date : 2023-05-17(017)
* description :
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 2023-05-17(017) dhji 최초 생성
*/
public class ObjectMapperUtils {
public static ObjectMapper getObjectMapper() {
return getObjectMapperBuilder().build();
}
public static Jackson2ObjectMapperBuilder getObjectMapperBuilder() {
Jackson2ObjectMapperBuilder jacksonBuilder = new Jackson2ObjectMapperBuilder();
jacksonBuilder.serializationInclusion(JsonInclude.Include.NON_NULL);
jacksonBuilder.serializationInclusion(JsonInclude.Include.NON_EMPTY);
// jacksonBuilder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// jacksonBuilder.featuresToDisable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// jacksonBuilder.featuresToDisable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
// jacksonBuilder.featuresToDisable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
// jacksonBuilder.modulesToInstall(new JavaTimeModule());
// jacksonBuilder.timeZone(TimeZone.getTimeZone("UTC"));
// jacksonBuilder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");
// jacksonBuilder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
// jacksonBuilder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// jacksonBuilder.deserializers(new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
// jacksonBuilder.deserializers(new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
return jacksonBuilder;
}
}

1
data/com/build.gradle

@ -1,5 +1,4 @@
dependencies {
implementation "$boot:spring-boot-starter-data-jpa"

27
data/pty/build.gradle

@ -0,0 +1,27 @@
dependencies {
implementation "$boot:spring-boot-starter-data-jpa"
implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta"
annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"
testRuntimeOnly("com.h2database:h2")
}
def querydslDir = layout.buildDirectory.dir("generated/querydsl").get().asFile
sourceSets {
main.java.srcDir(querydslDir)
}
tasks.withType(JavaCompile) {
options.getGeneratedSourceOutputDirectory().set(file(querydslDir))
}
clean {
delete file(querydslDir)
}

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCrtfyhpBas.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCrtfyhpBas.java

5
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrBas.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrBas.java

@ -21,7 +21,7 @@ public class PtyCstmrBas {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "CSTMR_SNO")
private Integer cstmrSno;
private Long cstmrSno;
// 권한ID
@Column(name = "AUTH_ID")
@ -79,4 +79,7 @@ public class PtyCstmrBas {
@Column(name = "TRMNL_ID")
private String trmnlId;
@OneToOne(mappedBy = "ptyCstmrBas", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
private PtyCstmrDtl ptyCstmrDtl;
}

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrConectHist.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrConectHist.java

11
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrDtl.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrDtl.java

@ -1,9 +1,6 @@
package kr.co.palnet.kac.data.pty.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@ -23,7 +20,7 @@ public class PtyCstmrDtl {
// 고객일련번호
@Id
@Column(name = "CSTMR_SNO")
private int cstmrSno;
private Long cstmrSno;
// 아이핀DI
@Column(name = "IPIN_DI")
@ -85,5 +82,9 @@ public class PtyCstmrDtl {
@Column(name = "UPDATE_USER_ID")
private String updateUserId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CSTMR_SNO", insertable = false, updatable = false)
private PtyCstmrBas ptyCstmrBas;
}

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrGroup.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrGroup.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyGroupBas.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyGroupBas.java

1
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtySnsLoginRel.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtySnsLoginRel.java

@ -9,7 +9,6 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.Instant;

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsAgreeTxn.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsAgreeTxn.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsBas.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsBas.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsDtl.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsDtl.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCrtfyhpBasRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCrtfyhpBasRepository.java

11
data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrBasRepository.java

@ -0,0 +1,11 @@
package kr.co.palnet.kac.data.pty.repository;
import kr.co.palnet.kac.data.pty.model.PtyCstmrBas;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface PtyCstmrBasRepository extends JpaRepository<PtyCstmrBas, Integer> {
@Query("select b from PtyCstmrBas b inner join b.ptyCstmrDtl where b.userId = :userId")
PtyCstmrBas findByUserId(@Param("userId") String userId);
}

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrConectHistRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrConectHistRepository.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrDtlRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrDtlRepository.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrGroupRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrGroupRepository.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtySnsLoginRelRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtySnsLoginRelRepository.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsAgreeTxnRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsAgreeTxnRepository.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsBasRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsBasRepository.java

0
app/kac-app/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsDtlRepository.java → data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyTermsDtlRepository.java

19
data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyCstmrDomainService.java

@ -0,0 +1,19 @@
package kr.co.palnet.kac.data.pty.service;
import kr.co.palnet.kac.data.pty.model.PtyCstmrBas;
import kr.co.palnet.kac.data.pty.repository.PtyCstmrBasRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@RequiredArgsConstructor
@Service
public class PtyCstmrDomainService {
private final PtyCstmrBasRepository ptyCstmrBasRepository;
public PtyCstmrBas getCstmrInfoByUserId(String userId) {
return ptyCstmrBasRepository.findByUserId(userId);
}
}

6
data/user/build.gradle

@ -1,6 +0,0 @@
dependencies {
}

5
http-client/http-client.env.json

@ -0,0 +1,5 @@
{
"local": {
"host": "http://localhost:8080"
}
}

19
http-client/http/auth.http

@ -0,0 +1,19 @@
### 로그인
@userId = user
@password = 1234
POST {{host}}/v1/login
Authorization: Bearer {{authToken}} // 토큰이 있을 경우 필터에 걸리는지 확인하기 위한 조치
Content-Type: application/json
{
"userId": "{{userId}}",
"password": "{{password}}"
}
> {%
client.global.set("authToken", response.headers.valueOf("Auth-Token"));
%}

27
http-client/test.http → http-client/http/code.http

@ -1,17 +1,20 @@
### 전체 코드 조회 - 코드그룹-코드-언어
GET http://localhost:8080/v1/com/code/all
GET {{host}}/v1/com/code/all
?siteCd=KAC&langDivCd=ko_KR
Authorization: Bearer {{authToken}}
### 그룹 목록 조회 - 코드 그룹만
GET http://localhost:8080/v1/com/code/group
GET {{host}}/v1/com/code/group
Authorization: Bearer {{authToken}}
### 코드 목록 조회 - 코드 - 언어
GET http://localhost:8080/v1/com/code/code
GET {{host}}/v1/com/code/code
?groupCd=TEST1&langDivCd=ko_KR
### 코드 그룹 등록
POST http://localhost:8080/v1/com/code/group
POST {{host}}/v1/com/code/group
Content-Type: application/json
{
@ -22,7 +25,7 @@ Content-Type: application/json
}
### 코드 등록
POST http://localhost:8080/v1/com/code/code
POST {{host}}/v1/com/code/code
Content-Type: application/json
{
@ -35,7 +38,7 @@ Content-Type: application/json
}
### 언어 등록
POST http://localhost:8080/v1/com/code/lang
POST {{host}}/v1/com/code/lang
Content-Type: application/json
{
@ -47,7 +50,7 @@ Content-Type: application/json
}
### 코드 그룹 수정
PUT http://localhost:8080/v1/com/code/group
PUT {{host}}/v1/com/code/group
Content-Type: application/json
{
@ -58,7 +61,7 @@ Content-Type: application/json
}
### 코드 수정
PUT http://localhost:8080/v1/com/code/code
PUT {{host}}/v1/com/code/code
Content-Type: application/json
{
@ -71,7 +74,7 @@ Content-Type: application/json
}
### 언어 수정
PUT http://localhost:8080/v1/com/code/lang
PUT {{host}}/v1/com/code/lang
Content-Type: application/json
{
@ -84,14 +87,14 @@ Content-Type: application/json
### 코드 그룹 삭제
DELETE http://localhost:8080/v1/com/code/group
DELETE {{host}}/v1/com/code/group
?groupCd=NEW_GROUP001
### 코드 삭제
DELETE http://localhost:8080/v1/com/code/code
DELETE {{host}}/v1/com/code/code
?groupCd=NEW_GROUP001&cdId=NEW_CODE001
### 언어 삭제
DELETE http://localhost:8080/v1/com/code/lang
DELETE {{host}}/v1/com/code/lang
?groupCd=NEW_GROUP001&cdId=NEW_CODE001&langDivCd=ko_KR

2
web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeDTO.java

@ -44,7 +44,7 @@ public class CodeDTO {
// 수정일시
private LocalDateTime updateDt;
public static CodeDTO fromEntity(ComCdBas entity) {
public static CodeDTO toDTO(ComCdBas entity) {
return CodeDTO.builder()
.groupCd(entity.getGroupCd())
.cdId(entity.getCdId())

2
web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeGroupDTO.java

@ -38,7 +38,7 @@ public class CodeGroupDTO {
// 수정일시
private LocalDateTime updateDt;
public static CodeGroupDTO fromEntity(ComCdGroupBas entity){
public static CodeGroupDTO toDTO(ComCdGroupBas entity){
return CodeGroupDTO.builder()
.groupCd(entity.getGroupCd())
.siteCd(entity.getSiteCd())

2
web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeGroupRS.java

@ -21,7 +21,7 @@ public class CodeGroupRS {
private List<CodeRS> codeList = new ArrayList<>();
// ComCdGroupBas을 받아서 CodeGroupRS로 변환
public static CodeGroupRS fromEntity(ComCdGroupBas comCdGroupBas) {
public static CodeGroupRS toRS(ComCdGroupBas comCdGroupBas) {
return CodeGroupRS.builder()
.groupCd(comCdGroupBas.getGroupCd())
.siteCd(comCdGroupBas.getSiteCd())

2
web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeLangDTO.java

@ -41,7 +41,7 @@ public class CodeLangDTO {
// 수정일시
private LocalDateTime updateDt;
public static CodeLangDTO fromEntity(ComCdLangCtg entity) {
public static CodeLangDTO toDTO(ComCdLangCtg entity) {
return CodeLangDTO.builder()
.groupCd(entity.getGroupCd())
.cdId(entity.getCdId())

2
web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/model/CodeRS.java

@ -22,7 +22,7 @@ public class CodeRS {
private String addInfoValue;
private List<CodeRS> children = new ArrayList<>();
public static CodeRS fromEntity(ComCdBas comCdBas) {
public static CodeRS toRS(ComCdBas comCdBas) {
return CodeRS.builder()
.groupCd(comCdBas.getComCdGroupBas().getGroupCd())
.cdId(comCdBas.getCdId())

20
web/api-com/src/main/java/kr/co/palnet/kac/api/v1/com/code/service/ComCodeService.java

@ -24,13 +24,13 @@ public class ComCodeService {
List<ComCdGroupBas> comCdGroupBasList = comCodeDomainService.getComCdGroupBasList(rq.getSiteCd());
List<CodeGroupRS> codeGroupRSList = comCdGroupBasList.stream().map(group -> {
CodeGroupRS codeGroupRS = CodeGroupRS.fromEntity(group);
CodeGroupRS codeGroupRS = CodeGroupRS.toRS(group);
List<ComCdBas> comCdBasList = group.getComCdBasList();
if (comCdBasList != null && !comCdBasList.isEmpty()) {
// TODO 계층 구조 필요시 적용
List<CodeRS> codeRSList = comCdBasList.stream().map(code -> {
CodeRS codeRS = CodeRS.fromEntity(code);
CodeRS codeRS = CodeRS.toRS(code);
if (code.getComCdLangCtgList() != null && !code.getComCdLangCtgList().isEmpty()) {
code.getComCdLangCtgList().stream().filter(lang ->
lang.getLangDivCd().equals(rq.getLangDivCd())
@ -50,14 +50,14 @@ public class ComCodeService {
// 그룹 목록 조회 - 코드 그룹만
public List<CodeGroupRS> getAllGroupCode() {
List<ComCdGroupBas> comCdGroupBasList = comCodeDomainService.getComCdGroupBasList();
return comCdGroupBasList.stream().map(CodeGroupRS::fromEntity).toList();
return comCdGroupBasList.stream().map(CodeGroupRS::toRS).toList();
}
// 코드 목록 조회 - 코드 - 언어
public List<CodeRS> getAllCodeByGroup(SearchCodeRQ rq) {
List<ComCdBas> comCdBasList = comCodeDomainService.getComCdBasList(rq.getGroupCd());
return comCdBasList.stream().map(entity -> {
CodeRS codeRS = CodeRS.fromEntity(entity);
CodeRS codeRS = CodeRS.toRS(entity);
if (entity.getComCdLangCtgList() != null && !entity.getComCdLangCtgList().isEmpty()) {
entity.getComCdLangCtgList().stream().filter(lang ->
lang.getLangDivCd().equals(rq.getLangDivCd())
@ -71,21 +71,21 @@ public class ComCodeService {
public CodeGroupDTO createCodeGroup(FormCodeGroupRQ rq) {
ComCdGroupBas entity = rq.toEntity();
ComCdGroupBas comCdGroupBas = comCodeDomainService.createComCdGroupBas(entity);
return CodeGroupDTO.fromEntity(comCdGroupBas);
return CodeGroupDTO.toDTO(comCdGroupBas);
}
// 코드 등록
public CodeDTO createCode(FormCodeRQ rq) {
ComCdBas entity = rq.toEntity();
ComCdBas comCdBas = comCodeDomainService.createComCdBas(entity);
return CodeDTO.fromEntity(comCdBas);
return CodeDTO.toDTO(comCdBas);
}
// 언어 등록
public CodeLangDTO createCodeLang(FormCodeLangRQ rq) {
ComCdLangCtg entity = rq.toEntity();
ComCdLangCtg comCdLangCtg = comCodeDomainService.createComCdLangCtg(entity);
return CodeLangDTO.fromEntity(comCdLangCtg);
return CodeLangDTO.toDTO(comCdLangCtg);
}
@ -93,21 +93,21 @@ public class ComCodeService {
public CodeGroupDTO updateCodeGroup(FormCodeGroupRQ rq) {
ComCdGroupBas entity = rq.toEntity();
ComCdGroupBas comCdGroupBas = comCodeDomainService.updateComCdGroupBas(entity);
return CodeGroupDTO.fromEntity(comCdGroupBas);
return CodeGroupDTO.toDTO(comCdGroupBas);
}
// 코드 수정
public CodeDTO updateCode(FormCodeRQ rq) {
ComCdBas entity = rq.toEntity();
ComCdBas comCdBas = comCodeDomainService.updateComCdBas(entity);
return CodeDTO.fromEntity(comCdBas);
return CodeDTO.toDTO(comCdBas);
}
// 언어 수정
public CodeLangDTO updateCodeLang(FormCodeLangRQ rq) {
ComCdLangCtg entity = rq.toEntity();
ComCdLangCtg comCdLangCtg = comCodeDomainService.updateComCdLangCtg(entity);
return CodeLangDTO.fromEntity(comCdLangCtg);
return CodeLangDTO.toDTO(comCdLangCtg);
}
// 코드 그룹 삭제

Loading…
Cancel
Save