토큰 방식 개발 중...

dev_token
김수봉 2 years ago
parent e5a881e15f
commit 1bb45ee9b2

@ -119,6 +119,11 @@ dependencies {
implementation files("lib/ASRLIB-2.4.0.2.jar") implementation files("lib/ASRLIB-2.4.0.2.jar")
implementation files("lib/pttsnet_class.jar") implementation files("lib/pttsnet_class.jar")
// jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
} }
tasks.named('test') { tasks.named('test') {

@ -5,6 +5,7 @@ import com.icomsys.main_vm.biz.advice.excep.CustomBadRequestException;
import com.icomsys.main_vm.biz.advice.excep.CustomNoSuchFieldException; import com.icomsys.main_vm.biz.advice.excep.CustomNoSuchFieldException;
import com.icomsys.main_vm.biz.advice.excep.CustomNotFoundException; import com.icomsys.main_vm.biz.advice.excep.CustomNotFoundException;
import com.icomsys.main_vm.biz.common.common.service.FileService; import com.icomsys.main_vm.biz.common.common.service.FileService;
import com.icomsys.main_vm.biz.common.login.CinnamonToken;
import com.icomsys.main_vm.biz.common.login.req.LoginReq; import com.icomsys.main_vm.biz.common.login.req.LoginReq;
import com.icomsys.main_vm.biz.common.login.req.MainOprReq; import com.icomsys.main_vm.biz.common.login.req.MainOprReq;
import com.icomsys.main_vm.biz.common.login.req.PwdUpdateReq; import com.icomsys.main_vm.biz.common.login.req.PwdUpdateReq;
@ -68,6 +69,15 @@ public class LoginController {
return loginService.LoginValidService(loginReq, model); return loginService.LoginValidService(loginReq, model);
} }
@PostMapping("/adm/tokenLogin")
@ResponseBody
public CinnamonToken tokenLogin(@RequestBody LoginCheckReq dto) {
String id = dto.getUserId();
String pwd = dto.getPassword();
return loginService.tokenLogin(dto);
}
@RequestMapping(value = "/adm/main/actionMain.do") @RequestMapping(value = "/adm/main/actionMain.do")
public String actionMain(ModelMap model) { public String actionMain(ModelMap model) {
return loginService.actionMain(model); return loginService.actionMain(model);

@ -45,8 +45,7 @@ public class CustomUserDetailsService implements UserDetailsService {
List<SimpleGrantedAuthority> permission = authList.stream() List<SimpleGrantedAuthority> permission = authList.stream()
.map(SimpleGrantedAuthority::new) .map(SimpleGrantedAuthority::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
return new User(String.valueOf(dto.getUserId()), dto.getPassword(), permission) return new User(String.valueOf(dto.getUserId()), dto.getPassword(), permission);
;
} }

@ -5,6 +5,8 @@ import com.icomsys.main_vm.biz.advice.excep.CustomBadRequestException;
import com.icomsys.main_vm.biz.advice.excep.CustomNotFoundException; import com.icomsys.main_vm.biz.advice.excep.CustomNotFoundException;
import com.icomsys.main_vm.biz.common.common.service.LogService; import com.icomsys.main_vm.biz.common.common.service.LogService;
import com.icomsys.main_vm.biz.common.common.service.LogVO; import com.icomsys.main_vm.biz.common.common.service.LogVO;
import com.icomsys.main_vm.biz.common.login.CinnamonToken;
import com.icomsys.main_vm.biz.common.login.TokenProvider;
import com.icomsys.main_vm.biz.common.login.req.LoginReq; import com.icomsys.main_vm.biz.common.login.req.LoginReq;
import com.icomsys.main_vm.biz.common.login.req.MainOprReq; import com.icomsys.main_vm.biz.common.login.req.MainOprReq;
import com.icomsys.main_vm.biz.common.login.req.PwdUpdateReq; import com.icomsys.main_vm.biz.common.login.req.PwdUpdateReq;
@ -29,6 +31,7 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
@ -54,6 +57,8 @@ import java.util.stream.Collectors;
*/ */
public class LoginService { public class LoginService {
private final TokenProvider tokenProvider;
private final AuthenticationManagerBuilder authenticationManagerBuilder; private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final AuthenticationManager authenticationManager; private final AuthenticationManager authenticationManager;
private final PasswordEncoder passwordEncoder; private final PasswordEncoder passwordEncoder;
@ -113,6 +118,26 @@ public class LoginService {
} }
@Transactional
public CinnamonToken tokenLogin(LoginCheckReq dto){
// 1. Login ID/PW 를 기반으로 Authentication 객체 생성
// 이때 authentication 는 인증 여부를 확인하는 authenticated 값이 false
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(dto.getUserId(), dto.getPassword());
// 2. 실제 검증 (사용자 비밀번호 체크)이 이루어지는 부분
// authenticate 매서드가 실행될 때 CustomUserDetailsService 에서 만든 loadUserByUsername 메서드가 실행
try {
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
// 3. 인증 정보를 기반으로 JWT 토큰 생성
CinnamonToken tokenInfo = tokenProvider.generateToken(authentication);
return tokenInfo;
} catch ( AuthenticationException e) {
log.info(e.getMessage());
throw e;
}
}
public String actionMain(ModelMap model) { public String actionMain(ModelMap model) {

@ -4,12 +4,16 @@ import com.fasterxml.jackson.databind.ObjectMapper;
//import com.icomsys.main_vm.db.jpa.repo.bot.TbBotAuthMenuRepo; //import com.icomsys.main_vm.db.jpa.repo.bot.TbBotAuthMenuRepo;
//import com.icomsys.main_vm.db.jpa.repo.bot.TbBotMenuRepo; //import com.icomsys.main_vm.db.jpa.repo.bot.TbBotMenuRepo;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.icomsys.main_vm.biz.common.login.TokenProvider;
import com.icomsys.main_vm.common.code.enumresource.SessionResource; import com.icomsys.main_vm.common.code.enumresource.SessionResource;
import com.icomsys.main_vm.db.mybatis.alias.LoginVO; import com.icomsys.main_vm.db.mybatis.alias.LoginVO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper; import org.springframework.web.util.ContentCachingResponseWrapper;
@ -27,6 +31,8 @@ import java.time.LocalDateTime;
public class LoginFilter extends OncePerRequestFilter { public class LoginFilter extends OncePerRequestFilter {
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
private final TokenProvider tokenProvider;
// private final TbBotAuthMenuRepo tbBotAuthMenuRepo; // private final TbBotAuthMenuRepo tbBotAuthMenuRepo;
// private final TbBotMenuRepo tbBotMenuRepo; // private final TbBotMenuRepo tbBotMenuRepo;
// @Value("${Server.servlet.context-path}") // @Value("${Server.servlet.context-path}")
@ -43,21 +49,12 @@ public class LoginFilter extends OncePerRequestFilter {
// log.info("필터 요청유알엘 - {}, {}", reqUrl); // log.info("필터 요청유알엘 - {}, {}", reqUrl);
if (reqUrl.startsWith("/re1")){
response.sendError(490);
return;
}
if (reqUrl.startsWith("/re2")){
response.sendError(491);
return;
}
if (reqUrl.startsWith("/lib") if (reqUrl.startsWith("/lib")
|| reqUrl.startsWith("/css") || reqUrl.startsWith("/css")
|| reqUrl.startsWith("/images") || reqUrl.startsWith("/images")
|| reqUrl.startsWith("/js") || reqUrl.startsWith("/js")
|| reqUrl.startsWith("/adm") || reqUrl.startsWith("/adm/")
|| reqUrl.startsWith("/ws") || reqUrl.startsWith("/ws")
|| reqUrl.startsWith("/rest") || reqUrl.startsWith("/rest")
|| reqUrl.startsWith("/create") || reqUrl.startsWith("/create")
@ -66,9 +63,28 @@ public class LoginFilter extends OncePerRequestFilter {
|| reqUrl.startsWith("/error") || reqUrl.startsWith("/error")
|| reqUrl.startsWith("/files") || reqUrl.startsWith("/files")
|| reqUrl.equals("/") || reqUrl.equals("/")
// || reqUrl.equals("/tokenLogin")
) { ) {
filterChain.doFilter(request, response); filterChain.doFilter(request, response);
} else { } else {
// 1. Request Header 에서 JWT 토큰 추출
String token = resolveToken((HttpServletRequest) request);
// 2. validateToken 으로 토큰 유효성 검사
if (token != null && tokenProvider.validateToken(token)) {
// Todo: 토큰 유효성 검사 후 에러 처리
// 토큰이 유효할 경우 토큰에서 Authentication 객체를 가지고 와서 SecurityContext 에 저장
Authentication authentication = tokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
response.sendError(403);
}
filterChain.doFilter(request, response);
}
/*
if (request.getSession().getAttribute(SessionResource.UserVO.getName()) == null || request.getSession().getAttribute(SessionResource.UserVO.getName()).equals("")) { if (request.getSession().getAttribute(SessionResource.UserVO.getName()) == null || request.getSession().getAttribute(SessionResource.UserVO.getName()).equals("")) {
log.info("session Check"); log.info("session Check");
response.sendError(490); response.sendError(490);
@ -104,6 +120,17 @@ public class LoginFilter extends OncePerRequestFilter {
} }
} }
// response.copyBodyToResponse(); // response.copyBodyToResponse();
*/
}
// Request Header 에서 토큰 정보 추출
private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer")) {
return bearerToken.substring(7);
}
return null;
} }
} }

@ -29,6 +29,8 @@ spring:
dialect: com.icomsys.main_vm.common.util.CustomDialect dialect: com.icomsys.main_vm.common.util.CustomDialect
generate_statistics: true generate_statistics: true
jwt:
secret: f2d7e5002d67c8d118ebf800274b6a5c83ed7b3d3518b2cddcd7226f7484eb34
#https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/dialect/package-summary.html #https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/dialect/package-summary.html
feign: feign:

@ -17,6 +17,8 @@
}); });
$(document).ready(function () { $(document).ready(function () {
let tmp = window.localStorage.getItem("cinnmonToken");
console.log(tmp);
$('.btn_wrap').on("click", function () { $('.btn_wrap').on("click", function () {
// fncSend(); // fncSend();
fncCheck(); fncCheck();
@ -87,24 +89,46 @@
contentType: "application/json; charset=utf-8", contentType: "application/json; charset=utf-8",
datatype: "JSON", datatype: "JSON",
async: false, async: false,
url: "<c:url value='/adm/main/check'/>", url: "<c:url value='/adm/tokenLogin'/>",
data: JSON.stringify(json), data: JSON.stringify(json),
}) })
.complete(function (data) { .complete(function (data) {
console.log(data);
if (data.status == 200) { if (data.status == 200) {
window.localStorage.setItem("cinnmonToken", data.responseJSON.accessToken);
console.log(data.responseJSON);
let tmp = window.localStorage.getItem("cinnmonToken");
console.log(tmp);
document.signinInfoForm.action = "<c:url value='/adm/main/actionSecurityLogin.do'/>"; document.signinInfoForm.action = "<c:url value='/adm/main/actionSecurityLogin.do'/>";
document.signinInfoForm.submit(); document.signinInfoForm.submit();
} else if (data.status == 400) {
// alert("비밀번호 5회 실패로 계정이 잠겼습니다. 관리자에게 잠금해제 요청하세요."); } else {
$.utils.warning("계정이 잠겼습니다. 관리자에게 잠금해제 요청하세요."); // login 실패
} else if (data.status == 401) { // Todo: 실패에 코드 정의 및 처리 방식 고려 필요
// alert("비밀번호 변경후 90일이 지났습니다."); console.log("data.status: " + data.status);
$.utils.warning("비밀번호 변경후 90일이 지났습니다."); $.utils.warning("로그인 실패!! 에러 코드 처리 필요");
document.location.href = "<c:url value='/adm/main/changePwd'/>" ;
} else if (data.status == 404) {
// alert("로그인 정보가 올바르지 않습니다.");
$.utils.warning("로그인 정보가 올바르지 않습니다.");
} }
<%--if (data.status == 200) {--%>
<%-- document.signinInfoForm.action = "<c:url value='/adm/main/actionSecurityLogin.do'/>";--%>
<%-- document.signinInfoForm.submit();--%>
<%--} else if (data.status == 400) {--%>
<%-- // alert("비밀번호 5회 실패로 계정이 잠겼습니다. 관리자에게 잠금해제 요청하세요.");--%>
<%-- $.utils.warning("계정이 잠겼습니다. 관리자에게 잠금해제 요청하세요.");--%>
<%--} else if (data.status == 401) {--%>
<%-- // alert("비밀번호 변경후 90일이 지났습니다.");--%>
<%-- $.utils.warning("비밀번호 변경후 90일이 지났습니다.");--%>
<%-- document.location.href = "<c:url value='/adm/main/changePwd'/>" ;--%>
<%--} else if (data.status == 404) {--%>
<%-- // alert("로그인 정보가 올바르지 않습니다.");--%>
<%-- $.utils.warning("로그인 정보가 올바르지 않습니다.");--%>
<%--}--%>
}) })
} }

Loading…
Cancel
Save