parent
f80c336e12
commit
149a206533
@ -1,38 +0,0 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
@ -1,174 +0,0 @@
|
||||
|
||||
### API 가이드
|
||||
[카카오페이 문서발송 단건](./document/카카오페이내문서함_1.문서발송(단건).pdf)
|
||||
[카카오페이 문서발송 대량](./document/카카오페이내문서함_1.문서발송(대량).pdf)
|
||||
[카카오페이 문서발송 네트워크가이드](./document/카카오페이내문서함_1.네트워크가이드.pdf)
|
||||
|
||||
### swagger
|
||||
[API URL](http://localhost:8081/swagger-ui.html)
|
||||
[Front URL](http://localhost:8080/swagger-ui.html)
|
||||
[Front test page](http://localhost:8080/api/kakaopay/test)
|
||||
|
||||
### API 결과 수신
|
||||
* 정상 수신
|
||||
```java
|
||||
public class ApiResponseDTO<T> implements Serializable {
|
||||
private static final String FAIL_STATUS = "fail";
|
||||
private static final String ERROR_STATUS = "error";
|
||||
|
||||
@Schema(example = "true", description = "에러인 경우 false", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private boolean success;
|
||||
|
||||
@Schema(example = " ", description = "HttpStatus.OK", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String code;
|
||||
|
||||
@Schema(description = "결과 데이타, 오류시 null", example = " ")
|
||||
private T data;
|
||||
|
||||
@Schema(description = "오류 발생시 오류 메세지", example = " ", requiredMode = Schema.RequiredMode.AUTO)
|
||||
@Setter
|
||||
private String message;
|
||||
|
||||
@Schema(example = " ", description = "HttpStatus.OK", requiredMode = Schema.RequiredMode.AUTO)
|
||||
private HttpStatus httpStatus;
|
||||
|
||||
@Schema(description = "API 실행 결과 데이타 수")
|
||||
private int count;
|
||||
}
|
||||
```
|
||||
* 정상 수신
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"code": "200",
|
||||
"httpStatus": "OK",
|
||||
"message": "성공했습니다.",
|
||||
"data": {
|
||||
"token_status": "USED",
|
||||
"token_expires_at": 1624344762,
|
||||
"token_used_at": 0,
|
||||
"doc_box_sent_at": 0,
|
||||
"doc_box_received_at": 0,
|
||||
"authenticated_at": 0,
|
||||
"user_notified_at": 0,
|
||||
"payload": "payload 파라미터 입니다.",
|
||||
"signed_at": 0
|
||||
},
|
||||
"count": 1,
|
||||
"paginationInfo": null
|
||||
}
|
||||
```
|
||||
* 에러 수신
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"code": "error",
|
||||
"data": null,
|
||||
"message": "로그인 정보가 올바르지 않습니다.",
|
||||
"httpStatus": "BAD_REQUEST",
|
||||
"count": 0,
|
||||
"paginationInfo": null
|
||||
}
|
||||
```
|
||||
* API 호출 결과가 서버등(네트웍장애)의 장애인 경우를 제외 하고
|
||||
예외로 return 되는 경우는 없다(발생시 공통팀에 반드시 알려 줄 것)
|
||||
```js
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: method,
|
||||
contentType: "application/json; charset=utf-8",
|
||||
dataType: "json",
|
||||
data: JSON.stringify(data),
|
||||
beforeSend: (xhr) => {
|
||||
//xhr.setRequestHeader(header, token);
|
||||
$("#loading").show();
|
||||
|
||||
},
|
||||
success: function (res, textStatus) {
|
||||
console.log( JSON.stringify(res));
|
||||
if(res.success){
|
||||
//정상 응답
|
||||
$("#resData").text(res.data)
|
||||
}else{
|
||||
//에러 응답
|
||||
$("#errData").text(JSON.stringify(res));
|
||||
}
|
||||
},
|
||||
error : function(data) {
|
||||
// 여기로 오는 경우 공통팀에 알려 주세요
|
||||
alert("점검필요-error로 return", data.responseText);
|
||||
},
|
||||
complete: () => {
|
||||
$("#loading").hide();
|
||||
}
|
||||
});
|
||||
```
|
||||
### API(Restful call) validation
|
||||
* Controller 단에서 @Validated 사용으로 처리 가능
|
||||
* But, 이경우 API 로그를 남기기 위해 Service 단에서 체크 하도록 컨트롤러 단에서는 유효성 체크 skip
|
||||
|
||||
### spring validation
|
||||
```text
|
||||
@Valid는 Java, @Validated는 Spring에서 지원하는 어노테이션
|
||||
@Validated는 @Valid의 기능을 포함하고, 유효성을 검토할 그룹을 지정할 수 있는 기능이 추가됨
|
||||
```
|
||||
|
||||
```java
|
||||
@Null // null만 혀용
|
||||
@NotNull // null을 허용하지 않습니다. "", " "는 허용
|
||||
@NotEmpty // null, ""을 허용하지 않습니다. " "는 허용
|
||||
@NotBlank // null, "", " " 모두 허용하지 않습니다.
|
||||
|
||||
@Email // 이메일 형식을 검사합니다. 다만 ""의 경우를 통과 시킵니다
|
||||
@Pattern(regexp = ) // 정규식을 검사할 때 사용됩니다.
|
||||
@Size(min=, max=) // 길이를 제한할 때 사용됩니다.
|
||||
|
||||
@Max(value = ) // value 이하의 값을 받을 때 사용됩니다.
|
||||
@Min(value = ) // value 이상의 값을 받을 때 사용됩니다.
|
||||
|
||||
@Positive // 값을 양수로 제한합니다.
|
||||
@PositiveOrZero // 값을 양수와 0만 가능하도록 제한합니다.
|
||||
|
||||
@Negative // 값을 음수로 제한합니다.
|
||||
@NegativeOrZero // 값을 음수와 0만 가능하도록 제한합니다.
|
||||
|
||||
@Future // 현재보다 미래
|
||||
@Past // 현재보다 과거
|
||||
|
||||
@AssertFalse // false 여부, null은 체크하지 않습니다.
|
||||
@AssertTrue // true 여부, null은 체크하지 않습니다.
|
||||
```
|
||||
### intellij devtools 활성
|
||||
```text
|
||||
1. IntelliJ - Preferencs…
|
||||
2. 컴파일러 - build project automatically(프로젝트 자동 빌드) 체크
|
||||
3. Advanced Settings > Compiler
|
||||
Allow auto-make to start even if developed application is current running
|
||||
(개발된 애플리케이션이 현재 실행 중인 경우에도 auto-make가 시작되도록 허용) 체크
|
||||
# 1 ~ 3항 까지 설정후 에도 안되는 경우만 4번 설정
|
||||
4. 서버설정 : Edit Configurations...
|
||||
Modfy Options > On Update Action > Update Resources
|
||||
|
||||
```
|
||||
### ens-api 배포 및 run : profile에 따라 local|dev|prod
|
||||
```shell
|
||||
# jdk : azul-17.0.1
|
||||
# 프로젝트 root 폴더로 이동 : ens-parent
|
||||
# 패키지 생성 : local|dev|prod
|
||||
$ mvnw clean package -P local
|
||||
|
||||
# 실행 : 프로젝트폴더/ens-parent/ens-api/target에 생성된 jar파일 실행
|
||||
$ c:\tools\java\azul-17.0.1\java -jar -Dspring.profiles.active=local .\mens-api.jar
|
||||
|
||||
# mvn 명령어 설명
|
||||
# -pl [모듈명] : 모듈명의 프로젝트만 빌드
|
||||
# -am : 의존성 있는 프로젝트 함께 빌드 - C가 A를 디펜던시로 가지고 있으며 C를 빌드하면 A -> C 순으로 빌드
|
||||
$ mvnw clean package -pl mens-api -am -P local
|
||||
# -amd : 의존성 있는 타 프로젝트 빌드 - C가 A를 디펜던시로 가지고 있는 경우 A를 빌드 하면 A -> C 순으로 빌드
|
||||
$ mvnw clean package -pl mens-core -amd -P local
|
||||
|
||||
mvn clean package -pl mens-batch -am -P prod
|
||||
|
||||
```
|
||||
### 스프링 배치 DB schema
|
||||
[mysql DDL 스크립트](./document/batch-schema-mysql.sql)
|
Binary file not shown.
@ -1,137 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>kr.xit</groupId>
|
||||
<artifactId>mens-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>mens-admin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>war</packaging>
|
||||
<name>mens-admin</name>
|
||||
<description>Mobile Electronic Administrator Web</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>kr.xit</groupId>
|
||||
<artifactId>mens-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
<version>11.2.0.3</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/ojdbc6.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<defaultGoal>install</defaultGoal>
|
||||
<directory>${basedir}/target</directory>
|
||||
<finalName>${project.name}</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
<include>static/**/*</include>
|
||||
<include>egovframework/**/*</include>
|
||||
<include>config/application.yml</include>
|
||||
<include>config/application-app.yml</include>
|
||||
<include>config/application-ens*</include>
|
||||
<include>config/application-jpa.yml</include>
|
||||
<include>config/application-${env}.yml</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<!-- dependency 추가 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<!-- dependency jar 파일명 -->
|
||||
<!--finalName>${project.name}-${project.version}</finalName-->
|
||||
<!-- 기본생성 jar와 dependency jar 가 포함된 각각 파일 생성-->
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- spring-boot-maven-plugin : multi 프로젝트 이므로 mainClass 지정 필요 -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<executable>true</executable>
|
||||
<mainClass>kr.xit.EnsAdminApplication</mainClass>
|
||||
<!-- 외부jar import -->
|
||||
<includeSystemScope>true</includeSystemScope>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -1,89 +0,0 @@
|
||||
package kr.xit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.springframework.boot.Banner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.context.ApplicationPidFileWriter;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
|
||||
import org.springframework.boot.web.servlet.ServletComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import kr.xit.core.spring.config.support.CustomBeanNameGenerator;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : ens API application main
|
||||
* ServletComponentScan
|
||||
* - 서블릿컴포넌트(필터, 서블릿, 리스너)를 스캔해서 빈으로 등록
|
||||
* - WebFilter, WebServlet, WebListener annotaion sacan
|
||||
* - SpringBoot의 내장톰캣을 사용하는 경우에만 동작
|
||||
* ConfigurationPropertiesScan
|
||||
* - ConfigurationProperties annotaion class scan 등록
|
||||
* - EnableConfigurationProperties 대체
|
||||
* packageName : kr.xit
|
||||
* fileName : EnsAdminApplication
|
||||
* author : julim
|
||||
* date : 2023-04-28
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-04-28 julim 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@SpringBootApplication
|
||||
@ConfigurationPropertiesScan(basePackages = {"egovframework", "kr.xit"})
|
||||
@ServletComponentScan
|
||||
@ComponentScan(
|
||||
nameGenerator = CustomBeanNameGenerator.class,
|
||||
basePackages = {"egovframework", "kr.xit"}
|
||||
)
|
||||
public class EnsAdminApplication {
|
||||
static final List<String> basePackages = new ArrayList<>(
|
||||
Arrays.asList("egovframework", "kr.xit")
|
||||
);
|
||||
|
||||
public static void main(String[] args) {
|
||||
final String line = "====================================================================";
|
||||
log.info(line);
|
||||
log.info("==== EnsAdminApplication start :: active profiles - {} ====", System.getProperty("spring.profiles.active"));
|
||||
if(Objects.isNull(System.getProperty("spring.profiles.active"))) {
|
||||
|
||||
log.error(">>>>>>>>>>>>>> Undefined start VM option <<<<<<<<<<<<<<");
|
||||
log.error(">>>>>>>>>>>>>> -Dspring.profiles.active=local|dev|prd <<<<<<<<<<<<<<");
|
||||
log.error("============== EnsAdminApplication start fail ===============");
|
||||
log.error(line);
|
||||
System.exit(-1);
|
||||
}
|
||||
log.info(line);
|
||||
|
||||
// beanName Generator 등록 : API v1, v2 등으로 분류하는 경우
|
||||
// Bean 이름 식별시 풀패키지 명으로 식별 하도록 함
|
||||
final CustomBeanNameGenerator beanNameGenerator = new CustomBeanNameGenerator();
|
||||
beanNameGenerator.addBasePackages(basePackages);
|
||||
|
||||
final SpringApplicationBuilder applicationBuilder = new SpringApplicationBuilder(EnsAdminApplication.class);
|
||||
applicationBuilder.beanNameGenerator(beanNameGenerator);
|
||||
|
||||
final SpringApplication application = applicationBuilder.build();
|
||||
application.setBannerMode(Banner.Mode.OFF);
|
||||
application.setLogStartupInfo(false);
|
||||
|
||||
//TODO : 이벤트 실행 시점이 Application context 실행 이전인 경우 리스너 추가
|
||||
//PID(Process ID 작성)
|
||||
application.addListeners(new ApplicationPidFileWriter()) ;
|
||||
application.run(args);
|
||||
|
||||
log.info("=========================================================================================");
|
||||
log.info("========== EnsAdminApplication load Complete :: active profiles - {} ==========", System.getProperty("spring.profiles.active"));
|
||||
log.info("=========================================================================================");
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package kr.xit.biz.auth.service;
|
||||
|
||||
import egovframework.com.cmm.model.LoginVO;
|
||||
import egovframework.com.cmm.util.EgovFileScrty;
|
||||
import javax.annotation.Resource;
|
||||
import kr.xit.core.spring.auth.mapper.IAuthMapper;
|
||||
import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class AuthService extends EgovAbstractServiceImpl implements IAuthService {
|
||||
|
||||
@Resource
|
||||
private IAuthMapper mapper;
|
||||
|
||||
/**
|
||||
* 일반 로그인 처리
|
||||
* @param vo LoginVO
|
||||
* @return LoginVO
|
||||
*/
|
||||
@Override
|
||||
public LoginVO actionLogin(LoginVO vo) {
|
||||
|
||||
// 1. 입력한 비밀번호를 암호화한다.
|
||||
String enpassword = EgovFileScrty.encryptPassword(vo.getPassword(), vo.getId());
|
||||
vo.setPassword(enpassword);
|
||||
|
||||
// 2. 아이디와 암호화된 비밀번호가 DB와 일치하는지 확인한다.
|
||||
LoginVO loginVO = mapper.login(vo); //loginDAO.actionLogin(vo);
|
||||
|
||||
// 3. 결과를 리턴한다.
|
||||
if (loginVO != null && !loginVO.getId().equals("") && !loginVO.getPassword().equals("")) {
|
||||
return loginVO;
|
||||
} else {
|
||||
loginVO = new LoginVO();
|
||||
}
|
||||
|
||||
return loginVO;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package kr.xit.biz.auth.service;
|
||||
|
||||
import egovframework.com.cmm.model.LoginVO;
|
||||
|
||||
/**
|
||||
* 일반 로그인을 처리하는 비즈니스 구현 클래스
|
||||
* @author 공통서비스 개발팀 박지욱
|
||||
* @since 2009.03.06
|
||||
* @version 1.0
|
||||
* @see
|
||||
*
|
||||
* <pre>
|
||||
* << 개정이력(Modification Information) >>
|
||||
*
|
||||
* 수정일 수정자 수정내용
|
||||
* ------- -------- ---------------------------
|
||||
* 2009.03.06 박지욱 최초 생성
|
||||
* 2011.08.31 JJY 경량환경 템플릿 커스터마이징버전 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
public interface IAuthService {
|
||||
|
||||
/**
|
||||
* 일반 로그인 처리
|
||||
*
|
||||
* @param vo LoginVO
|
||||
* @return LoginVO
|
||||
*/
|
||||
LoginVO actionLogin(LoginVO vo);
|
||||
|
||||
}
|
@ -1,208 +0,0 @@
|
||||
package kr.xit.biz.auth.web;
|
||||
|
||||
import egovframework.com.cmm.model.LoginVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.ExampleObject;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import kr.xit.biz.auth.service.IAuthService;
|
||||
import kr.xit.core.consts.Constants;
|
||||
import kr.xit.core.consts.Constants.JwtToken;
|
||||
import kr.xit.core.model.ApiResponseDTO;
|
||||
import kr.xit.core.model.ClientInfoDTO;
|
||||
import kr.xit.core.model.IApiResponse;
|
||||
import kr.xit.core.model.TokenDTO;
|
||||
import kr.xit.core.spring.auth.jwt.JwtTokenProvider;
|
||||
import kr.xit.core.spring.util.MessageUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : 인증 로그인 처리
|
||||
*
|
||||
* packageName : kr.xit.biz.auth
|
||||
* fileName : AuthApiController
|
||||
* author : limju
|
||||
* date : 2023-04-26
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-04-26 limju 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
* @see
|
||||
*/
|
||||
@Tag(name = "AuthApiController", description = "인증 관리")
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping(value = "/auth")
|
||||
public class AuthController {
|
||||
@Value("${app.token.saveType:header}")
|
||||
private String authSaveType;
|
||||
|
||||
/** EgovLoginService */
|
||||
|
||||
private final IAuthService loginService;
|
||||
|
||||
/** EgovMessageSource */
|
||||
|
||||
private final MessageUtil messageUtil;
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
@Operation(summary = "로그인" , description = "로그인")
|
||||
@GetMapping(value = "/loginForm")
|
||||
public ModelAndView login() {
|
||||
return new ModelAndView("/auth/loginForm.html");
|
||||
}
|
||||
|
||||
/**
|
||||
* 일반 로그인을 처리한다
|
||||
* @param loginVO 아이디, 비밀번호가 담긴 LoginVO
|
||||
* @param request 세션처리를 위한 HttpServletRequest
|
||||
* @return 로그인결과(세션정보)
|
||||
*/
|
||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||
required = true,
|
||||
content = {
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
examples = {
|
||||
@ExampleObject(value = """
|
||||
{
|
||||
"id": "admin",
|
||||
"password": "1",
|
||||
"userSe": "USR"
|
||||
}
|
||||
""")
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@Operation(summary = "로그인" , description = "로그인")
|
||||
@PostMapping(value = "/login", consumes = {MediaType.APPLICATION_JSON_VALUE , MediaType.TEXT_HTML_VALUE})
|
||||
public IApiResponse login(@RequestBody final LoginVO loginVO, HttpServletRequest request) {
|
||||
// 1. 일반 로그인 처리
|
||||
LoginVO loginResultVO = loginService.actionLogin(loginVO);
|
||||
|
||||
if (loginResultVO != null && loginResultVO.getId() != null && !loginResultVO.getId().equals("")) {
|
||||
request.getSession().setAttribute(Constants.AuthSaveSession.LOGIN_VO.getCode(), loginResultVO);
|
||||
return ApiResponseDTO.success(loginResultVO);
|
||||
}
|
||||
return ApiResponseDTO.success(messageUtil.getMessage("fail.common.login"));
|
||||
}
|
||||
|
||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||
required = true,
|
||||
content = {
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
examples = {
|
||||
@ExampleObject(
|
||||
name = "admin",
|
||||
description = "admin",
|
||||
value = """
|
||||
{
|
||||
"id": "admin",
|
||||
"password": "1",
|
||||
"userSe": "USR"
|
||||
}
|
||||
"""),
|
||||
@ExampleObject(
|
||||
name = "admin1",
|
||||
description = "admin1",
|
||||
value = """
|
||||
{
|
||||
"id": "admin1",
|
||||
"password": "1",
|
||||
"userSe": "USR"
|
||||
}
|
||||
""")
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@Operation(summary = "로그인(JWT)" , description = "로그인(JWT)")
|
||||
@PostMapping(value = "/loginJwt")
|
||||
public IApiResponse loginJWT(@RequestBody final LoginVO loginVO, ClientInfoDTO clientInfo, final HttpServletRequest request, final HttpServletResponse response) {
|
||||
|
||||
HashMap<String, Object> resultMap = new HashMap<String, Object>();
|
||||
|
||||
// 1. 일반 로그인 처리
|
||||
LoginVO loginResultVO = loginService.actionLogin(loginVO);
|
||||
|
||||
if (loginResultVO != null && loginResultVO.getId() != null && !loginResultVO.getId().equals("")) {
|
||||
|
||||
Map<String, Object> claimsMap = new HashMap<>();
|
||||
// claimsMap.put("dkkdk", "kdkkdkdkd");
|
||||
TokenDTO tokenDTO = jwtTokenProvider.generateTokenDto(claimsMap, String.format("{}{}",loginVO.getUserSe(), loginVO.getId()));
|
||||
|
||||
// String jwtToken = egovJwtTokenUtil.generateToken(loginVO.getId());
|
||||
|
||||
String username = jwtTokenProvider.getUsernameFromToken(tokenDTO.getAccessToken());
|
||||
|
||||
|
||||
// System.out.println("Dec jwtToken username = "+username);
|
||||
|
||||
//서버사이드 권한 체크 통과를 위해 삽입
|
||||
//EgovUserDetailsHelper.isAuthenticated() 가 그 역할 수행. DB에 정보가 없으면 403을 돌려 줌. 로그인으로 튕기는 건 프론트 쪽에서 처리
|
||||
request.getSession().setAttribute(Constants.AuthSaveSession.LOGIN_VO.getCode(), loginResultVO);
|
||||
|
||||
|
||||
|
||||
|
||||
// UsernamePasswordAuthenticationToken authenticationToken = jwtTokenProvider.toAuthentication(loginVO.getId(), loginVO.getPassword());
|
||||
// Authentication authentication = authenticationManager.authenticate(authenticationToken);
|
||||
//
|
||||
//
|
||||
// // Authentication 저장
|
||||
// if(Objects.equals(authSaveType, Constants.AuthSaveType.SECURITY.getCode())){
|
||||
// // TODO :: SessionCreationPolicy.STATELESS 인 경우 사용 불가
|
||||
// SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
//
|
||||
// }else if(Objects.equals(authSaveType, Constants.AuthSaveType.SESSION.getCode())){
|
||||
// session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, SecurityContextHolder.getContext());
|
||||
// }
|
||||
|
||||
//Map<String, Object> infoMap = new HashMap<>();
|
||||
//infoMap.put(Constants.JwtToken.TOKEN_USER_ID.getCode(), loginVO.getId());
|
||||
//infoMap.put(Constants.JwtToken.TOKEN_USER_MAIL.getCode(), loginVO.getEmail());
|
||||
|
||||
//String jwtToken = jwtTokenProvider.generateJwtAccessToken(authentication, infoMap);
|
||||
//String jwtToken = jwtTokenProvider.generateJwtAccessToken(loginVO.getId(), "ROLE_USER");
|
||||
|
||||
resultMap.put("resultVO", loginResultVO);
|
||||
resultMap.put("token", tokenDTO);
|
||||
response.setHeader(JwtToken.HEADER_NAME.getCode(), String.format("%s %s", JwtToken.GRANT_TYPE.getCode(), tokenDTO.getAccessToken()));
|
||||
return ApiResponseDTO.success(resultMap);
|
||||
|
||||
}
|
||||
return ApiResponseDTO.error(messageUtil.getMessage("fail.common.login") );
|
||||
}
|
||||
|
||||
/**
|
||||
* 로그아웃한다.
|
||||
* @return resultVO
|
||||
* @exception Exception
|
||||
*/
|
||||
@Operation(summary = "logout" , description = "로그아웃")
|
||||
@GetMapping(value = "/logout")
|
||||
public IApiResponse actionLogoutJSON(HttpServletRequest request) {
|
||||
|
||||
RequestContextHolder.currentRequestAttributes().removeAttribute(Constants.AuthSaveSession.LOGIN_VO.getCode(), RequestAttributes.SCOPE_SESSION);
|
||||
return ApiResponseDTO.empty();
|
||||
}
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
package kr.xit.core.aop;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import kr.xit.core.exception.BizRuntimeException;
|
||||
import kr.xit.core.support.utils.Checks;
|
||||
import kr.xit.core.support.utils.JsonUtils;
|
||||
import kr.xit.core.support.utils.LogUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.JoinPoint;
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
import org.aspectj.lang.annotation.AfterThrowing;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : logging trace aspect
|
||||
* 공통 core 모듈의 LoggerAspect 상속 -> traceLogging / traceLoggingError / traceLoggingResult 구현
|
||||
*
|
||||
* Logging trace 구현시
|
||||
* - MDC(Mapped Diagnostic Context : logback, log4j에 포함) 사용 로깅
|
||||
* - ThreadLocal 사용
|
||||
* - nginx : proxy_set_header X-RequestID $request_id;
|
||||
* - logback log pattern : [traceId=%X{request_id}]
|
||||
*
|
||||
* app.slack-webhook.enabled: true인 경우 slack push
|
||||
* Slack webhook : SlackWebhookPush
|
||||
*
|
||||
* packageName : kr.xit.core.aop
|
||||
* fileName : TraceLoggerAspect
|
||||
* author : julim
|
||||
* date : 2023-04-28
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-04-28 julim 최초 생성
|
||||
* 2023-06-12 julim 배치처리시 RequestContextHolder.HttpServletRequest 객체 미사용에 따른 처리 추가
|
||||
* </pre>
|
||||
* @see kr.xit.core.support.slack.SlackWebhookPush#sendSlackAlertLog(String, String, String)
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
public class TraceLoggerAspect {
|
||||
|
||||
@Value("${app.log.request.custom-enabled:false}")
|
||||
private boolean isReqLogEnabled;
|
||||
|
||||
// 응답결과 로그
|
||||
@Value("${app.log.response-enabled:false}")
|
||||
private boolean isResLogEnabled;
|
||||
|
||||
@Pointcut("execution(public * egovframework..web.*.*(..)) || execution(public * kr.xit..web.*.*(..))")
|
||||
public void requestPointCut() {
|
||||
}
|
||||
|
||||
@Pointcut("execution(public * egovframework..*.*(..)) || execution(public * kr.xit..*.*(..))")
|
||||
public void errorPointCut() {
|
||||
}
|
||||
|
||||
@Pointcut("execution(public * egovframework..web.*.*(..)) || execution(public * kr.xit..web.*.*(..))")
|
||||
public void resultPointCut() {
|
||||
}
|
||||
|
||||
@Before(value = "requestPointCut()")
|
||||
public void logBefore(JoinPoint joinPoint) {
|
||||
if(!isReqLogEnabled) return;
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes != null? attributes.getRequest(): null;
|
||||
assert request != null;
|
||||
requestLog(request, getParams(request));
|
||||
}
|
||||
|
||||
@AfterReturning(pointcut = "resultPointCut()", returning = "result")
|
||||
public void logAfterReturning(final JoinPoint jp, final Object result) {
|
||||
if(isResLogEnabled) {
|
||||
log.info("{}{}{}",
|
||||
"\n//============================= Http Response ==============================",
|
||||
LogUtils.toString(result),
|
||||
"\n=========================================================================//"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterThrowing(value = "errorPointCut()", throwing="error")
|
||||
public void afterThrowingProceed(final JoinPoint jp, final Throwable error) {
|
||||
//traceApiLoggingError(jp, error);
|
||||
}
|
||||
|
||||
private String getResult(final Object o){
|
||||
//noinspection rawtypes
|
||||
if(o instanceof Future future) {
|
||||
try {
|
||||
return JsonUtils.toJson(future.get());
|
||||
} catch (InterruptedException ie){
|
||||
// thread pool에 에러 상태 전송
|
||||
Thread.currentThread().interrupt();
|
||||
throw BizRuntimeException.create(ie);
|
||||
|
||||
} catch (ExecutionException ee) {
|
||||
throw BizRuntimeException.create(ee);
|
||||
}
|
||||
}else{
|
||||
return JsonUtils.toJson(o);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestLog(HttpServletRequest request, JSONObject params) {
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
//sb.append("Ajax Call : " + "XMLHttpRequest".equals(request.getHeader(Globals.AJAX_HEADER))).append("\n");
|
||||
map.put("URI", request.getRequestURI());
|
||||
map.put("URL", request.getRequestURL());
|
||||
map.put("IP", request.getRemoteAddr());
|
||||
map.put("Referer URI", request.getHeader("referer"));
|
||||
map.put("Method", request.getMethod());
|
||||
map.put("User Agent", request.getHeader("User-Agent"));
|
||||
map.put("Session", request.getSession().getId());
|
||||
map.put("Locale", request.getLocale().getCountry());
|
||||
map.put("ContentType", request.getContentType());
|
||||
map.put("Parameters", params);
|
||||
|
||||
log.info("{}{}{}",
|
||||
"\n//============================= Http Request ==============================",
|
||||
LogUtils.toString(map),
|
||||
"\n=========================================================================//"
|
||||
);
|
||||
map.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private JSONObject getParams(HttpServletRequest request) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
Enumeration<String> params = request.getParameterNames();
|
||||
while (params.hasMoreElements()) {
|
||||
String param = params.nextElement();
|
||||
String replaceParam = param.replaceAll("\\.", "-");
|
||||
jsonObject.put(replaceParam, maskingParam(replaceParam, request.getParameter(param)));
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
private String maskingParam(final String key, final String value){
|
||||
if(Checks.isEmpty(value)) return value;
|
||||
if("juminId".equals(key)) {
|
||||
if(value.length() == 14) {
|
||||
return value.replaceAll("([0-9]{6})-([1-4]{1})([0-9]{6})", "$1-$2******");
|
||||
}
|
||||
return value.replaceAll("([0-9]{6})([1-4]{1})([0-9]{6})", "$1$2******");
|
||||
}
|
||||
if("telNo".equals(key)) {
|
||||
if(value.contains("-")){
|
||||
return value.replaceAll("-[0-9]{3,4}-", "-****-");
|
||||
};
|
||||
return value.replaceAll("([0-9]{3})([0-9]{4})([0-9]{4})", "$1$2****");
|
||||
}
|
||||
if("email".equals(key)) {
|
||||
return value.replaceAll("[a-z,A-Z,0-9]+@", "******@");
|
||||
}
|
||||
if("name".equals(key)) {
|
||||
return value.replaceAll("(?<=.{1}).", "*");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private String resetJsonMasking(final JSONObject json){
|
||||
for (Object key : json.keySet()) {
|
||||
if(Checks.isEmpty(json.get(key))) {
|
||||
json.put(key, json.get(key));
|
||||
}else {
|
||||
json.put(key, maskingParam((String) key, String.valueOf(json.get(key))));
|
||||
}
|
||||
}
|
||||
return json.toJSONString();
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package kr.xit.core.model;
|
||||
|
||||
import kr.xit.core.spring.config.WebServerConfig;
|
||||
import kr.xit.core.spring.resolver.ClientInfoArgumentResolver;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Client 헤더값 class
|
||||
* 헤더 값 set
|
||||
* -> 1. HandlerMethodArgumentResolver 인터페이스를 구현하여 ClientInfoDTO 객체 생성
|
||||
* 2. WebMvcConfigurer 인터페이스를 구현하여 Resolver 를 등록
|
||||
* 3. Controller 에서 헤더 값을 객체로 받는다.
|
||||
* packageName : kr.xit.core.model
|
||||
* fileName : ClientInfoDTO
|
||||
* author : limju
|
||||
* date : 2023-04-26
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-04-26 limju 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
* @see ClientInfoArgumentResolver
|
||||
* @see WebServerConfig
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
@Builder
|
||||
public class ClientInfoDTO {
|
||||
|
||||
private final String channel;
|
||||
private final String clientAddress;
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package kr.xit.core.spring.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import kr.xit.core.model.ApiResponseDTO;
|
||||
import kr.xit.core.support.utils.JsonUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
/**
|
||||
* fileName : JwtAuthenticationEntryPoint
|
||||
* author : crlee
|
||||
* date : 2023/06/11
|
||||
* description :
|
||||
* ===========================================================
|
||||
* DATE AUTHOR NOTE
|
||||
* -----------------------------------------------------------
|
||||
* 2023/06/11 crlee 최초 생성
|
||||
*/
|
||||
|
||||
//@Component
|
||||
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
||||
// 403 에러
|
||||
@SuppressWarnings("rawtypes")
|
||||
ApiResponseDTO apiResponseDTO = ApiResponseDTO.builder()
|
||||
.success(false)
|
||||
.code(String.valueOf(HttpStatus.FORBIDDEN.value()))
|
||||
.message("인가된 사용자가 아닙니다")
|
||||
.build();
|
||||
|
||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||
response.setContentType(MediaType.APPLICATION_JSON.toString());
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.getWriter().println(JsonUtils.toJson(apiResponseDTO));
|
||||
|
||||
//TODO:: 페이지 생성후 처리
|
||||
//response.sendRedirect("");
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package kr.xit.core.spring.auth;
|
||||
|
||||
import egovframework.com.cmm.model.LoginVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* fileName : CustomAuthenticationPrincipalResolver
|
||||
* author : crlee
|
||||
* date : 2023/07/13
|
||||
* description :
|
||||
* ===========================================================
|
||||
* DATE AUTHOR NOTE
|
||||
* -----------------------------------------------------------
|
||||
* 2023/07/13 crlee 최초 생성
|
||||
*/
|
||||
@Slf4j
|
||||
public class CustomAuthenticationPrincipalResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return parameter.hasParameterAnnotation(AuthenticationPrincipal.class) &&
|
||||
parameter.getParameterType().equals(LoginVO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
|
||||
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (authentication == null ||
|
||||
authentication.getPrincipal() == null ||
|
||||
"anonymousUser".equals(authentication.getPrincipal())
|
||||
) {
|
||||
log.info("익명(anonymousUser) 사용자 로그인 처리로 LoginVO 생성");
|
||||
return new LoginVO();
|
||||
}
|
||||
log.info("사용자 로그인 {}", authentication.getPrincipal());
|
||||
return authentication.getPrincipal();
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package kr.xit.core.spring.auth;
|
||||
|
||||
import java.util.List;
|
||||
import kr.xit.core.exception.BizRuntimeException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : 권한 정보를 생성하고 검증 하는 utilis class
|
||||
* packageName : kr.xit.core.spring.auth
|
||||
* fileName : CustomAuthorityUtils
|
||||
* author : julim
|
||||
* date : 2023-11-29
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-11-29 julim 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
public class CustomAuthorityUtils {
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* role 값을 기반으로 권한 정보를 생성하여 List<GrantedAuthority> 타입으로 변환
|
||||
* 권한 정보는 “ROLE_USER”, “ROLE_ADMIN” 형식으로 생성
|
||||
* @param role 권한 : ROLE_USR|ROLE_ADMIN 형태
|
||||
* @return List<GrantedAuthority> </pre>
|
||||
*/
|
||||
public static List<GrantedAuthority> createAuthorities(String role) {
|
||||
return List.of(new SimpleGrantedAuthority("ROLE_" + role));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 입력된 role 값이 유효한 권한인지 검증
|
||||
* @param role String USER|ADMIN
|
||||
*/
|
||||
public static void verifiedRole(String role) {
|
||||
if (role == null) {
|
||||
throw BizRuntimeException.create("fail.jwt.role.notExists");
|
||||
} else if (!role.equals("USER") && !role.equals("ADMIN")) {
|
||||
throw BizRuntimeException.create("fail.jwt.role.invalid", new String[]{role});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
package kr.xit.core.spring.auth;
|
||||
|
||||
import egovframework.com.cmm.model.LoginVO;
|
||||
import java.util.Collection;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : UserDetails 인터페이스를 구현한 클래스
|
||||
* Spring Security에서 관리하는 User 정보를 관리
|
||||
* packageName : kr.xit.core.spring.auth
|
||||
* fileName : CustomUserDetails
|
||||
* author : julim
|
||||
* date : 2023-11-29
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-11-29 julim 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@ToString
|
||||
public class CustomUserDetails implements UserDetails {
|
||||
private String id;
|
||||
private String email;
|
||||
private String role;
|
||||
private String password;
|
||||
|
||||
private CustomUserDetails(LoginVO loginVO) {
|
||||
this.id = loginVO.getId();
|
||||
this.email = loginVO.getEmail();
|
||||
this.password = loginVO.getPassword();
|
||||
//this.role = loginVO.getRole();
|
||||
}
|
||||
|
||||
private CustomUserDetails(String email, String role) {
|
||||
this.email = email;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
private CustomUserDetails(String email, String password, String role) {
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public static CustomUserDetails of(LoginVO loginVO) {
|
||||
return new CustomUserDetails(loginVO);
|
||||
}
|
||||
|
||||
public static CustomUserDetails of(String email, String role) {
|
||||
return new CustomUserDetails(email, role);
|
||||
}
|
||||
|
||||
public static CustomUserDetails of(String email, String password, String role) {
|
||||
return new CustomUserDetails(email, password, role);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 권한을 생성하고 List<GrantedAuthority> 타입으로 반환
|
||||
* @return Collection<? extends GrantedAuthority>
|
||||
* </pre>
|
||||
*/
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return CustomAuthorityUtils.createAuthorities(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* 계정이 만료되지 않았는가?
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 계정이 잠긴 상태인가?
|
||||
* @return true| false
|
||||
*/
|
||||
@Override
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 인증정보가 만료되지 않았는가?
|
||||
* @return true| flase
|
||||
*/
|
||||
@Override
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 계정이 활성화 상태인가?
|
||||
* @return true|false
|
||||
*/
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
package kr.xit.core.spring.auth;
|
||||
|
||||
import java.util.List;
|
||||
import kr.xit.core.spring.auth.filter.JwtAuthenticationFilter;
|
||||
import kr.xit.core.spring.auth.handler.CustomAccessDeniedHandler;
|
||||
import kr.xit.core.spring.auth.handler.CustomAuthenticationFailureHandler;
|
||||
import kr.xit.core.spring.auth.handler.CustomAuthenticationSuccessHandler;
|
||||
import kr.xit.core.spring.auth.jwt.JwtTokenProvider;
|
||||
import kr.xit.core.spring.auth.mapper.IAuthMapper;
|
||||
import kr.xit.core.spring.util.AES128Config;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
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.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Spring security 설정
|
||||
* packageName : kr.xit.core.spring.auth
|
||||
* fileName : SecurityConfig
|
||||
* author : julim
|
||||
* date : 2023-11-29
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-11-29 julim 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@RequiredArgsConstructor
|
||||
public class SecurityConfig implements WebMvcConfigurer {
|
||||
//Http Methpd : Get 인증예외 List
|
||||
private String[] AUTH_GET_WHITELIST = {
|
||||
"/schedule/daily", //일별 일정 조회
|
||||
"/schedule/week", //주간 일정 조회
|
||||
"/schedule/{schdulId}", //일정 상세조회
|
||||
};
|
||||
|
||||
// 인증 예외 List
|
||||
@Value("${app.spring.security.white-list}")
|
||||
private String[] AUTH_WHITELIST;
|
||||
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final AES128Config aes128Config;
|
||||
private final IAuthMapper authMapper;
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(new CustomAuthenticationPrincipalResolver());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* SecurityFilterChain 설정
|
||||
* -> 애플리케이션의 보안 설정을 구성
|
||||
* <code>headers().frameOptions().sameOrigin()</code> : X-Frame-Options 헤더 설정을 SAMEORIGIN으로 설정하여, 웹 페이지를 iframe으로 삽입하는 공격 방지를 위한 설정
|
||||
* <code>http.csrf().disable()</code> : jwt를 사용하기 때문에 CSRF(Cross-Site Request Forgery) 공격 방지 기능을 사용하지 않는다.
|
||||
* <code>http.cors().configurationSource(corsConfigurationSource())</code> : CORS(Cross-Origin Resource Sharing)를 활성화 및 설정 - 공통에서 처리
|
||||
* <code>http.formLogin().disable()</code> : 폼 기반 로그인 방식 비활성화
|
||||
* <code>http.httpBasic().disable()</code> : HTTP 기본 인증 방식 비활성화
|
||||
* <code>sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)</code> :인증에 사용할 세션을 생성하지 않도록 설정
|
||||
* <code>exceptionHandling()</code> :예외 처리를 설정
|
||||
* <code>authenticationEntryPoint(new CustomAuthenticationEntryPoint())</code> :인증되지 않은 사용자가 보호된 리소스에 접근할 때 호출할 엔드포인트 설정
|
||||
* <code>accessDeniedHandler(new CustomAccessDeniedHandler())</code> :인가되지 않은 사용자가 보호된 리소스에 접근할 때 호출할 핸들러 설정
|
||||
* <code>apply(new CustomFilterConfigurer())</code> :사용자 정의 필터 적용
|
||||
* <code>authorizeHttpRequests(authorize -> authorize.anyRequest().permitAll())</code> :모든 HTTP 요청에 대해 접근 허용
|
||||
* @param http HttpSecurity
|
||||
* @return SecurityFilterChain
|
||||
* </pre>
|
||||
*/
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.headers().frameOptions().sameOrigin()
|
||||
.and()
|
||||
.csrf().disable()
|
||||
//.cors().configurationSource(corsConfigurationSource())
|
||||
.cors().and()
|
||||
//.formLogin().disable()
|
||||
//.httpBasic().disable()
|
||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
.and()
|
||||
.exceptionHandling()
|
||||
// .authenticationEntryPoint(
|
||||
// (request, response, authException) -> response.sendRedirect(""))
|
||||
// .accessDeniedHandler(
|
||||
// (request, response, accessDeniedException) -> response.sendRedirect(""))
|
||||
.authenticationEntryPoint(new CustomAuthenticationEntryPoint())
|
||||
.accessDeniedHandler(new CustomAccessDeniedHandler())
|
||||
.and()
|
||||
.apply(new CustomFilterConfigurer(authMapper))
|
||||
.and()
|
||||
// TODO: 추후 권한 별 페이지 접근제어 설정 예정
|
||||
.authorizeHttpRequests(authorize -> authorize
|
||||
.antMatchers(AUTH_WHITELIST).permitAll()
|
||||
//.antMatchers(AUTH_WHITELIST).authenticated()
|
||||
.antMatchers(HttpMethod.GET,AUTH_GET_WHITELIST).permitAll()
|
||||
.anyRequest().authenticated()
|
||||
);
|
||||
|
||||
return http.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : 보안 설정을 정의하는 HttpSecurity를 구성
|
||||
* -> 인증 및 권한 부여를 위해 사용되는 필터 체인을 구성하는 데 사용
|
||||
* - AbstractHttpConfigurer 를 상속하며 configure() 메서드를 재정의
|
||||
* packageName : kr.xit.core.spring.auth
|
||||
* fileName : CustomFilterConfigurer
|
||||
* author : julim
|
||||
* date : 2023-11-29
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-11-29 julim 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class CustomFilterConfigurer extends
|
||||
AbstractHttpConfigurer<CustomFilterConfigurer, HttpSecurity> {
|
||||
private final IAuthMapper authMapper;
|
||||
|
||||
@Override
|
||||
public void configure(HttpSecurity httpSecurity) throws Exception {
|
||||
log.info("SecurityConfiguration.CustomFilterConfigurer.configure excute");
|
||||
AuthenticationManager authenticationManager = httpSecurity.getSharedObject(
|
||||
AuthenticationManager.class);
|
||||
JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager,
|
||||
jwtTokenProvider, aes128Config, authMapper);
|
||||
//JwtVerificationFilter jwtVerificationFilter = new JwtVerificationFilter(jwtTokenProvider, redisService);
|
||||
|
||||
jwtAuthenticationFilter.setFilterProcessesUrl("/auth/login");
|
||||
jwtAuthenticationFilter.setAuthenticationSuccessHandler(new CustomAuthenticationSuccessHandler());
|
||||
jwtAuthenticationFilter.setAuthenticationFailureHandler(new CustomAuthenticationFailureHandler());
|
||||
|
||||
httpSecurity
|
||||
.addFilter(jwtAuthenticationFilter)
|
||||
// .addFilterAfter(jwtVerificationFilter, JwtAuthenticationFilter.class);
|
||||
// .addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
package kr.xit.core.spring.auth.filter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import egovframework.com.cmm.model.LoginVO;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import kr.xit.core.exception.BizRuntimeException;
|
||||
import kr.xit.core.model.RefreshTokenDTO;
|
||||
import kr.xit.core.model.TokenDTO;
|
||||
import kr.xit.core.spring.auth.CustomUserDetails;
|
||||
import kr.xit.core.spring.auth.jwt.JwtTokenProvider;
|
||||
import kr.xit.core.spring.auth.mapper.IAuthMapper;
|
||||
import kr.xit.core.spring.util.AES128Config;
|
||||
import kr.xit.core.support.utils.DateUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : 로그인을 담당/ 토큰 발급을 진행
|
||||
* UsernamePasswordAuthenticationFilter를 상속 받는 경우
|
||||
* 1. 필터를 거치고 다음 필터로 동작을 넘기지 않는다.
|
||||
* -> 따라서 인증 성공 여부에 따른 메서드 successfulAuthentication/unSuccessfulAuthentication 구현 필요
|
||||
* 2. 해당 필터는 /login에 접근할 때만 동작
|
||||
* -> 따라서 특정 Url에서 필터가 동작하길 원한다면 setFilterProcessesUrl()로 Url를 설정해야 한다
|
||||
* 3. 위와 같은 특징 때문에 Jwt 필터를 따로 만들어줘야 한다.
|
||||
* packageName : kr.xit.core.spring.auth.filter
|
||||
* fileName : JwtAuthorizationFilter
|
||||
* author : julim
|
||||
* date : 2023-11-29
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-11-29 julim 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final AES128Config aes128Config;
|
||||
private final IAuthMapper authMapper;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request,
|
||||
HttpServletResponse response) throws AuthenticationException {
|
||||
// ServletInputStream을 LoginDto 객체로 역직렬화
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
LoginVO loginVO = objectMapper.readValue(request.getInputStream(), LoginVO.class);
|
||||
UsernamePasswordAuthenticationToken authenticationToken =
|
||||
new UsernamePasswordAuthenticationToken(loginVO.getEmail(), loginVO.getPassword());
|
||||
|
||||
return authenticationManager.authenticate(authenticationToken);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException, ServletException {
|
||||
CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal();
|
||||
|
||||
Map<String,Object> cliams = new HashMap<>();
|
||||
cliams.put("role", customUserDetails.getRole());
|
||||
TokenDTO tokenDto = jwtTokenProvider.generateTokenDto(cliams, customUserDetails.getUsername());
|
||||
|
||||
String accessToken = tokenDto.getAccessToken();
|
||||
String refreshToken = tokenDto.getRefreshToken();
|
||||
String encryptedRefreshToken = aes128Config.encryptAes(refreshToken);
|
||||
jwtTokenProvider.accessTokenSetHeader(accessToken, response);
|
||||
jwtTokenProvider.refresshTokenSetHeader(encryptedRefreshToken, response);
|
||||
|
||||
LoginVO loginVO = authMapper.selectUserById(customUserDetails.getId())
|
||||
.orElseThrow(() -> BizRuntimeException.of("fail.auth.login.user"));
|
||||
|
||||
//TODO:: 로그인 성공시 Refresh Token 저장
|
||||
Date date = jwtTokenProvider.getExpirationDateFromToken(refreshToken);
|
||||
authMapper.saveRefreshToken(
|
||||
RefreshTokenDTO.builder()
|
||||
.id(loginVO.getId())
|
||||
.refreshToken(refreshToken)
|
||||
.refreshTokenExpiresIn(DateUtils.parseToLong(date))
|
||||
.build()
|
||||
);
|
||||
//...(loginVO.getId(), refreshToken, Duration.ofMillis(DateUtils.parseToLong(date)));
|
||||
|
||||
this.getSuccessHandler().onAuthenticationSuccess(request, response, authentication);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package kr.xit.core.spring.auth.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
|
||||
|
||||
private String denied_url;
|
||||
|
||||
public CustomAccessDeniedHandler() {
|
||||
this.denied_url = "egovframework/com/cmm/error/csrfAccessDenied";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response,
|
||||
AccessDeniedException accessDeniedException) throws IOException, ServletException {
|
||||
response.sendRedirect(request.getContextPath() + denied_url);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package kr.xit.core.spring.auth.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.InsufficientAuthenticationException;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
|
||||
throws IOException, ServletException, IOException {
|
||||
|
||||
String errorMessage = "Invalid Username or Password";
|
||||
|
||||
if(exception instanceof BadCredentialsException){
|
||||
errorMessage = "Invalid Username or Password";
|
||||
}else if(exception instanceof InsufficientAuthenticationException){
|
||||
errorMessage = "Invalid Secret Key";
|
||||
}
|
||||
|
||||
setDefaultFailureUrl("/auth/login?error=true&exception=" + exception.getMessage());
|
||||
|
||||
super.onAuthenticationFailure(request, response, exception);
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package kr.xit.core.spring.auth.handler;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.DefaultRedirectStrategy;
|
||||
import org.springframework.security.web.RedirectStrategy;
|
||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
|
||||
import org.springframework.security.web.savedrequest.RequestCache;
|
||||
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||
|
||||
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
|
||||
private final RequestCache requestCache = new HttpSessionRequestCache();
|
||||
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication authentication) throws IOException, ServletException {
|
||||
|
||||
setDefaultTargetUrl("/auth/login");
|
||||
SavedRequest savedRequest = requestCache.getRequest(request, response);
|
||||
|
||||
// 사용자가 권한이 필요한 자원에 접근해 인증 예외가 발생해 인증을 처리하는 것이 아닌 경우
|
||||
// SavedRequest 객체가 생성되지 않는다.
|
||||
if (savedRequest != null) {
|
||||
String targetUrl = savedRequest.getRedirectUrl();
|
||||
redirectStrategy.sendRedirect(request, response, targetUrl);
|
||||
} else {
|
||||
redirectStrategy.sendRedirect(request, response, getDefaultTargetUrl());
|
||||
}
|
||||
super.clearAuthenticationAttributes(request);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package kr.xit.core.spring.auth.mapper;
|
||||
|
||||
import egovframework.com.cmm.model.LoginVO;
|
||||
import java.util.Optional;
|
||||
import kr.xit.core.model.RefreshTokenDTO;
|
||||
import org.egovframe.rte.psl.dataaccess.mapper.Mapper;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description :
|
||||
*
|
||||
* packageName : kr.xit.core.spring.auth.mapper
|
||||
* fileName : IAuthMapper
|
||||
* author : limju
|
||||
* date : 2023-11-29
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-11-29 limju 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@Mapper
|
||||
public interface IAuthMapper {
|
||||
<T> LoginVO login(T t);
|
||||
Optional<LoginVO> selectUserById(String id);
|
||||
|
||||
int saveRefreshToken(final RefreshTokenDTO dto);
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package kr.xit.core.spring.auth.service;
|
||||
|
||||
import egovframework.com.cmm.model.LoginVO;
|
||||
import kr.xit.core.exception.BizRuntimeException;
|
||||
import kr.xit.core.spring.auth.CustomUserDetails;
|
||||
import kr.xit.core.spring.auth.mapper.IAuthMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class CustomUserDetailsService implements UserDetailsService {
|
||||
private final IAuthMapper mapper;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
return mapper.selectUserById(username)
|
||||
.map(this::createUserDetails)
|
||||
.orElseThrow(() -> BizRuntimeException.of("fail.auth.login.user"));
|
||||
}
|
||||
|
||||
private UserDetails createUserDetails(LoginVO member) {
|
||||
return CustomUserDetails.of(member);
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package kr.xit.core.spring.config;
|
||||
|
||||
import org.springdoc.core.GroupedOpenApi;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Springdoc(swagger) 설정
|
||||
* 설정내용이 상이한 경우 동일한 파일로 재정의 하거나 상속받아 사용
|
||||
* packageName : kr.xit.core.spring.config
|
||||
* fileName : SpringDocsConfig
|
||||
* author : julim
|
||||
* date : 2023-04-28
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-04-28 julim 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
*/
|
||||
@ConditionalOnProperty(value = "springdoc.swagger-ui.enabled", havingValue = "true", matchIfMissing = false)
|
||||
@Configuration
|
||||
public class SpringDocsApiConfig {
|
||||
@Bean
|
||||
public GroupedOpenApi authentification() {
|
||||
return GroupedOpenApi.builder()
|
||||
.group("1. Authentification API")
|
||||
.pathsToMatch(
|
||||
"/auth/**"
|
||||
)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package kr.xit.core.spring.config;
|
||||
|
||||
import java.util.List;
|
||||
import kr.xit.core.model.ClientInfoDTO;
|
||||
import kr.xit.core.spring.resolver.ClientInfoArgumentResolver;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Web server 설정
|
||||
* packageName : kr.xit.core.spring.config
|
||||
* fileName : WebServerConfig
|
||||
* author : limju
|
||||
* date : 2023-04-26
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-04-26 limju 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
* @see ClientInfoDTO
|
||||
* @see WebServerConfig
|
||||
*/
|
||||
@Configuration
|
||||
public class WebServerConfig implements WebMvcConfigurer {
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
|
||||
resolvers.add(new ClientInfoArgumentResolver());
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package kr.xit.core.spring.resolver;
|
||||
|
||||
import kr.xit.core.model.ClientInfoDTO;
|
||||
import kr.xit.core.spring.config.WebServerConfig;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Client 헤더값에서 ClientInfoDTO 객체 생성
|
||||
* HandlerMethodArgumentResolver 인터페이스를 구현하여 ClientInfoDTO 객체 생성
|
||||
* -> WebMvcConfigurer 인터페이스를 구현하여 Resolver 를 등록
|
||||
* packageName : kr.xit.core.spring.resolver
|
||||
* fileName : ClientInfoArgumentResolver
|
||||
* author : limju
|
||||
* date : 2023-04-26
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-04-26 limju 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
* @see ClientInfoDTO
|
||||
* @see WebServerConfig
|
||||
*/
|
||||
public class ClientInfoArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private static final String HEADER_CHANNEL = "X-APP-CHANNEL";
|
||||
private static final String HEADER_CLIENT_IP = "X-FORWORD-FOR";
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return ClientInfoDTO.class.equals(parameter.getParameterType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(@Nullable MethodParameter parameter,
|
||||
ModelAndViewContainer mavContainer,
|
||||
NativeWebRequest webRequest,
|
||||
WebDataBinderFactory binderFactory) throws Exception {
|
||||
|
||||
String channel = webRequest.getHeader(HEADER_CHANNEL);
|
||||
String clientAddress = webRequest.getHeader(HEADER_CLIENT_IP);
|
||||
return new ClientInfoDTO(channel, clientAddress);
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package kr.xit.core.spring.util;
|
||||
|
||||
import kr.xit.core.spring.config.support.ApplicationContextProvider;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* description : Get Bean Object
|
||||
* Filter / Interceptor 등에서 Bean 사용시 필요
|
||||
* (Bean으로 등록되는 클래스 내에서만 @Autowired / @Resource 등이 동작)
|
||||
* packageName : kr.xit.core.spring.util
|
||||
* fileName : AdminSpringUtils
|
||||
* author : julim
|
||||
* date : 2023-04-28
|
||||
* ======================================================================
|
||||
* 변경일 변경자 변경 내용
|
||||
* ----------------------------------------------------------------------
|
||||
* 2023-04-28 julim 최초 생성
|
||||
*
|
||||
* </pre>
|
||||
* @see ApplicationContextProvider
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class AdminSpringUtils {
|
||||
|
||||
public static ApplicationContext getApplicationContext() {
|
||||
return ApplicationContextProvider.getApplicationContext();
|
||||
}
|
||||
|
||||
public static boolean containsBean(String beanName) {
|
||||
return getApplicationContext().containsBean(beanName);
|
||||
}
|
||||
|
||||
public static Object getBean(String beanName) {
|
||||
return getApplicationContext().getBean(beanName);
|
||||
}
|
||||
|
||||
public static Object getBean(Class<?> clazz) {
|
||||
return getApplicationContext().getBean(clazz);
|
||||
}
|
||||
|
||||
// public static ICmmEnsCacheService getCmmEnsCacheService(){
|
||||
// return (ICmmEnsCacheService)getBean(CmmEnsCacheService.class);
|
||||
// }
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#-----------------------------------------------------------------------
|
||||
# application 설정
|
||||
#-----------------------------------------------------------------------
|
||||
|
||||
app:
|
||||
#---------------------------------------------------------------
|
||||
# log 설정
|
||||
# request:
|
||||
# custom-enabled | common-enabled | filter-enabled 중 1개만 활성화
|
||||
# --> 운영: common-enabled, 개발: custom-enabled 사용 권장
|
||||
# response-enabled : 호출 결과 출력 - 운영시 false
|
||||
# mdc : api 호출(서비스) 로그 기록
|
||||
# uris : api 호출 로그 제외 패턴
|
||||
#---------------------------------------------------------------
|
||||
log:
|
||||
request:
|
||||
# exclude pattern : CommonsRequestLoggingFilter && LoggingFilter 적용
|
||||
exclude-patterns: '/swagger-ui/(.*), /api-docs/(.*), /favicon.ico'
|
||||
custom-enabled: false
|
||||
# CommonsRequestLoggingFilter 사용 parameter 로그 출력
|
||||
common-enabled: false
|
||||
# Filter를 사용한 로그 출력
|
||||
filter-enabled: false
|
||||
response-enabled: false
|
||||
|
||||
# slack
|
||||
slack-webhook:
|
||||
enabled: false
|
||||
url: https://hooks.slack.com/services/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
|
@ -1,82 +0,0 @@
|
||||
#-----------------------------------------------------------------------
|
||||
# dev 설정
|
||||
#-----------------------------------------------------------------------
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
# 9 server
|
||||
primary:
|
||||
database: mysql
|
||||
driver-class-name: org.mariadb.jdbc.Driver
|
||||
jdbc-url: jdbc:mariadb://211.119.124.9:4407/mens?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
|
||||
username: root
|
||||
password: xit1807
|
||||
read-only: false
|
||||
|
||||
# multi-database
|
||||
#secondary:
|
||||
|
||||
devtools:
|
||||
livereload:
|
||||
enabled: true
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
enabled: true
|
||||
swagger-ui:
|
||||
enabled: true
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: debug
|
||||
org.apache.http: warn
|
||||
io.netty: warn
|
||||
reactor.netty: WARN
|
||||
# webclient logging
|
||||
reactor.netty.http.client: DEBUG
|
||||
#org.springframework.web.reactive.function.client.ExchangeFunctions: TRACE
|
||||
org.springframework: warn
|
||||
org.hibernate.validator.internal: WARN
|
||||
file:
|
||||
# 로그파일 위치
|
||||
path: ${app.data.root.path}/mens/logs
|
||||
name: ${app.name}
|
||||
|
||||
# ==================================================================================================================
|
||||
# SQL logging lib setting
|
||||
# ==================================================================================================================
|
||||
decorator:
|
||||
datasource:
|
||||
p6spy:
|
||||
enable-logging: true
|
||||
|
||||
app:
|
||||
api-ip: 211.119.124.9
|
||||
# 강제로 swagger-url을 지정해야 하는 경우만 선언
|
||||
#swagger-url: 'http://localhost:${server.port}${server.servlet.context-path:}/'
|
||||
# Spring Security cors 설정 :: CorsConfiguration 설정 값
|
||||
cors:
|
||||
allowed-origins: http://localhost:8080, http://${app.api-ip}:8080, http://localhost:8082, http://${app.api-ip}:8082
|
||||
|
||||
data:
|
||||
root:
|
||||
path: /data
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# log 설정
|
||||
# request:
|
||||
# custom-enabled | common-enabled | filter-enabled 중 1개만 활성화
|
||||
# --> 운영: common-enabled, 개발: custom-enabled 사용 권장
|
||||
# response-enabled : 호출 결과 출력 - 운영시 false
|
||||
# mdc : api 호출(서비스) 로그 기록
|
||||
# uris : api 호출 로그 제외 패턴
|
||||
#---------------------------------------------------------------
|
||||
log:
|
||||
request:
|
||||
custom-enabled: true
|
||||
response-enabled: true
|
||||
|
||||
# slack
|
||||
slack-webhook:
|
||||
enabled: false
|
||||
url: https://hooks.slack.com/services/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
|
@ -1,93 +0,0 @@
|
||||
#-----------------------------------------------------------------------
|
||||
# local 설정
|
||||
#-----------------------------------------------------------------------
|
||||
server:
|
||||
port: 8444
|
||||
http: 8080
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
# 9 server
|
||||
primary:
|
||||
database: mysql
|
||||
driver-class-name: org.mariadb.jdbc.Driver
|
||||
jdbc-url: jdbc:mariadb://211.119.124.9:4407/mens?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
|
||||
username: root
|
||||
password: xit1807
|
||||
read-only: false
|
||||
# multi-database
|
||||
#secondary:
|
||||
|
||||
devtools:
|
||||
restart:
|
||||
enabled: true
|
||||
additional-exclude: static/**,public/**
|
||||
livereload:
|
||||
enabled: true
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
enabled: true
|
||||
swagger-ui:
|
||||
enabled: true
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: debug
|
||||
org.apache.http: warn
|
||||
io.netty: warn
|
||||
reactor.netty: WARN
|
||||
# webclient logging
|
||||
reactor.netty.http.client: DEBUG
|
||||
#org.springframework.web.reactive.function.client.ExchangeFunctions: TRACE
|
||||
org.springframework: warn
|
||||
org.hibernate.validator.internal: WARN
|
||||
file:
|
||||
# 로그파일 위치
|
||||
path: ${app.data.root.path}/mens/logs
|
||||
name: ${app.name}
|
||||
|
||||
# ==================================================================================================================
|
||||
# SQL logging lib setting
|
||||
# ==================================================================================================================
|
||||
decorator:
|
||||
datasource:
|
||||
p6spy:
|
||||
enable-logging: true
|
||||
|
||||
app:
|
||||
api-ip: 211.119.124.73
|
||||
# 강제로 swagger-url을 지정해야 하는 경우만 선언
|
||||
#swagger-url: 'http://localhost:${server.port}${server.servlet.context-path:}/'
|
||||
# Spring Security cors 설정 :: CorsConfiguration 설정 값
|
||||
cors:
|
||||
allowed-origins:
|
||||
http://localhost:${server.http},
|
||||
http://${app.api-ip}:${server.http},
|
||||
https://localhost:${server.port},
|
||||
https://${app.api-ip}:${server.port}
|
||||
|
||||
data:
|
||||
root:
|
||||
#path: /Users/minuk/data
|
||||
path: d:/data
|
||||
|
||||
#---------------------------------------------------------------
|
||||
# log 설정
|
||||
# request:
|
||||
# custom-enabled | common-enabled | filter-enabled 중 1개만 활성화
|
||||
# --> 운영: common-enabled, 개발: custom-enabled 사용 권장
|
||||
# response-enabled : 호출 결과 출력 - 운영시 false
|
||||
# mdc : api 호출(서비스) 로그 기록
|
||||
# uris : api 호출 로그 제외 패턴
|
||||
#---------------------------------------------------------------
|
||||
log:
|
||||
request:
|
||||
custom-enabled: true
|
||||
response-enabled: true
|
||||
|
||||
# slack
|
||||
slack-webhook:
|
||||
enabled: false
|
||||
url: https://hooks.slack.com/services/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
|
||||
|
@ -1,82 +0,0 @@
|
||||
#-----------------------------------------------------------------------
|
||||
# prod 설정
|
||||
#-----------------------------------------------------------------------
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
# 9 server
|
||||
primary:
|
||||
database: mysql
|
||||
driver-class-name: org.mariadb.jdbc.Driver
|
||||
# jdbc:mariadb://127.0.0.1:4407/mens?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&autoReconnect=true
|
||||
jdbc-url: ENC(N7TRplIpBBUbXtSi8fx0wr92OdMgvp9Iw5tmaW7EUaH6ialiAWohx+rOEZx/j+OHFkJSrhYQElPIVe5r4d0tWDNREpgvKwxZRTGXhNdTMMUUHonkGKfB7bURxMfjuMSQEUdKicPZv+xB9eGlwcuPpgC7vaQuZM6WrUDP31+6qYboTUQKBK/7lg==)
|
||||
username: ENC(wgnjrc4VB7R3I+OwMV+iXQ==)
|
||||
password: ENC(+sXCmhmSV3Q/3KgOnmpnTQ==)
|
||||
read-only: false
|
||||
# multi-database
|
||||
#secondary:
|
||||
|
||||
devtools:
|
||||
livereload:
|
||||
enabled: false
|
||||
|
||||
springdoc:
|
||||
api-docs:
|
||||
enabled: false
|
||||
swagger-ui:
|
||||
enabled: false
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: warn
|
||||
org.apache.http: warn
|
||||
io.netty: warn
|
||||
reactor.netty: WARN
|
||||
# webclient logging
|
||||
reactor.netty.http.client: warn
|
||||
#org.springframework.web.reactive.function.client.ExchangeFunctions: TRACE
|
||||
org.springframework: warn
|
||||
org.hibernate.validator.internal: WARN
|
||||
file:
|
||||
# 로그파일 위치
|
||||
path: ${app.data.root.path}/mens/logs
|
||||
name: ${app.name}
|
||||
|
||||
# ==================================================================================================================
|
||||
# SQL logging lib setting
|
||||
# ==================================================================================================================
|
||||
decorator:
|
||||
datasource:
|
||||
p6spy:
|
||||
enable-logging: true
|
||||
|
||||
app:
|
||||
api-ip: 103.145.215.46
|
||||
# 강제로 swagger-url을 지정해야 하는 경우만 선언
|
||||
swagger-url: 'http://103.145.215.46:8081/${server.servlet.context-path:}/'
|
||||
# Spring Security cors 설정 :: CorsConfiguration 설정 값
|
||||
cors:
|
||||
allowed-origins: http://localhost, http://${app.api-ip}, http://localhost:8082, http://${app.api-ip}:8082, https://ens.sisul.or.kr
|
||||
|
||||
data:
|
||||
root:
|
||||
path: /data
|
||||
#---------------------------------------------------------------
|
||||
# log 설정
|
||||
# request:
|
||||
# custom-enabled | common-enabled | filter-enabled 중 1개만 활성화
|
||||
# --> 운영: common-enabled, 개발: custom-enabled 사용 권장
|
||||
# response-enabled : 호출 결과 출력 - 운영시 false
|
||||
# mdc : api 호출(서비스) 로그 기록
|
||||
# uris : api 호출 로그 제외 패턴
|
||||
#---------------------------------------------------------------
|
||||
log:
|
||||
request:
|
||||
common-enabled: true
|
||||
response-enabled: false
|
||||
|
||||
# slack
|
||||
slack-webhook:
|
||||
enabled: false
|
||||
url: https://hooks.slack.com/services/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
|
||||
|
@ -1,110 +0,0 @@
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# egovframework 설정
|
||||
# api 공통 설정
|
||||
#-----------------------------------------------------------------------
|
||||
Globals:
|
||||
# DB서버 타입(hsql,mysql,oracle,altibase,tibero) - datasource 및 sqlMap 파일 지정에 사용됨
|
||||
DbType: mysql
|
||||
|
||||
# MainPage Setting
|
||||
MainPage: /cmm/main/mainPage.do
|
||||
|
||||
#server.servlet.context-path=/sht_boot_web
|
||||
server:
|
||||
port: 8080
|
||||
error:
|
||||
whitelabel:
|
||||
enabled: false
|
||||
app:
|
||||
name: mens-admin
|
||||
# springdoc url 정보
|
||||
desc: 모바일 전자고지 Administrator
|
||||
# spring security ignore
|
||||
spring:
|
||||
security:
|
||||
white-list:
|
||||
favicon.ico,
|
||||
/,
|
||||
/semantic/**
|
||||
/auth/loginForm*,
|
||||
/auth/login*,
|
||||
/auth/loginJwt*,
|
||||
/api-docs/**,
|
||||
/swagger-resources,
|
||||
/swagger-ui.html,
|
||||
/swagger-ui/**
|
||||
data:
|
||||
root:
|
||||
path: /data
|
||||
file:
|
||||
cmm:
|
||||
temp-path: ${app.data.root.path}/temp
|
||||
upload:
|
||||
root: ${app.data.root.path}
|
||||
# root: /data
|
||||
# E-GREEN 우편 발송
|
||||
post: /post/rcv/
|
||||
|
||||
spring:
|
||||
main:
|
||||
# 순환참조 에러 무시
|
||||
allow-circular-references: true
|
||||
pid:
|
||||
file: ${app.data.root.path}/${app.name}.pid
|
||||
profiles:
|
||||
active: '@springProfilesActive@'
|
||||
|
||||
# core의 application-common.yml과 application-auth.yml include
|
||||
include:
|
||||
- https
|
||||
- common
|
||||
- auth
|
||||
- app
|
||||
# mvc:
|
||||
# static-path-pattern: /resources/static/**
|
||||
# view:
|
||||
# prefix:
|
||||
# suffix: .html
|
||||
|
||||
|
||||
batch:
|
||||
jdbc:
|
||||
initialize-schema: NEVER #NEVER|ALWAYS
|
||||
# JPA does not support custom isolation levels, so locks may not be taken when launching Jobs.
|
||||
# To silence this warning, set 'spring.batch.jdbc.isolation-level-for-create' to 'default'.
|
||||
isolation-level-for-create: default
|
||||
job:
|
||||
enabled: false
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
# xit framework 설정
|
||||
#-----------------------------------------------------------------
|
||||
datasource:
|
||||
#type: com.zaxxer.hikari.HikariDataSource
|
||||
hikari:
|
||||
primary:
|
||||
pool-name: xit-maria-pool
|
||||
auto-commit: false
|
||||
# 인프라의 적용된 connection time limit보다 작아야함
|
||||
max-lifetime: 1800000
|
||||
maximum-pool-size: 15
|
||||
minimum-idle: 5
|
||||
#transaction-isolation: TRANSACTION_READ_UNCOMMITTED
|
||||
data-source-properties:
|
||||
rewriteBatchedStatements: true
|
||||
|
||||
# secondary:
|
||||
# pool-name: xit-oracle-pool
|
||||
# auto-commit: false
|
||||
# # 인프라의 적용된 connection time limit보다 작아야함
|
||||
# max-lifetime: 1800000
|
||||
# maximum-pool-size: 15
|
||||
# minimum-idle: 5
|
||||
## transaction-isolation: TRANSACTION_READ_UNCOMMITTED
|
||||
# data-source-properties:
|
||||
# rewriteBatchedStatements: true
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: error
|
@ -1,382 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!--
|
||||
Checkstyle configuration that checks the Google coding conventions from Google Java Style
|
||||
that can be found at https://google.github.io/styleguide/javaguide.html
|
||||
|
||||
Checkstyle is very configurable. Be sure to read the documentation at
|
||||
http://checkstyle.org (or in your downloaded distribution).
|
||||
|
||||
To completely disable a check, just comment it out or delete it from the file.
|
||||
To suppress certain violations please review suppression filters.
|
||||
|
||||
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
|
||||
-->
|
||||
|
||||
<module name="Checker">
|
||||
<module name="SuppressWarningsFilter"/>
|
||||
|
||||
<property name="charset" value="UTF-8"/>
|
||||
|
||||
<property name="severity" value="warning"/>
|
||||
|
||||
<property name="fileExtensions" value="java, properties, xml"/>
|
||||
<!-- Excludes all 'module-info.java' files -->
|
||||
<!-- See https://checkstyle.org/filefilters/index.html -->
|
||||
<module name="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||
</module>
|
||||
<!-- https://checkstyle.org/filters/suppressionfilter.html -->
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${org.checkstyle.google.suppressionfilter.config}"
|
||||
default="checkstyle-suppressions.xml" />
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.org/checks/whitespace/index.html -->
|
||||
<module name="FileTabCharacter">
|
||||
<property name="eachLine" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="LineLength">
|
||||
<property name="fileExtensions" value="java"/>
|
||||
<property name="max" value="120"/>
|
||||
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<module name="OuterTypeFilename"/>
|
||||
<module name="IllegalTokenText">
|
||||
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
|
||||
<property name="format"
|
||||
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
|
||||
<property name="message"
|
||||
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
|
||||
</module>
|
||||
<module name="AvoidEscapedUnicodeCharacters">
|
||||
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||
<property name="allowByTailComment" value="true"/>
|
||||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
</module>
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="OneTopLevelClass"/>
|
||||
<module name="NoLineWrap">
|
||||
<property name="tokens" value="PACKAGE_DEF, IMPORT, STATIC_IMPORT"/>
|
||||
</module>
|
||||
<module name="EmptyBlock">
|
||||
<property name="option" value="TEXT"/>
|
||||
<property name="tokens"
|
||||
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
|
||||
</module>
|
||||
<module name="NeedBraces">
|
||||
<property name="tokens"
|
||||
value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/>
|
||||
</module>
|
||||
<module name="LeftCurly">
|
||||
<property name="tokens"
|
||||
value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_CONSTANT_DEF, ENUM_DEF,
|
||||
INTERFACE_DEF, LAMBDA, LITERAL_CASE, LITERAL_CATCH, LITERAL_DEFAULT,
|
||||
LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF,
|
||||
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF,
|
||||
OBJBLOCK, STATIC_INIT, RECORD_DEF, COMPACT_CTOR_DEF"/>
|
||||
</module>
|
||||
<module name="RightCurly">
|
||||
<property name="id" value="RightCurlySame"/>
|
||||
<property name="tokens"
|
||||
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
|
||||
LITERAL_DO"/>
|
||||
</module>
|
||||
<module name="RightCurly">
|
||||
<property name="id" value="RightCurlyAlone"/>
|
||||
<property name="option" value="alone"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
|
||||
INSTANCE_INIT, ANNOTATION_DEF, ENUM_DEF, INTERFACE_DEF, RECORD_DEF,
|
||||
COMPACT_CTOR_DEF, LITERAL_SWITCH"/>
|
||||
</module>
|
||||
<module name="SuppressionXpathSingleFilter">
|
||||
<!-- suppresion is required till https://github.com/checkstyle/checkstyle/issues/7541 -->
|
||||
<property name="id" value="RightCurlyAlone"/>
|
||||
<property name="query" value="//RCURLY[parent::SLIST[count(./*)=1]
|
||||
or preceding-sibling::*[last()][self::LCURLY]]"/>
|
||||
</module>
|
||||
<module name="WhitespaceAfter">
|
||||
<property name="tokens"
|
||||
value="COMMA, SEMI, TYPECAST, LITERAL_IF, LITERAL_ELSE, LITERAL_RETURN,
|
||||
LITERAL_WHILE, LITERAL_DO, LITERAL_FOR, LITERAL_FINALLY, DO_WHILE, ELLIPSIS,
|
||||
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_CATCH, LAMBDA,
|
||||
LITERAL_YIELD, LITERAL_CASE"/>
|
||||
</module>
|
||||
<module name="WhitespaceAround">
|
||||
<property name="allowEmptyConstructors" value="true"/>
|
||||
<property name="allowEmptyLambdas" value="true"/>
|
||||
<property name="allowEmptyMethods" value="true"/>
|
||||
<property name="allowEmptyTypes" value="true"/>
|
||||
<property name="allowEmptyLoops" value="true"/>
|
||||
<property name="ignoreEnhancedForColon" value="false"/>
|
||||
<property name="tokens"
|
||||
value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR,
|
||||
BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAMBDA, LAND,
|
||||
LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,
|
||||
LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
|
||||
LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN,
|
||||
NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR,
|
||||
SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
|
||||
<message key="ws.notFollowed"
|
||||
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks
|
||||
may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
|
||||
<message key="ws.notPreceded"
|
||||
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
|
||||
</module>
|
||||
<module name="OneStatementPerLine"/>
|
||||
<module name="MultipleVariableDeclarations"/>
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<module name="FallThrough"/>
|
||||
<module name="UpperEll"/>
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="tokens"
|
||||
value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
||||
STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,
|
||||
COMPACT_CTOR_DEF"/>
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="id" value="SeparatorWrapDot"/>
|
||||
<property name="tokens" value="DOT"/>
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="id" value="SeparatorWrapComma"/>
|
||||
<property name="tokens" value="COMMA"/>
|
||||
<property name="option" value="EOL"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<!-- ELLIPSIS is EOL until https://github.com/google/styleguide/issues/259 -->
|
||||
<property name="id" value="SeparatorWrapEllipsis"/>
|
||||
<property name="tokens" value="ELLIPSIS"/>
|
||||
<property name="option" value="EOL"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<!-- ARRAY_DECLARATOR is EOL until https://github.com/google/styleguide/issues/258 -->
|
||||
<property name="id" value="SeparatorWrapArrayDeclarator"/>
|
||||
<property name="tokens" value="ARRAY_DECLARATOR"/>
|
||||
<property name="option" value="EOL"/>
|
||||
</module>
|
||||
<module name="SeparatorWrap">
|
||||
<property name="id" value="SeparatorWrapMethodRef"/>
|
||||
<property name="tokens" value="METHOD_REF"/>
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
<module name="PackageName">
|
||||
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Package name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="TypeName">
|
||||
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
||||
ANNOTATION_DEF, RECORD_DEF"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="MemberName">
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Member name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="ParameterName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="LambdaParameterName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="CatchParameterName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="LocalVariableName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="PatternVariableName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Pattern variable name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="ClassTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Class type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="RecordComponentName">
|
||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Record component name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="RecordTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Record type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="MethodTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Method type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="InterfaceTypeParameterName">
|
||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="NoFinalizer"/>
|
||||
<module name="GenericWhitespace">
|
||||
<message key="ws.followed"
|
||||
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
|
||||
<message key="ws.preceded"
|
||||
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
|
||||
<message key="ws.illegalFollow"
|
||||
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
|
||||
<message key="ws.notPreceded"
|
||||
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
|
||||
</module>
|
||||
<module name="Indentation">
|
||||
<property name="basicOffset" value="4"/>
|
||||
<property name="braceAdjustment" value="4"/>
|
||||
<property name="caseIndent" value="4"/>
|
||||
<property name="throwsIndent" value="4"/>
|
||||
<property name="lineWrappingIndentation" value="4"/>
|
||||
<property name="arrayInitIndent" value="4"/>
|
||||
</module>
|
||||
<module name="AbbreviationAsWordInName">
|
||||
<property name="ignoreFinal" value="false"/>
|
||||
<property name="allowedAbbreviationLength" value="0"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,
|
||||
PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, PATTERN_VARIABLE_DEF, RECORD_DEF,
|
||||
RECORD_COMPONENT_DEF"/>
|
||||
</module>
|
||||
<module name="NoWhitespaceBeforeCaseDefaultColon"/>
|
||||
<module name="OverloadMethodsDeclarationOrder"/>
|
||||
<module name="VariableDeclarationUsageDistance"/>
|
||||
<module name="CustomImportOrder">
|
||||
<property name="sortImportsInGroupAlphabetically" value="true"/>
|
||||
<property name="separateLineBetweenGroups" value="true"/>
|
||||
<property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
|
||||
<property name="tokens" value="IMPORT, STATIC_IMPORT, PACKAGE_DEF"/>
|
||||
</module>
|
||||
<module name="MethodParamPad">
|
||||
<property name="tokens"
|
||||
value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
|
||||
SUPER_CTOR_CALL, ENUM_CONSTANT_DEF, RECORD_DEF"/>
|
||||
</module>
|
||||
<module name="NoWhitespaceBefore">
|
||||
<property name="tokens"
|
||||
value="COMMA, SEMI, POST_INC, POST_DEC, DOT,
|
||||
LABELED_STAT, METHOD_REF"/>
|
||||
<property name="allowLineBreaks" value="true"/>
|
||||
</module>
|
||||
<module name="ParenPad">
|
||||
<property name="tokens"
|
||||
value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF,
|
||||
EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,
|
||||
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,
|
||||
METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA,
|
||||
RECORD_DEF"/>
|
||||
</module>
|
||||
<module name="OperatorWrap">
|
||||
<property name="option" value="NL"/>
|
||||
<property name="tokens"
|
||||
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
|
||||
LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF,
|
||||
TYPE_EXTENSION_AND "/>
|
||||
</module>
|
||||
<module name="AnnotationLocation">
|
||||
<property name="id" value="AnnotationLocationMostCases"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF,
|
||||
RECORD_DEF, COMPACT_CTOR_DEF"/>
|
||||
</module>
|
||||
<module name="AnnotationLocation">
|
||||
<property name="id" value="AnnotationLocationVariables"/>
|
||||
<property name="tokens" value="VARIABLE_DEF"/>
|
||||
<property name="allowSamelineMultipleAnnotations" value="true"/>
|
||||
</module>
|
||||
<module name="NonEmptyAtclauseDescription"/>
|
||||
<module name="InvalidJavadocPosition"/>
|
||||
<module name="JavadocTagContinuationIndentation"/>
|
||||
<module name="SummaryJavadoc">
|
||||
<property name="forbiddenSummaryFragments"
|
||||
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
|
||||
</module>
|
||||
<module name="JavadocParagraph"/>
|
||||
<module name="RequireEmptyLineBeforeBlockTagGroup"/>
|
||||
<module name="AtclauseOrder">
|
||||
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
|
||||
<property name="target"
|
||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
||||
</module>
|
||||
<module name="JavadocMethod">
|
||||
<property name="accessModifiers" value="public"/>
|
||||
<property name="allowMissingParamTags" value="true"/>
|
||||
<property name="allowMissingReturnTag" value="true"/>
|
||||
<property name="allowedAnnotations" value="Override, Test"/>
|
||||
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/>
|
||||
</module>
|
||||
<module name="MissingJavadocMethod">
|
||||
<property name="scope" value="public"/>
|
||||
<property name="minLineCount" value="2"/>
|
||||
<property name="allowedAnnotations" value="Override, Test"/>
|
||||
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF,
|
||||
COMPACT_CTOR_DEF"/>
|
||||
</module>
|
||||
<module name="MissingJavadocType">
|
||||
<property name="scope" value="protected"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
||||
RECORD_DEF, ANNOTATION_DEF"/>
|
||||
<property name="excludeScope" value="nothing"/>
|
||||
</module>
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[a-z][a-z0-9]\w*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Method name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
<module name="SingleLineJavadoc"/>
|
||||
<module name="EmptyCatchBlock">
|
||||
<property name="exceptionVariableName" value="expected"/>
|
||||
</module>
|
||||
<module name="CommentsIndentation">
|
||||
<property name="tokens" value="SINGLE_LINE_COMMENT, BLOCK_COMMENT_BEGIN"/>
|
||||
</module>
|
||||
<!-- https://checkstyle.org/filters/suppressionxpathfilter.html -->
|
||||
<module name="SuppressionXpathFilter">
|
||||
<property name="file" value="${org.checkstyle.google.suppressionxpathfilter.config}"
|
||||
default="checkstyle-xpath-suppressions.xml" />
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
<module name="SuppressWarningsHolder" />
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)" />
|
||||
<property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)" />
|
||||
<property name="checkFormat" value="$1" />
|
||||
</module>
|
||||
<module name="SuppressWithNearbyCommentFilter">
|
||||
<property name="commentFormat" value="CHECKSTYLE.SUPPRESS\: ([\w\|]+)"/>
|
||||
<!-- $1 refers to the first match group in the regex defined in commentFormat -->
|
||||
<property name="checkFormat" value="$1"/>
|
||||
<!-- The check is suppressed in the next line of code after the comment -->
|
||||
<property name="influenceFormat" value="1"/>
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="kr.xit.core.spring.auth.mapper.IAuthMapper">
|
||||
<!-- 일반 로그인 -->
|
||||
<select id="login" resultType="egovframework.com.cmm.model.LoginVO">
|
||||
<if test="userSe = 'USR'">
|
||||
/** auth-mysql-mapper|login-로그인|julim */
|
||||
SELECT user_id AS id
|
||||
, user_nm AS name
|
||||
, password
|
||||
, ihidnum
|
||||
, email_adres AS email
|
||||
, 'USR' AS userSe
|
||||
, orgnzt_id
|
||||
, esntl_id
|
||||
FROM xit_user_info
|
||||
WHERE user_id = #{id}
|
||||
AND password = #{password}
|
||||
AND user_sttus_code = 'P'
|
||||
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectUserById" resultType="egovframework.com.cmm.model.LoginVO">
|
||||
<if test="userSe = 'USR'">
|
||||
/** auth-mysql-mapper|selectUserById-사용자조회|julim */
|
||||
SELECT user_id AS id
|
||||
, user_nm AS name
|
||||
, password
|
||||
, ihidnum
|
||||
, email_adres AS email
|
||||
, 'USR' AS userSe
|
||||
, orgnzt_id
|
||||
, esntl_id
|
||||
FROM xit_user_info
|
||||
WHERE user_id = #{id}
|
||||
AND user_sttus_code = 'P'
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<insert id="saveRefreshToken">
|
||||
|
||||
</insert>
|
||||
|
||||
</mapper>
|
@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||
|
||||
<configuration>
|
||||
<!--
|
||||
cacheEnabled 설정에서 각 mapper 에 설정된 캐시를 전역적으로 사용할지 말지에 대한 여부 true | false true
|
||||
lazyLoadingEnabled 늦은 로딩을 사용할지에 대한 여부. 사용하지 않는다면 모두 즉시 로딩할 것이다. 이 값은 fetchType 속성을 사용해서 대체할 수 있다. true | false false
|
||||
aggressiveLazyLoading 활성화 상태로 두게 되면 늦은(lazy) 로딩 프로퍼티를 가진 객체는 호출에 따라 로드될 것이다. 반면에 개별 프로퍼티는 요청할때 로드된다. true | false true
|
||||
multipleResultSetsEnabled 한개의 구문에서 여러개의 ResultSet 을 허용할지의 여부(드라이버가 해당 기능을 지원해야 함) true | false true
|
||||
useColumnLabel 칼럼명 대신에 칼럼라벨을 사용. 드라이버마다 조금 다르게 작동한다. 문서와 간단한 테스트를 통해 실제 기대하는 것처럼 작동하는지 확인해야 한다. true | false true
|
||||
useGeneratedKeys 생성키에 대한 JDBC 지원을 허용. 지원하는 드라이버가 필요하다. true 로 설정하면 생성키를 강제로 생성한다. 일부 드라이버(예를들면, Derby)에서는 이 설정을 무시한다. true | false False
|
||||
autoMappingBehavior MyBatis 가 칼럼을 필드/프로퍼티에 자동으로 매핑할지와 방법에 대해 명시. PARTIAL 은 간단한 자동매핑만 할뿐, 내포된 결과에 대해서는 처리하지 않는다. FULL 은 처리가능한 모든 자동매핑을 처리한다. NONE, PARTIAL, FULL PARTIAL
|
||||
defaultExecutorType 디폴트 실행자(executor) 설정. SIMPLE 실행자는 특별히 하는 것이 없다. REUSE 실행자는 PreparedStatement 를 재사용한다. BATCH 실행자는 구문을 재사용하고 수정을 배치처리한다. SIMPLE REUSE BATCH SIMPLE
|
||||
defaultStatementTimeout 데이터베이스로의 응답을 얼마나 오래 기다릴지를 판단하는 타임아웃을 셋팅 양수 셋팅되지 않음(null)
|
||||
safeRowBoundsEnabled 중첩구문내 RowBound 사용을 허용 true | false False
|
||||
mapUnderscoreToCamelCase 전통적인 데이터베이스 칼럼명 형태인 A_COLUMN을 CamelCase형태의 자바 프로퍼티명 형태인 aColumn으로 자동으로 매핑하도록 함 true | false False
|
||||
localCacheScope 마이바티스는 순환참조를 막거나 반복된 쿼리의 속도를 높히기 위해 로컬캐시를 사용한다. 디폴트 설정인 SESSION을 사용해서 동일 세션의 모든 쿼리를 캐시한다. localCacheScope=STATEMENT 로 설정하면 로컬 세션은 구문 실행할때만 사용하고 같은 SqlSession에서 두개의 다른 호출사이에는 데이터를 공유하지 않는다. SESSION | STATEMENT SESSION
|
||||
jdbcTypeForNull JDBC타입을 파라미터에 제공하지 않을때 null값을 처리한 JDBC타입을 명시한다. 일부 드라이버는 칼럼의 JDBC타입을 정의하도록 요구하지만 대부분은 NULL, VARCHAR 나 OTHER 처럼 일반적인 값을 사용해서 동작한다. JdbcType 이늄. 대부분은 NULL, VARCHAR 나 OTHER 를 공통적으로 사용한다. OTHER
|
||||
lazyLoadTriggerMethods 늦은 로딩을 야기하는 객체의 메소드를 명시 메소드 이름을 나열하고 여러개일 경우 콤마(,) 로 구분 equals,clone,hashCode,toString
|
||||
defaultScriptingLanguage 동적으로 SQL을 만들기 위해 기본적으로 사용하는 언어를 명시 타입별칭이나 패키지 경로를 포함한 클래스명 org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver
|
||||
callSettersOnNulls 가져온 값이 null일때 setter나 맵의 put 메소드를 호출할지를 명시 Map.keySet() 이나 null값을 초기화할때 유용하다. int, boolean 등과 같은 원시타입은 null을 셋팅할 수 없다는 점은 알아두면 좋다. true | false false
|
||||
logPrefix 마이바티스가 로거(logger) 이름에 추가할 접두사 문자열을 명시 문자열 셋팅하지 않음
|
||||
logImpl 마이바티스가 사용할 로깅 구현체를 명시 이 설정을 사용하지 않으면 마이바티스가 사용할 로깅 구현체를 자동으로 찾는다. SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING 셋팅하지 않음
|
||||
proxyFactory 마이바티스가 늦은 로딩을 처리할 객체를 생성할 때 사용할 프록시 툴을 명시 CGLIB | JAVASSIST CGLIB
|
||||
-->
|
||||
<settings>
|
||||
<!--
|
||||
Settings 설정 옵션 사이트 참조
|
||||
-.사이트주소: https://postitforhooney.tistory.com/entry/MyBatisSetting-Mybatis%EC%97%90%EC%84%9C-%ED%95%84%EC%9A%94%ED%95%9C-%EB%B6%80%EB%B6%84%EB%93%A4-setting%EC%9E%90%EB%A3%8C
|
||||
-->
|
||||
<setting name="mapUnderscoreToCamelCase" value="true"/>
|
||||
<setting name="cacheEnabled" value="true" />
|
||||
<setting name="jdbcTypeForNull" value="VARCHAR" /><!-- NULL / VARCHAR / OTHER-->
|
||||
<setting name="callSettersOnNulls" value="true"/> <!-- resultType으로 Map Collection 지정 시 value가 null일 떄 컬럼 누락문제 해결을 위한 설정 -->
|
||||
|
||||
<setting name="lazyLoadingEnabled" value="false" />
|
||||
<setting name="multipleResultSetsEnabled" value="true" />
|
||||
<setting name="useColumnLabel" value="true" />
|
||||
<setting name="useGeneratedKeys" value="false" />
|
||||
<setting name="autoMappingBehavior" value="PARTIAL" /><!-- NONE / PARTIAL / FULL-->
|
||||
<setting name="defaultExecutorType" value="SIMPLE" /><!-- SIMPLE / REUSE / BATCH-->
|
||||
<setting name="defaultStatementTimeout" value="25" />
|
||||
<setting name="safeRowBoundsEnabled" value="false" />
|
||||
<setting name="localCacheScope" value="SESSION" /><!-- SESSION / STATEMENT-->
|
||||
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
|
||||
<setting name="aggressiveLazyLoading" value="true" />
|
||||
</settings>
|
||||
|
||||
<!-- Type Aliases 설정-->
|
||||
<!-- <typeAliases>-->
|
||||
<!-- <typeAlias alias="egovMap" type="org.egovframe.rte.psl.dataaccess.util.EgovMap" />-->
|
||||
<!-- <typeAlias alias="ComDefaultCodeVO" type="egovframework.com.cmm.model.ComDefaultCodeVO" />-->
|
||||
<!-- <typeAlias alias="comDefaultVO" type="egovframework.com.cmm.model.ComDefaultVO" />-->
|
||||
<!-- </typeAliases>-->
|
||||
|
||||
</configuration>
|
@ -1,7 +0,0 @@
|
||||
#------------------------------------------------
|
||||
# Admin \uBA54\uC138\uC9C0 \uC815\uC758
|
||||
#------------------------------------------------
|
||||
fail.auth.header.invalid=header\uAC00 \uC5C6\uAC70\uB098, \uD615\uC2DD\uC774 \uD2C0\uB9BD\uB2C8\uB2E4({0})
|
||||
|
||||
fail.auth.login.user=\uC0AC\uC6A9\uC790(\uD68C\uC6D0) \uC815\uBCF4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||
|
@ -1,3 +0,0 @@
|
||||
#------------------------------------------------
|
||||
# Admin \uBA54\uC138\uC9C0 \uC815\uC758
|
||||
#------------------------------------------------
|
@ -1,3 +0,0 @@
|
||||
#------------------------------------------------
|
||||
# Admin \uBA54\uC138\uC9C0 \uC815\uC758
|
||||
#------------------------------------------------
|
@ -1,183 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true" scanPeriod="30 seconds">
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
|
||||
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
|
||||
|
||||
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
|
||||
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
|
||||
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
|
||||
|
||||
<!--
|
||||
logback-spring.xml 로 설정시 스프링의 환경변수를 로그백 시스템 환경변수로 사용
|
||||
logging.file.name => LOG_FILE, logging.file.path => LOG_PATH
|
||||
logging.charset.console / file => CONSOLE_LOG_CHARSET, FILE_LOG_CHARSET
|
||||
-->
|
||||
|
||||
<!-- async rolling appender 사용시 로그의 class, method, line number 출력 제어 : 성능저하 이슈 -->
|
||||
<springProfile name="local, dev">
|
||||
<property name="isIncludeCallerData" value="true"/>
|
||||
</springProfile>
|
||||
<springProfile name="prod">
|
||||
<property name="isIncludeCallerData" value="false"/>
|
||||
</springProfile>
|
||||
|
||||
<!-- ============================================================================= -->
|
||||
<!-- console logging Appender defined -->
|
||||
<!-- ============================================================================= -->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- 기본 출력 로그 제거 -->
|
||||
<Filter class="kr.xit.core.support.logback.ExcludeLogFilter"/>
|
||||
<encoder>
|
||||
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
|
||||
<charset>${CONSOLE_LOG_CHARSET}</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- ============================================================================= -->
|
||||
|
||||
<!-- ============================================================================= -->
|
||||
<!-- file logging Appender defined -->
|
||||
<!-- ============================================================================= -->
|
||||
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${LOG_PATH}/${LOG_FILE}.log</file>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>DEBUG</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<!-- 다른 수준의 레벨은 기록하지 않는다.(상위 레벨도 기록 안함), 상위 수준의 레벨에 대한 기록을 원하면 ACCEPT 로 하면 기록된다. -->
|
||||
<onMismatch>ACCEPT</onMismatch>
|
||||
</filter>
|
||||
<!-- 기본 출력 로그 제거 -->
|
||||
<!--Filter class="kr.xit.core.support.logback.ExcludeLogFilter"/-->
|
||||
|
||||
<encoder>
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
<charset>${FILE_LOG_CHARSET}</charset>
|
||||
</encoder>
|
||||
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${LOG_PATH}/backup/${LOG_FILE}_%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>30MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<maxHistory>50</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<!-- async appender defined -->
|
||||
<!-- includeCallerData=true -->
|
||||
<appender name="ASYNC_ROLLING" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<appender-ref ref="ROLLING"/>
|
||||
<!-- blocking queue의 최대 수용 갯수로 기본값은 256 -->
|
||||
<queueSize>2048</queueSize>
|
||||
<discardingThreshold>20</discardingThreshold>
|
||||
<!-- 해당 시간안에 처리하지 못한 이벤트는 삭제 : 단위 - ms -->
|
||||
<maxFlushTime>6000</maxFlushTime>
|
||||
<!--큐가 가득찬 상황에서 메세지 유실을 방지하기 위해 application block 할지 여부 -->
|
||||
<!-- true로 설정된 경우 application을 멈추지 않기 위해 메세지를 버린다 -->
|
||||
<neverBlock>true</neverBlock>
|
||||
<!-- 메소드명, 라인번호 출력 : 성능저하 요인 -->
|
||||
<includeCallerData>${isIncludeCallerData}</includeCallerData>
|
||||
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
</appender>
|
||||
<!-- ============================================================================= -->
|
||||
|
||||
<!-- ============================================================================= -->
|
||||
<!-- logging mask defined -->
|
||||
<!-- ============================================================================= -->
|
||||
<appender name="mask" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
|
||||
<layout class="kr.xit.core.support.logback.LogbackMaskingPatternLayout">
|
||||
<maskPattern>\"juminId\"\s*:\s*\"(.*?)\"</maskPattern> <!-- SSN JSON pattern -->
|
||||
<maskPattern>\"recveJuminno\"\s*:\s*\"(.*?)\"</maskPattern> <!-- SSN JSON pattern -->
|
||||
<maskPattern>\"recevAddr\"\s*:\s*\"(.*?)\"</maskPattern> <!-- Address JSON pattern -->
|
||||
<maskPattern>\"recevDetailAddr\"\s*:\s*\"(.*?)\"</maskPattern> <!-- Address JSON pattern -->
|
||||
<pattern>%-5p [%d{ISO8601,UTC}] [%thread] %c: %m%n%rootException</pattern>
|
||||
</layout>
|
||||
</encoder>
|
||||
</appender>
|
||||
<!-- ============================================================================= -->
|
||||
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- SQL log : root appender로 로그 전파 - additivity="true" -->
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- DB transaction -->
|
||||
<logger name="org.mybatis.spring.SqlSessionUtils" level="DEBUG" />
|
||||
<!-- log4jdbc 옵션 설정 -->
|
||||
<logger name="jdbc" level="OFF"/>
|
||||
|
||||
<springProfile name="prod">
|
||||
<!-- 운영 환경에서만 sql문 및 결과 출력하지 않음 -->
|
||||
<!-- SQL문과 소요된 시간 -->
|
||||
<logger name="jdbc.sqltiming" level="OFF"/>
|
||||
<!-- SQL 결과 조회된 데이터를 table 형식으로 출력 -->
|
||||
<logger name="jdbc.resultsettable" level="OFF"/>
|
||||
</springProfile>
|
||||
|
||||
<springProfile name="local, dev">
|
||||
<!-- 로컬, 개발 환경에서는 sql문 및 결과 출력 -->
|
||||
<!-- SQL문과 소요된 시간 -->
|
||||
<logger name="jdbc.sqltiming" level="DEBUG" />
|
||||
<!-- SQL 결과 조회된 데이터를 table 형식으로 출력 -->
|
||||
<logger name="jdbc.resultsettable" level="DEBUG" />
|
||||
</springProfile>
|
||||
|
||||
<!-- SQL문 출력 -->
|
||||
<logger name="jdbc.sqlonly" level="OFF"/>
|
||||
<!-- result를 포함한 모든 JDBC 호출 정보 -->
|
||||
<logger name="jdbc.resultset" level="OFF"/>
|
||||
<!-- DB connection open/close -->
|
||||
<logger name="jdbc.connection" level="OFF"/>
|
||||
<!-- resultset을 제외한 JDBC 호출 정보 -->
|
||||
<logger name="jdbc.audit" level="OFF"/>
|
||||
<logger name="org.mariadb.jdbc" level="ERROR"/>
|
||||
|
||||
<!-- DB Connection Pool 관련 -->
|
||||
<logger name="com.zaxxer.hikari.pool.PoolBase" level="ERROR" />
|
||||
<logger name="com.zaxxer.hikari.pool.HikariPool" level="ERROR" />
|
||||
<logger name="com.zaxxer.hikari.HikariDataSource" level="ERROR" />
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- SQL log -->
|
||||
<!-- ************************************************************************* -->
|
||||
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- spring / 3rdparty log : root appender로 로그 전파 - additivity="true" -->
|
||||
<!-- ************************************************************************* -->
|
||||
<logger name="io.swagger.v3.core.converter" level="INFO"/>
|
||||
<logger name="org.egovframe.rte.fdl.cmmn.exception.manager" level="INFO"/>
|
||||
<logger name="org.egovframe.rte.fdl.cmmn.aspect.ExceptionTransfer" level="INFO"/>
|
||||
<logger name="org.egovframe" level="ERROR"/>
|
||||
<logger name="org.apache.commons" level="INFO"/>
|
||||
<logger name="com.zaxxer.hikari.pool.HikariPool" level="INFO"/>
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- spring / 3rdparty log -->
|
||||
<!-- ************************************************************************* -->
|
||||
|
||||
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- application log : root appender로 로그 전파 - additivity="true" -->
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- <logger name="org.springframework.web.filter.MustRequestLoggingFilter" level="DEBUG" additivity="false"/>-->
|
||||
<!--logger name="kr.xit.core.filter.CustomRequestLoggingFilter" level="DEBUG"/-->
|
||||
<logger name="kr.xit" level="DEBUG"/>
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- application log -->
|
||||
<!-- ************************************************************************* -->
|
||||
|
||||
|
||||
<!-- ************************************************************************* -->
|
||||
<!-- root logging -->
|
||||
<!-- ************************************************************************* -->
|
||||
<root level="DEBUG">
|
||||
<springProfile name="prod">
|
||||
<appender-ref ref="ASYNC_ROLLING"/>
|
||||
</springProfile>
|
||||
|
||||
<springProfile name="local, dev">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="ASYNC_ROLLING"/>
|
||||
</springProfile>
|
||||
</root>
|
||||
|
||||
</configuration>
|
@ -1,66 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css" href="/resources/static/semantic/dist/semantic.min.css">
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.1.1.min.js"
|
||||
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="/resources/static/semantic/dist/semantic.min.js"></script>
|
||||
<title>login</title>
|
||||
</head>
|
||||
<body>
|
||||
<form class="ui form">
|
||||
<div class="field">
|
||||
<label>id</label>
|
||||
<input type="text" name="id" placeholder="사용자 ID" value="admin">
|
||||
</div>
|
||||
<div class="field">
|
||||
<label>password</label>
|
||||
<input type="text" name="password" placeholder="비밀번호" value="1">
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" tabindex="0" class="hidden">
|
||||
<label>id 저장</label>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="userSe" value="USR">
|
||||
<button class="ui button" type="submit">Submit</button>
|
||||
</form>
|
||||
</body>
|
||||
<script>
|
||||
|
||||
const postForm = (body) => {
|
||||
return fetch('/auth/loginJwt', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-APP-CHANNEL': 'WEB',
|
||||
'X-FORWORD-FOR': '211.119.124.73',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const form = document.querySelector('form');
|
||||
const data = Object.fromEntries(new FormData(form).entries());
|
||||
|
||||
// const body = {
|
||||
// id: document.querySelector('input[name="id"]').value,
|
||||
// password: document.querySelector('input[name="password"]').value,
|
||||
// userSe: document.querySelector('input[name="userSe"]').value,
|
||||
// }
|
||||
|
||||
const res = await postForm(JSON.stringify(data))
|
||||
const json = await res.json();
|
||||
console.log(json)
|
||||
};
|
||||
|
||||
document.querySelector('form').addEventListener("click", handleSubmit);
|
||||
</script>
|
||||
</html>
|
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Error</p>
|
||||
</body>
|
||||
</html>
|
@ -1,16 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>전자고지 API Framework</title>
|
||||
</head>
|
||||
<body>
|
||||
<h3>전자고지 API Framework</h3>
|
||||
<p>
|
||||
<a href="http://localhost:8081/swagger-ui.html">API Document</a>
|
||||
</p>
|
||||
<p>
|
||||
자세한 사항은 README.md 참고
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,33 +0,0 @@
|
||||
README.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
@ -1,143 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>kr.xit</groupId>
|
||||
<artifactId>mens-parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>xit-init</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>xit-init</name>
|
||||
<description>xit-init</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- migration 완료후 제거 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-properties-migrator</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- migration 완료후 제거 -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.70</version>
|
||||
</dependency>
|
||||
<!-- proguard -->
|
||||
<dependency>
|
||||
<groupId>com.guardsquare</groupId>
|
||||
<artifactId>proguard-base</artifactId>
|
||||
<version>${proguard-base-version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.guardsquare</groupId>
|
||||
<artifactId>proguard-core</artifactId>
|
||||
<version>${proguard-core-version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<defaultGoal>install</defaultGoal>
|
||||
<directory>${basedir}/target</directory>
|
||||
<finalName>${project.name}</finalName>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.wvengen</groupId>
|
||||
<artifactId>proguard-maven-plugin</artifactId>
|
||||
<version>${proguard-plugin-version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<!-- proguard -->
|
||||
<!--
|
||||
<plugin>
|
||||
<groupId>com.github.wvengen</groupId>
|
||||
<artifactId>proguard-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>proguard</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<injar>${project.build.finalName}.jar</injar>
|
||||
<outjar>${project.build.finalName}.jar</outjar>
|
||||
<obfuscate>true</obfuscate>
|
||||
<addMavenDescriptor>false</addMavenDescriptor>
|
||||
<proguardInclude>proguard.cfg</proguardInclude>
|
||||
<putLibraryJarsInTempDir>true</putLibraryJarsInTempDir>
|
||||
<injarNotExistsSkip>true</injarNotExistsSkip>
|
||||
<options>
|
||||
<option>-target 17</option>
|
||||
<option>-dontshrink</option>
|
||||
<option>-dontnote</option>
|
||||
<option>-dontwarn</option>
|
||||
<option>-keepparameternames</option>
|
||||
<option>-renamesourcefileattribute SourceFile</option>
|
||||
<option>-keepattributes Signature,Exceptions,*Annotation*,
|
||||
InnerClasses,PermittedSubclasses,EnclosingMethod,
|
||||
Deprecated,SourceFile,LineNumberTable
|
||||
</option>
|
||||
|
||||
<option>-keep public class * {
|
||||
public protected *;
|
||||
}
|
||||
</option>
|
||||
<option>-keepclasseswithmembernames,includedescriptorclasses class * {
|
||||
native <![CDATA[<methods>]]>;
|
||||
}
|
||||
</option>
|
||||
<option>-keepclassmembers,allowoptimization enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
</option>
|
||||
<option>-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
private static final java.io.ObjectStreamField[] serialPersistentFields;
|
||||
private void writeObject(java.io.ObjectOutputStream);
|
||||
private void readObject(java.io.ObjectInputStream);
|
||||
java.lang.Object writeReplace();
|
||||
java.lang.Object readResolve();
|
||||
}
|
||||
</option>
|
||||
</options>
|
||||
<libs>
|
||||
<lib>${java.home}/jmods/java.base.jmod</lib>
|
||||
</libs>
|
||||
</configuration>
|
||||
</plugin-->
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
Loading…
Reference in New Issue