mirror of
http://git.mhez-qa.uplus.co.kr/hubez/hubez-admin.git
synced 2025-12-06 21:36:44 +09:00
어드민 vuejs 통합 빌드 환경 구성 / 유플러스 마스킹 유틸 구성
This commit is contained in:
@@ -1,15 +1,14 @@
|
||||
package kr.co.uplus.ez;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class Scheduler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Scheduler.class);
|
||||
|
||||
/**
|
||||
* 스케줄러 트리거는 해당영역에 선언 / 서비스영역은 별도
|
||||
*/
|
||||
|
||||
@@ -3,19 +3,18 @@ package kr.co.uplus.ez;
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.core.env.AbstractEnvironment;
|
||||
|
||||
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
|
||||
public class WebApplication extends SpringBootServletInitializer {
|
||||
import kr.co.uplus.ez.common.utils.USecuritySupUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WebApplication.class);
|
||||
@Slf4j
|
||||
@SpringBootApplication
|
||||
public class WebApplication extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
|
||||
@@ -32,6 +31,9 @@ public class WebApplication extends SpringBootServletInitializer {
|
||||
|
||||
@PostConstruct
|
||||
public void onStartup() {
|
||||
// 유플러스 마스킹 유틸 적용
|
||||
USecuritySupUtils.initMaskingRule();
|
||||
|
||||
Thread checkThread = new Thread(new CheckProcess());
|
||||
checkThread.setDaemon(true);
|
||||
checkThread.start();
|
||||
@@ -44,10 +46,13 @@ public class WebApplication extends SpringBootServletInitializer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 프로세스 hang 확인을 위한 1분마다 메모리 로깅 기능
|
||||
* 데몬 스레드 방식으로 스프링 관리 스레드 아님
|
||||
*/
|
||||
@Slf4j
|
||||
class CheckProcess implements Runnable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CheckProcess.class);
|
||||
|
||||
private static final String PROC_NAME = "mhez-admin";
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package kr.co.uplus.ez.common.jwt;
|
||||
|
||||
import static kr.co.uplus.ez.config.SecurityConfig.LOGIN_API_URL;
|
||||
import static kr.co.uplus.ez.config.SecurityConfig.PUBLIC_API_URL;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -22,34 +19,25 @@ import io.jsonwebtoken.impl.TextCodec;
|
||||
import kr.co.uplus.ez.common.data.Const;
|
||||
import kr.co.uplus.ez.common.utils.WebUtils;
|
||||
|
||||
public abstract class JwtAuthFilter extends OncePerRequestFilter {
|
||||
public abstract class JwtAuthFilter extends OncePerRequestFilter {
|
||||
|
||||
protected final JwtProperties jwtProps;
|
||||
|
||||
|
||||
public JwtAuthFilter(JwtProperties jwtProps) {
|
||||
this.jwtProps = jwtProps;
|
||||
}
|
||||
|
||||
public abstract String getToken(HttpServletRequest request);
|
||||
|
||||
public abstract void onValidateSuccess(HttpServletRequest request, HttpServletResponse response, Claims claims);
|
||||
public abstract void onValidateException(HttpServletRequest request, HttpServletResponse response, JwtException exception);
|
||||
|
||||
public abstract void onValidateException(HttpServletRequest request, HttpServletResponse response,
|
||||
JwtException exception);
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
throws ServletException, IOException {
|
||||
if (WebUtils.isResourceRequest(request) || WebUtils.isMatchedUriPattern(request, "/login",
|
||||
"/api/v1/bo/login/**",
|
||||
"/v2/api-docs",
|
||||
"/swagger-resources",
|
||||
"/swagger-resources/**",
|
||||
"/configuration/ui",
|
||||
"/configuration/security",
|
||||
"/swagger-ui.html",
|
||||
"/webjars/**",
|
||||
"/v3/api-docs/**",
|
||||
"/swagger-ui/**",
|
||||
"/")) {
|
||||
if (WebUtils.isResourceRequest(request) || WebUtils.isMatchedUriPattern(request, "/api/v1/bo/login/**")) {
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
@@ -57,7 +45,7 @@ public abstract class JwtAuthFilter extends OncePerRequestFilter {
|
||||
// 쿠키에서 토큰 추출 (client - server token)
|
||||
String token = getToken(request);
|
||||
|
||||
if(token == null) {
|
||||
if (token == null) {
|
||||
chain.doFilter(request, response); // go to the next filter in the filter chain
|
||||
return;
|
||||
}
|
||||
@@ -67,26 +55,24 @@ public abstract class JwtAuthFilter extends OncePerRequestFilter {
|
||||
|
||||
try {
|
||||
// 4. 토큰 검증
|
||||
claims = Jwts.parser()
|
||||
.setSigningKey(TextCodec.BASE64.decode(jwtProps.getKeyString()))
|
||||
.parseClaimsJws(token)
|
||||
claims = Jwts.parser().setSigningKey(TextCodec.BASE64.decode(jwtProps.getKeyString())).parseClaimsJws(token)
|
||||
.getBody();
|
||||
|
||||
String subject = claims.getSubject();
|
||||
if(subject != null) {
|
||||
String subject = claims.getSubject();
|
||||
if (subject != null) {
|
||||
onValidateSuccess(request, response, claims);
|
||||
|
||||
// 5. 스프링 용 UsernamePasswordAuthenticationToken 객체 생성
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String,Object> principalMap = (Map<String,Object>) claims.get("principal");
|
||||
Map<String, Object> principalMap = (Map<String, Object>) claims.get("principal");
|
||||
JwtUser user = JwtUser.createAuthUser(principalMap);
|
||||
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
|
||||
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, null,
|
||||
user.getAuthorities());
|
||||
|
||||
// 6. 사용자 인증 처리 (Now, user is authenticated)
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
}
|
||||
}
|
||||
catch(JwtException e) {
|
||||
} catch (JwtException e) {
|
||||
onValidateException(request, response, e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
251
src/main/java/kr/co/uplus/ez/common/utils/USecuritySupUtils.java
Normal file
251
src/main/java/kr/co/uplus/ez/common/utils/USecuritySupUtils.java
Normal file
@@ -0,0 +1,251 @@
|
||||
package kr.co.uplus.ez.common.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import lguplus.security.data.USecurityModule;
|
||||
import lguplus.security.json.simple.parser.ParseException;
|
||||
import lguplus.security.vulner.SetPolicyFile;
|
||||
|
||||
public class USecuritySupUtils {
|
||||
|
||||
private static final String RULE_NM = "UplusMR";
|
||||
private static final String RULE_FILE_NAME = "UplusMaskingRule";
|
||||
private static final String RULE_FILE_SUFFIX = "json";
|
||||
|
||||
/**
|
||||
* 마스킹룰 JSON 파일 위치를 재지정 하기 위한 기능
|
||||
* USecuritySupUtils.initMaskingRule()
|
||||
*/
|
||||
public static void initMaskingRule() {
|
||||
try {
|
||||
ClassPathResource resource = new ClassPathResource(RULE_FILE_NAME + "." + RULE_FILE_SUFFIX);
|
||||
InputStream inputStream = resource.getInputStream();
|
||||
File tmpFile = File.createTempFile(RULE_FILE_NAME, RULE_FILE_SUFFIX);
|
||||
FileUtils.copyInputStreamToFile(inputStream, tmpFile);
|
||||
SetPolicyFile.setRuleFile(RULE_NM, tmpFile.getPath());
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드정보
|
||||
*
|
||||
* 앞3자리, 뒤4자리 남긴 후 마스킹
|
||||
* 단, 7자리 이하는 앞 3자리 남기고 마스킹
|
||||
* 3자리 이하는 모두 마스킹
|
||||
* ex) 123*-****-****-1234
|
||||
* USecuritySupUtils.maskingCardnum("1234-1234-1234-1234")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingCardnum(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "cardnum", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 전화번호
|
||||
*
|
||||
* 국번 3자리 혹은 4자리 마스킹
|
||||
* 단, 8자리 이하는 뒤 4자리 남기고 마스킹
|
||||
* 4자리 이하는 모두 마스킹
|
||||
* ex) 02-****-1234 / 010-****-1234
|
||||
* USecuritySupUtils.maskingPhone("02-1234-1234")
|
||||
* USecuritySupUtils.maskingPhone("010-1234-1234")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingPhone(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "phone", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 시리얼번호
|
||||
*
|
||||
* 뒤 4자리 외 마스킹
|
||||
* 단, 4자리 이하는 모두 마스킹
|
||||
* ex) ***4567
|
||||
* USecuritySupUtils.maskingSerial("12345678")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingSerial(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "serial", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 계좌번호
|
||||
*
|
||||
* 앞 3자리, 뒤 4자리 남긴 후 마스킹
|
||||
* 단, 7자리 이하는 앞 3자리 남기고 마스킹
|
||||
* 3자리 이하는 모두 마스킹
|
||||
* ex) 123-***-**3456
|
||||
* USecuritySupUtils.maskingAccountnum("123-123-123456")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingAccountnum(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "accountnum", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP
|
||||
*
|
||||
* ipv4: Dot 기준으로 3번째 블록 마스킹
|
||||
* ex) 123.123.***.123
|
||||
* USecuritySupUtils.maskingIp("123.123.123.123")
|
||||
* ipv6: Colon 기준으로 마지막 블록 마스킹
|
||||
* ex) 2001:0DB8:0:0:0:0:1428:****
|
||||
* USecuritySupUtils.maskingIp("2001:0DB8:0:0:0:0:1428:1234")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingIp(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "ip", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 이름
|
||||
*
|
||||
* 성 뒤 이름의 첫자리 마스킹
|
||||
* ex) 홍*동, 허*설헌
|
||||
* USecuritySupUtils.maskingName("홍길동")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingName(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "name", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주민번호
|
||||
*
|
||||
* 뒤 6자리 마스킹
|
||||
* ex) 800101-1******
|
||||
* USecuritySupUtils.maskingJumin("800101-1234567")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingJumin(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "jumin", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 이메일주소
|
||||
*
|
||||
* 계정 앞 3자리 외 마스킹
|
||||
* 단, 3자리 이하는 계정 모두 마스킹
|
||||
* ex) abc*****@hanmail.net
|
||||
* USecuritySupUtils.maskingEmail("abcdefg@hanmail.net")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingEmail(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "email", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주소
|
||||
*
|
||||
* 도로명 뒤 마스킹(단 병기되는 동은 표시가능) 읍,면,동,리 이후 마스킹 또는 상세주소 제외
|
||||
* 단, 마스킹 대상이 없을 경우 (주소입력오류)
|
||||
* 1) 1차로 숫자만 마스킹
|
||||
* 2) 숫자도 없을 경우 뒤에서 3자리 마스킹
|
||||
* ex) 서울시 마포구 월드컵북로 ***
|
||||
* ex) 서울 영등포구 여의도동 **-*
|
||||
* USecuritySupUtils.maskingAddress("서울시 마포구 월드컵북로 200-1")
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String maskingAddress(String value) {
|
||||
String v = "";
|
||||
if (StringUtils.hasText(value)) {
|
||||
try {
|
||||
v = USecurityModule.maskingApply(RULE_NM, "address", value);
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import org.springframework.web.cors.CorsUtils;
|
||||
|
||||
import kr.co.uplus.ez.api.login.LoginFailureHandler;
|
||||
import kr.co.uplus.ez.api.login.LoginSuccessHandler;
|
||||
import kr.co.uplus.ez.common.data.ConfigProps;
|
||||
import kr.co.uplus.ez.common.jwt.JwtAuthCookieFilter;
|
||||
import kr.co.uplus.ez.common.jwt.JwtAuthHeaderFilter;
|
||||
import kr.co.uplus.ez.common.jwt.JwtExceptionFilter;
|
||||
@@ -31,7 +30,7 @@ import kr.co.uplus.ez.config.filter.VueStaticFilter;
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private static final String LOGIN_FORM_URL = "/login/**";
|
||||
private static final String LOGIN_FORM_URL = "/login";
|
||||
public static final String LOGIN_API_URL = "/api/v1/bo/login";
|
||||
public static final String LOGIN_FAIL_URL = "/login?error=true";
|
||||
public static final String LOGIN_SUCC_URL = "/";
|
||||
@@ -43,19 +42,13 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
private static final String[] PERMIT_URL_ARRAY = {
|
||||
"/login",
|
||||
"/api/v1/bo/login/**",
|
||||
"/v2/api-docs",
|
||||
"/swagger-resources",
|
||||
"/swagger-resources/**",
|
||||
"/configuration/ui",
|
||||
"/configuration/security",
|
||||
"/swagger-ui.html",
|
||||
"/webjars/**",
|
||||
"/v3/api-docs/**",
|
||||
"/swagger-ui/**",
|
||||
"/swagger-ui/**",
|
||||
"/swagger-resources/**",
|
||||
"/v3/api-docs",
|
||||
"/v3/api-docs/**",
|
||||
"/"
|
||||
};
|
||||
|
||||
|
||||
private static final String[] AUTH_URL_ARRAY = {
|
||||
"/api/v1/bo/login/*",
|
||||
"/api/v1/bo/comm/**",
|
||||
@@ -75,16 +68,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
@Autowired
|
||||
private ConfigProps cprops;
|
||||
@Autowired
|
||||
private JwtProperties jwtProps;
|
||||
|
||||
// @Autowired
|
||||
// private AuthService authService;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void configure(WebSecurity web) throws Exception {
|
||||
web.ignoring()
|
||||
@@ -100,7 +86,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
public void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.addFilterBefore(new VueStaticFilter(), UsernamePasswordAuthenticationFilter.class) // Vue에서 호출시 화면관련 URL은 / forward
|
||||
// .addFilterBefore(new XssFilter(cprops), UsernamePasswordAuthenticationFilter.class)
|
||||
.addFilterBefore(new JwtExceptionFilter(), UsernamePasswordAuthenticationFilter.class)
|
||||
.addFilterBefore(jwtAuthFilter(), UsernamePasswordAuthenticationFilter.class)
|
||||
.addFilterBefore(new JwtAuthHeaderFilter(jwtProps), UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
@@ -2,8 +2,6 @@ package kr.co.uplus.ez.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
@@ -15,20 +13,12 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
public class SwaggerConfig extends WebMvcConfigurationSupport {
|
||||
public class SwaggerConfig {
|
||||
|
||||
private static final String API_TITLE = "HubEasy Admin";
|
||||
private static final String API_DESC = "허브이지 어드민에서 사용되는 API 문서입니다.";
|
||||
private static final String API_TITLE = "mhez-admin";
|
||||
private static final String API_DESC = "U+메시지허브이지 어드민에서 사용되는 API 문서입니다.";
|
||||
private static final String API_VER = "1.0";
|
||||
|
||||
@Override
|
||||
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/swagger-ui/**")
|
||||
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
|
||||
registry.addResourceHandler("/webjars/**")
|
||||
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket api() {
|
||||
return new Docket(DocumentationType.OAS_30).useDefaultResponseMessages(false).select()
|
||||
|
||||
22
src/main/java/kr/co/uplus/ez/config/WebMvcConfig.java
Normal file
22
src/main/java/kr/co/uplus/ez/config/WebMvcConfig.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package kr.co.uplus.ez.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
|
||||
@Configuration
|
||||
public class WebMvcConfig extends WebMvcConfigurationSupport {
|
||||
|
||||
/**
|
||||
* swagger 및 정적파일 경로 지정
|
||||
*/
|
||||
@Override
|
||||
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/swagger-ui/**")
|
||||
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
|
||||
registry.addResourceHandler("/webjars/**")
|
||||
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
|
||||
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package kr.co.uplus.ez.config.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
@@ -10,33 +11,32 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.filter.GenericFilterBean;
|
||||
|
||||
// http://www.servletsuite.com/servlets/xssflt.htm
|
||||
public class VueStaticFilter extends GenericFilterBean {
|
||||
|
||||
// Vuejs router url prefix 선언
|
||||
private static final String[] FRONTEND_URLS = { "/view", "/custMgt", "/sysMgt", "/attractMgt", "/servMgt",
|
||||
"/calculate", "/channelMgt", "/sendNumMgt", "/mntrng", "/riskMgt", "/stats" };
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
if (shouldExclude(request)) {
|
||||
chain.doFilter(request, response);
|
||||
// some logic so the request doesnt go to the servlet
|
||||
|
||||
// maybe you could just forward
|
||||
// the request directly to the file getting accessed. not sure if that would
|
||||
// work
|
||||
} else {
|
||||
// vuejs에 해당하는 페이지는 index를 바라보도록 전달
|
||||
((HttpServletRequest) request).getRequestDispatcher("/").forward(request, response);
|
||||
}
|
||||
|
||||
// file should be passed to the servlet; you can do some logic here
|
||||
// if you want
|
||||
}
|
||||
|
||||
private boolean shouldExclude(ServletRequest req) {
|
||||
boolean isEx = true;
|
||||
if (req instanceof HttpServletRequest) {
|
||||
HttpServletRequest hreq = (HttpServletRequest) req;
|
||||
return !(hreq.getRequestURI().startsWith("/view"));
|
||||
if (Arrays.stream(FRONTEND_URLS).anyMatch(s -> hreq.getRequestURI().startsWith(s))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return isEx;
|
||||
}
|
||||
|
||||
}
|
||||
150
src/main/java/kr/co/uplus/ez/view/main/MainViewController.java
Normal file
150
src/main/java/kr/co/uplus/ez/view/main/MainViewController.java
Normal file
@@ -0,0 +1,150 @@
|
||||
package kr.co.uplus.ez.view.main;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import kr.co.uplus.ez.common.data.ApiResponseCode;
|
||||
import kr.co.uplus.ez.common.data.ApiResponseMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Controller
|
||||
public class MainViewController {
|
||||
|
||||
// Vue일 경우 index로 전달
|
||||
@GetMapping("/")
|
||||
public String home() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
/*
|
||||
* 엑셀 업로드 poi 4.1 사용 테스트 x
|
||||
*/
|
||||
@PostMapping("/insertFileXcel")
|
||||
@ResponseBody
|
||||
public ApiResponseMessage<?> insertFileXcel(MultipartHttpServletRequest multipartRequest) {
|
||||
|
||||
MultipartFile file = multipartRequest.getFile("file");
|
||||
String colName = multipartRequest.getParameter("colName");
|
||||
ApiResponseMessage result = new ApiResponseMessage(ApiResponseCode.SUCCESS);
|
||||
|
||||
try {
|
||||
int rowindex = 0;
|
||||
int columnindex = 0;
|
||||
|
||||
InputStream in = file.getInputStream();
|
||||
@SuppressWarnings("resource")
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(in);
|
||||
XSSFSheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
int rows = sheet.getPhysicalNumberOfRows();
|
||||
|
||||
if (rows > 10000 || rows < 1) {
|
||||
// 엑셀 로우 건수가 10000건이 넘으면 false 반환
|
||||
result.setData(false);
|
||||
} else {
|
||||
HashMap<String, String> xcelData = new HashMap<String, String>();
|
||||
for (rowindex = 0; rowindex < rows; rowindex++) {
|
||||
XSSFRow row = sheet.getRow(rowindex);
|
||||
if (row != null) {
|
||||
int cells = row.getPhysicalNumberOfCells();
|
||||
for (columnindex = 0; columnindex <= cells - 1; columnindex++) {
|
||||
// 셀값을 읽는다
|
||||
XSSFCell cell = row.getCell(columnindex);
|
||||
String value = "";
|
||||
|
||||
if (cell == null) {
|
||||
continue;
|
||||
} else {
|
||||
// 타입별로 내용 읽기
|
||||
switch (cell.getCellType()) {
|
||||
case FORMULA:
|
||||
value = cell.getCellFormula();
|
||||
break;
|
||||
case NUMERIC:
|
||||
value = cell.getNumericCellValue() + "";
|
||||
break;
|
||||
case STRING:
|
||||
value = cell.getStringCellValue() + "";
|
||||
break;
|
||||
case BLANK:
|
||||
value = cell.getBooleanCellValue() + "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ("false".equals(value)) {
|
||||
// logger.info(rowindex+"번 행 Error :" +value);
|
||||
|
||||
break;
|
||||
} else {
|
||||
// logger.info(rowindex+"번 행 : "+columnindex+"번 열 값은: "+value);
|
||||
// xcelData.put(value, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
XSSFCell cell = row.getCell(columnindex);
|
||||
}
|
||||
result.setData(true);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
log.info("data : {}", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* 엑셀 업로드 poi 3.13 사용 rcs에서 테스트 완료
|
||||
*/
|
||||
|
||||
/*
|
||||
* @PostMapping("/insertFileXcel")
|
||||
*
|
||||
* @ResponseBody public Result<?> insertFileXcel(MultipartHttpServletRequest
|
||||
* multipartRequest){
|
||||
*
|
||||
* MultipartFile file = multipartRequest.getFile("file"); String colName =
|
||||
* multipartRequest.getParameter("colName"); Result<Map<String,Object>> result =
|
||||
* new Result<>();
|
||||
*
|
||||
* try { int rowindex=0; int columnindex=0;
|
||||
*
|
||||
* InputStream in = file.getInputStream();
|
||||
*
|
||||
* @SuppressWarnings("resource") XSSFWorkbook workbook = new XSSFWorkbook(in);
|
||||
* XSSFSheet sheet=workbook.getSheetAt(0);
|
||||
*
|
||||
* int rows=sheet.getPhysicalNumberOfRows(); // 엑셀 갯수 if(rows > 100 || rows < 1)
|
||||
* { result.setSuccess(false); }else { HashMap<String, String> xcelData = new
|
||||
* HashMap<String, String>(); for(rowindex=0;rowindex<rows;rowindex++){ XSSFRow
|
||||
* row=sheet.getRow(rowindex); if(row !=null) { int
|
||||
* cells=row.getPhysicalNumberOfCells(); for(columnindex=0;
|
||||
* columnindex<=cells-1; columnindex++){ //셀값을 읽는다 XSSFCell
|
||||
* cell=row.getCell(columnindex); String value="";
|
||||
*
|
||||
* if(cell==null){ continue; }else{ //타입별로 내용 읽기 switch (cell.getCellType()){
|
||||
* case XSSFCell.CELL_TYPE_FORMULA: value=cell.getCellFormula(); break; case
|
||||
* XSSFCell.CELL_TYPE_NUMERIC: value=cell.getNumericCellValue()+""; break; case
|
||||
* XSSFCell.CELL_TYPE_STRING: value=cell.getStringCellValue()+""; break; case
|
||||
* XSSFCell.CELL_TYPE_BLANK: value=cell.getBooleanCellValue()+""; 7 break; } }
|
||||
* if("false".equals(value)) { logger.info(rowindex+"번 행 Error :" +value);
|
||||
*
|
||||
* break; }else { logger.info(rowindex+"번 행 : "+columnindex+"번 열 값은: "+value);
|
||||
* // xcelData.put(value, value) } } } XSSFCell cell=row.getCell(columnindex); }
|
||||
* result.setSuccess(true); } } catch (IOException e) { // TODO Auto-generated
|
||||
* catch block e.printStackTrace(); } return result; }
|
||||
*/
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
package kr.co.uplus.ez.view.sample;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||
|
||||
import kr.co.uplus.ez.common.data.ApiResponseCode;
|
||||
import kr.co.uplus.ez.common.data.ApiResponseMessage;
|
||||
|
||||
@Controller
|
||||
public class MainViewController {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
// WEB 없이 구성될 경우 필요
|
||||
// Vue일 경우 index로 전달
|
||||
@GetMapping("/")
|
||||
public String home() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
// Vue일 경우 index로 전달
|
||||
@RequestMapping(value = "/{path:[^\\.]*}")
|
||||
public String redirect() {
|
||||
return "forward:/";
|
||||
}
|
||||
|
||||
/*
|
||||
* 엑셀 업로드
|
||||
* poi 4.1 사용 테스트 x
|
||||
* */
|
||||
@PostMapping("/insertFileXcel")
|
||||
@ResponseBody
|
||||
public ApiResponseMessage<?> insertFileXcel(MultipartHttpServletRequest multipartRequest){
|
||||
|
||||
MultipartFile file = multipartRequest.getFile("file");
|
||||
String colName = multipartRequest.getParameter("colName");
|
||||
ApiResponseMessage result = new ApiResponseMessage(ApiResponseCode.SUCCESS);
|
||||
|
||||
try {
|
||||
int rowindex=0;
|
||||
int columnindex=0;
|
||||
|
||||
InputStream in = file.getInputStream();
|
||||
@SuppressWarnings("resource")
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(in);
|
||||
XSSFSheet sheet=workbook.getSheetAt(0);
|
||||
|
||||
int rows=sheet.getPhysicalNumberOfRows();
|
||||
|
||||
if(rows > 10000 || rows < 1) {
|
||||
// 엑셀 로우 건수가 10000건이 넘으면 false 반환
|
||||
result.setData(false);
|
||||
}else {
|
||||
HashMap<String, String> xcelData = new HashMap<String, String>();
|
||||
for(rowindex=0;rowindex<rows;rowindex++){
|
||||
XSSFRow row=sheet.getRow(rowindex);
|
||||
if(row !=null) {
|
||||
int cells=row.getPhysicalNumberOfCells();
|
||||
for(columnindex=0; columnindex<=cells-1; columnindex++){
|
||||
//셀값을 읽는다
|
||||
XSSFCell cell = row.getCell(columnindex);
|
||||
String value="";
|
||||
|
||||
if(cell==null){
|
||||
continue;
|
||||
}else{
|
||||
//타입별로 내용 읽기
|
||||
switch (cell.getCellType()){
|
||||
case FORMULA:
|
||||
value=cell.getCellFormula();
|
||||
break;
|
||||
case NUMERIC:
|
||||
value=cell.getNumericCellValue()+"";
|
||||
break;
|
||||
case STRING:
|
||||
value=cell.getStringCellValue()+"";
|
||||
break;
|
||||
case BLANK:
|
||||
value=cell.getBooleanCellValue()+"";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if("false".equals(value)) {
|
||||
// logger.info(rowindex+"번 행 Error :" +value);
|
||||
|
||||
break;
|
||||
}else {
|
||||
// logger.info(rowindex+"번 행 : "+columnindex+"번 열 값은: "+value);
|
||||
// xcelData.put(value, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
XSSFCell cell=row.getCell(columnindex);
|
||||
}
|
||||
result.setData(true);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
logger.info("data : {}", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 엑셀 업로드
|
||||
* poi 3.13 사용 rcs에서 테스트 완료
|
||||
* */
|
||||
|
||||
/*
|
||||
@PostMapping("/insertFileXcel")
|
||||
@ResponseBody
|
||||
public Result<?> insertFileXcel(MultipartHttpServletRequest multipartRequest){
|
||||
|
||||
MultipartFile file = multipartRequest.getFile("file");
|
||||
String colName = multipartRequest.getParameter("colName");
|
||||
Result<Map<String,Object>> result = new Result<>();
|
||||
|
||||
try {
|
||||
int rowindex=0;
|
||||
int columnindex=0;
|
||||
|
||||
InputStream in = file.getInputStream();
|
||||
@SuppressWarnings("resource")
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(in);
|
||||
XSSFSheet sheet=workbook.getSheetAt(0);
|
||||
|
||||
int rows=sheet.getPhysicalNumberOfRows();
|
||||
// 엑셀 갯수
|
||||
if(rows > 100 || rows < 1) {
|
||||
result.setSuccess(false);
|
||||
}else {
|
||||
HashMap<String, String> xcelData = new HashMap<String, String>();
|
||||
for(rowindex=0;rowindex<rows;rowindex++){
|
||||
XSSFRow row=sheet.getRow(rowindex);
|
||||
if(row !=null) {
|
||||
int cells=row.getPhysicalNumberOfCells();
|
||||
for(columnindex=0; columnindex<=cells-1; columnindex++){
|
||||
//셀값을 읽는다
|
||||
XSSFCell cell=row.getCell(columnindex);
|
||||
String value="";
|
||||
|
||||
if(cell==null){
|
||||
continue;
|
||||
}else{
|
||||
//타입별로 내용 읽기
|
||||
switch (cell.getCellType()){
|
||||
case XSSFCell.CELL_TYPE_FORMULA:
|
||||
value=cell.getCellFormula();
|
||||
break;
|
||||
case XSSFCell.CELL_TYPE_NUMERIC:
|
||||
value=cell.getNumericCellValue()+"";
|
||||
break;
|
||||
case XSSFCell.CELL_TYPE_STRING:
|
||||
value=cell.getStringCellValue()+"";
|
||||
break;
|
||||
case XSSFCell.CELL_TYPE_BLANK:
|
||||
value=cell.getBooleanCellValue()+"";
|
||||
7 break;
|
||||
}
|
||||
}
|
||||
if("false".equals(value)) {
|
||||
logger.info(rowindex+"번 행 Error :" +value);
|
||||
|
||||
break;
|
||||
}else {
|
||||
logger.info(rowindex+"번 행 : "+columnindex+"번 열 값은: "+value);
|
||||
// xcelData.put(value, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
XSSFCell cell=row.getCell(columnindex);
|
||||
}
|
||||
result.setSuccess(true);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
}
|
||||
11
src/main/resources/UplusMaskingRule.json
Normal file
11
src/main/resources/UplusMaskingRule.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"jumin":"8,13",
|
||||
"name":"2,2",
|
||||
"cardnum":"reserved",
|
||||
"accountnum":"reserved",
|
||||
"phone":"reserved",
|
||||
"address":"reserved",
|
||||
"email":"reserved",
|
||||
"serial":"reserved",
|
||||
"ip":"reserved"
|
||||
}
|
||||
@@ -12,12 +12,6 @@ spring:
|
||||
max-request-size: 15MB
|
||||
main:
|
||||
banner-mode: log
|
||||
mvc:
|
||||
# pathmatch:
|
||||
# matching-strategy: ant_path_matcher
|
||||
static-path-pattern: /static/**
|
||||
view:
|
||||
prefix: /templates/
|
||||
|
||||
app.props:
|
||||
encKey: RW5jS2V5Rm9yVXBsdXM=
|
||||
|
||||
Reference in New Issue
Block a user