SSO 인증처리 및 구글 2단계 인증처리 기능확대
This commit is contained in:
parent
224ed4bd63
commit
4953c90feb
@ -105,7 +105,14 @@ dependencies
|
|||||||
implementation 'org.apache.poi:poi-ooxml:4.1.2'
|
implementation 'org.apache.poi:poi-ooxml:4.1.2'
|
||||||
implementation 'org.apache.poi:poi-scratchpad:4.1.2'
|
implementation 'org.apache.poi:poi-scratchpad:4.1.2'
|
||||||
implementation 'org.apache.poi:poi-examples:4.1.2'
|
implementation 'org.apache.poi:poi-examples:4.1.2'
|
||||||
|
|
||||||
|
// 2026.04.02 나혁제 구글 OTP 기능 추가
|
||||||
|
implementation 'com.warrenstrange:googleauth:1.5.0'
|
||||||
|
|
||||||
|
// 2026.04.02 나혁제 구글 OTP 기능 추가
|
||||||
|
implementation 'com.google.zxing:core:3.5.1'
|
||||||
|
implementation 'com.google.zxing:javase:3.5.1'
|
||||||
|
implementation 'de.taimos:totp:1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
test
|
test
|
||||||
|
|||||||
@ -0,0 +1,92 @@
|
|||||||
|
package com.urpsys.basefront.common.service;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base32;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import com.google.zxing.BarcodeFormat;
|
||||||
|
import com.google.zxing.client.j2se.MatrixToImageWriter;
|
||||||
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
|
import com.warrenstrange.googleauth.GoogleAuthenticator;
|
||||||
|
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
|
||||||
|
|
||||||
|
import de.taimos.totp.TOTP;
|
||||||
|
|
||||||
|
public class GoogleOtpService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 비밀키 생성.
|
||||||
|
*
|
||||||
|
* @return 32자리의 비밀키
|
||||||
|
*/
|
||||||
|
public static String generateSecretKey()
|
||||||
|
{
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
byte[] bytes = new byte[20];
|
||||||
|
random.nextBytes(bytes);
|
||||||
|
Base32 base32 = new Base32();
|
||||||
|
return base32.encodeToString(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QR코드 URL 생성.
|
||||||
|
*
|
||||||
|
* @param displayName 표시할 이름
|
||||||
|
* @param secret 비밀키
|
||||||
|
* @return QR코드 URL
|
||||||
|
*/
|
||||||
|
public static String getQrCodeUrl(String displayName, String secret) throws Exception
|
||||||
|
{
|
||||||
|
String format = "otpauth://totp/" + URLEncoder.encode(displayName, StandardCharsets.UTF_8)
|
||||||
|
.replace("+", "%20")
|
||||||
|
+ "?secret=" + secret;
|
||||||
|
return generateQRCodeImage(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QR코드 이미지 생성.
|
||||||
|
*
|
||||||
|
* @param barcodeText 바코드 텍스트
|
||||||
|
* @return QR코드 이미지
|
||||||
|
*/
|
||||||
|
public static String generateQRCodeImage(String barcodeText) throws Exception
|
||||||
|
{
|
||||||
|
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
||||||
|
BitMatrix bitMatrix = qrCodeWriter.encode(barcodeText, BarcodeFormat.QR_CODE, 200, 200);
|
||||||
|
|
||||||
|
ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
MatrixToImageWriter.writeToStream(bitMatrix, "PNG", pngOutputStream);
|
||||||
|
|
||||||
|
return Base64.getEncoder().encodeToString(pngOutputStream.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OTP 체크.
|
||||||
|
*
|
||||||
|
* @param secretKey 비밀키 (32자리)
|
||||||
|
* @param otp OTP(6자리)
|
||||||
|
* @return true: 일치, false: 불일치
|
||||||
|
*/
|
||||||
|
public static boolean checkOtp(String secretKey, String otp)
|
||||||
|
{
|
||||||
|
return otp.equals(getOtpCode(secretKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getOtpCode(String secretKey)
|
||||||
|
{
|
||||||
|
Base32 base32 = new Base32();
|
||||||
|
byte[] bytes = base32.decode(secretKey);
|
||||||
|
String hexKey = Hex.encodeHexString(bytes);
|
||||||
|
return TOTP.getOTP(hexKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -59,8 +59,9 @@ public class LoginService implements UserDetailsService
|
|||||||
|
|
||||||
log.info("srLoing 0 [{}]", srLoing[0]);
|
log.info("srLoing 0 [{}]", srLoing[0]);
|
||||||
log.info("srLoing 1 [{}]", srLoing[1]);
|
log.info("srLoing 1 [{}]", srLoing[1]);
|
||||||
|
log.info("srLoing 2 [{}]", srLoing[2]); // sso 처리여부 추가
|
||||||
|
|
||||||
if(srLoing.length != 2)
|
if(srLoing.length != 3)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -71,11 +72,12 @@ public class LoginService implements UserDetailsService
|
|||||||
String strAuthClientSecret = "secretKey";
|
String strAuthClientSecret = "secretKey";
|
||||||
|
|
||||||
HttpResponse<String> resAuth = Unirest.post(strAuthServerUrl)
|
HttpResponse<String> resAuth = Unirest.post(strAuthServerUrl)
|
||||||
.basicAuth(strAuthClientId , strAuthClientSecret)
|
.basicAuth(strAuthClientId , strAuthClientSecret)
|
||||||
.queryString("grant_type" , "password")
|
.queryString("grant_type" , "password")
|
||||||
.queryString("username" , srLoing[0])
|
.queryString("username" , srLoing[0])
|
||||||
.queryString("password" , srLoing[1])
|
.queryString("password" , srLoing[1])
|
||||||
.asString();
|
.queryString("ssoYn" , srLoing[2])
|
||||||
|
.asString();
|
||||||
|
|
||||||
String returnAuth = resAuth.getBody();
|
String returnAuth = resAuth.getBody();
|
||||||
|
|
||||||
|
|||||||
@ -447,7 +447,7 @@ public class CommonUtil
|
|||||||
/**
|
/**
|
||||||
Map 데이터를 JSONObject로 변환.
|
Map 데이터를 JSONObject로 변환.
|
||||||
@version 1.0
|
@version 1.0
|
||||||
@author Yoon Su-wan
|
@author 나혁제
|
||||||
@since JDK1.0
|
@since JDK1.0
|
||||||
@param v_msg Map
|
@param v_msg Map
|
||||||
@return JSONObject
|
@return JSONObject
|
||||||
|
|||||||
@ -68,8 +68,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
|
|||||||
.antMatchers("/egov/images/**" ).permitAll()
|
.antMatchers("/egov/images/**" ).permitAll()
|
||||||
.antMatchers("/EgovModal.do" ).permitAll()
|
.antMatchers("/EgovModal.do" ).permitAll()
|
||||||
.antMatchers("/main/noAuth*.do" ).permitAll()
|
.antMatchers("/main/noAuth*.do" ).permitAll()
|
||||||
.antMatchers("//validator*" ).permitAll()
|
.antMatchers("/validator*" ).permitAll()
|
||||||
|
.antMatchers("/main/ssoDirectlogin.do" ).permitAll() // 2026.04.02 나혁제 SSO 로그인처리
|
||||||
|
|
||||||
|
// .antMatchers("//validator*" ).permitAll()
|
||||||
// .antMatchers("/main/searchIdFind.do" ).permitAll()
|
// .antMatchers("/main/searchIdFind.do" ).permitAll()
|
||||||
// .antMatchers("/main/UserPasswordResetExt.do" ).permitAll()
|
// .antMatchers("/main/UserPasswordResetExt.do" ).permitAll()
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,10 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
|||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
import com.urpsys.basefront.interceptor.GoogleOtpCheckFrontInterceptor;
|
||||||
|
import com.urpsys.basefront.interceptor.ItsmMenuAuthCheckFrontInterceptor;
|
||||||
|
import com.urpsys.basefront.interceptor.UrpPortalFrontInterceptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 기본 웹서버 설정 클리스
|
* 기본 웹서버 설정 클리스
|
||||||
*
|
*
|
||||||
@ -37,6 +41,9 @@ public class WebConfig implements WebMvcConfigurer
|
|||||||
@Autowired
|
@Autowired
|
||||||
ItsmMenuAuthCheckFrontInterceptor itsmMenuAuthCheckFrontInterceptor;
|
ItsmMenuAuthCheckFrontInterceptor itsmMenuAuthCheckFrontInterceptor;
|
||||||
|
|
||||||
|
// 2026.04.03 나혁제 구글 OTP 2단계 처리 interceptor
|
||||||
|
@Autowired
|
||||||
|
GoogleOtpCheckFrontInterceptor googleOtpCheckFrontInterceptor;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@Value("${custom.path.phy_sitemap}")
|
@Value("${custom.path.phy_sitemap}")
|
||||||
@ -52,6 +59,8 @@ public class WebConfig implements WebMvcConfigurer
|
|||||||
@Value("${custom.path.loc_svy}")
|
@Value("${custom.path.loc_svy}")
|
||||||
private String resourcesUriPathSvy; // 파일 URL 주소
|
private String resourcesUriPathSvy; // 파일 URL 주소
|
||||||
|
|
||||||
|
@Value("${custom.GoogleOtpUseYn}")
|
||||||
|
private String strGoogleOtpUseYn; // 2026.04.03 나혁제 OTP 사용여부
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addResourceHandlers(ResourceHandlerRegistry registry)
|
public void addResourceHandlers(ResourceHandlerRegistry registry)
|
||||||
@ -73,6 +82,18 @@ public class WebConfig implements WebMvcConfigurer
|
|||||||
public void addInterceptors(InterceptorRegistry registry)
|
public void addInterceptors(InterceptorRegistry registry)
|
||||||
{
|
{
|
||||||
registry.addInterceptor(urpPortalFrontInterceptor).addPathPatterns("/**/*.do");
|
registry.addInterceptor(urpPortalFrontInterceptor).addPathPatterns("/**/*.do");
|
||||||
|
|
||||||
|
// 2026.04.03 나혁제 OTP 사용여부
|
||||||
|
if(strGoogleOtpUseYn.equals("Y"))
|
||||||
|
{
|
||||||
|
registry.addInterceptor(googleOtpCheckFrontInterceptor).addPathPatterns("/main/*.do");
|
||||||
|
registry.addInterceptor(googleOtpCheckFrontInterceptor).addPathPatterns("/srm/*.do");
|
||||||
|
registry.addInterceptor(googleOtpCheckFrontInterceptor).addPathPatterns("/bbs/*.do");
|
||||||
|
registry.addInterceptor(googleOtpCheckFrontInterceptor).addPathPatterns("/rem/*.do");
|
||||||
|
registry.addInterceptor(googleOtpCheckFrontInterceptor).addPathPatterns("/sys/*.do");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2026.03.02 나혁제 url 보안영부
|
||||||
registry.addInterceptor(itsmMenuAuthCheckFrontInterceptor).addPathPatterns("/srm/*.do");
|
registry.addInterceptor(itsmMenuAuthCheckFrontInterceptor).addPathPatterns("/srm/*.do");
|
||||||
registry.addInterceptor(itsmMenuAuthCheckFrontInterceptor).addPathPatterns("/bbs/*.do");
|
registry.addInterceptor(itsmMenuAuthCheckFrontInterceptor).addPathPatterns("/bbs/*.do");
|
||||||
registry.addInterceptor(itsmMenuAuthCheckFrontInterceptor).addPathPatterns("/rem/*.do");
|
registry.addInterceptor(itsmMenuAuthCheckFrontInterceptor).addPathPatterns("/rem/*.do");
|
||||||
|
|||||||
@ -6,9 +6,11 @@ import javax.servlet.ServletException;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.urpsys.basefront.common.exception.CustomException;
|
import com.urpsys.basefront.common.exception.CustomException;
|
||||||
import com.urpsys.basefront.common.util.CommonUtil;
|
import com.urpsys.basefront.common.util.CommonUtil;
|
||||||
@ -42,6 +43,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@Component
|
||||||
public class CustomSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler
|
public class CustomSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler
|
||||||
{
|
{
|
||||||
@Resource(name="RestApiCallUtil")
|
@Resource(name="RestApiCallUtil")
|
||||||
|
|||||||
@ -54,7 +54,8 @@ public class CustomAuthenticationProvider implements AuthenticationProvider
|
|||||||
String username = (String) authentication.getPrincipal();
|
String username = (String) authentication.getPrincipal();
|
||||||
String password = (String) authentication.getCredentials();
|
String password = (String) authentication.getCredentials();
|
||||||
|
|
||||||
String strLoginInfo = username+","+password;
|
// 2026.04.02 나혁제 SSO 처리여부 추가
|
||||||
|
String strLoginInfo = username+","+password+","+"N";
|
||||||
|
|
||||||
UserDetails info = loginService.loadUserByUsername(strLoginInfo); // 사용자 정보 추출
|
UserDetails info = loginService.loadUserByUsername(strLoginInfo); // 사용자 정보 추출
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,175 @@
|
|||||||
|
package com.urpsys.basefront.controller;
|
||||||
|
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base32;
|
||||||
|
import org.egovframe.rte.fdl.property.EgovPropertyService;
|
||||||
|
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import com.google.gson.FieldNamingPolicy;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.urpsys.basefront.common.egov.util.EgovStringUtil;
|
||||||
|
import com.urpsys.basefront.common.service.CommonService;
|
||||||
|
import com.urpsys.basefront.common.service.GoogleOtpService;
|
||||||
|
import com.urpsys.basefront.common.service.LoginService;
|
||||||
|
import com.urpsys.basefront.common.util.CommonUtil;
|
||||||
|
import com.urpsys.basefront.common.util.ConvertUtils;
|
||||||
|
import com.urpsys.basefront.common.util.RestApiCallUtil;
|
||||||
|
import com.urpsys.basefront.config.handler.CustomSuccessHandler;
|
||||||
|
import com.urpsys.basefront.domain.MemberVO;
|
||||||
|
import com.urpsys.basefront.domain.TokenInfo;
|
||||||
|
import com.urpsys.itmsfront.cmm.domain.ComDefaultCodeVO;
|
||||||
|
import com.urpsys.itmsfront.sys.domain.PrsnlPortletCreateVO;
|
||||||
|
import com.urpsys.itmsfront.sys.domain.PrsnlPortletManageVO;
|
||||||
|
import com.urpsys.itmsfront.sys.domain.UserDefaultVO;
|
||||||
|
import com.urpsys.itmsfront.sys.domain.UserManageVO;
|
||||||
|
|
||||||
|
import kong.unirest.HttpResponse;
|
||||||
|
import kong.unirest.JsonNode;
|
||||||
|
import kong.unirest.Unirest;
|
||||||
|
import kong.unirest.json.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSO 처리 Controller
|
||||||
|
* @author urp 인프라본부 나혁제
|
||||||
|
* @since 2026.04.02
|
||||||
|
* @version 1.0
|
||||||
|
* @see
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* << 개정이력(Modification Information) >>
|
||||||
|
*
|
||||||
|
* 수정일 수정자 수정내용
|
||||||
|
* ---------- -------- ---------------------------
|
||||||
|
* 2026.04.02 나혁제 최초 생성
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Controller
|
||||||
|
public class GoogleOtpController
|
||||||
|
{
|
||||||
|
@Resource(name="RestApiCallUtil")
|
||||||
|
private RestApiCallUtil restApiCallUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* otp key 발급처리
|
||||||
|
* @author urp 인프라본부 나혁제
|
||||||
|
* 작성일 : 2026.04.03
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/otp/OrRegist.do")
|
||||||
|
public String OrRegist ( HttpServletRequest request
|
||||||
|
, HttpServletResponse response
|
||||||
|
, Model model) throws Exception
|
||||||
|
{
|
||||||
|
log.info(">>>>>>>>>>>>>>> /otpOrRegist.do <<<<<<<<<<<<<<<");
|
||||||
|
|
||||||
|
Map<String, Object> bodyMap = new LinkedHashMap();
|
||||||
|
Map<String, Object> returnMap = new LinkedHashMap();
|
||||||
|
|
||||||
|
String secretKey = GoogleOtpService.generateSecretKey();
|
||||||
|
|
||||||
|
log.info("secretKey [{}] ", secretKey);
|
||||||
|
|
||||||
|
TokenInfo tokenInfo = CommonUtil.getTokenInfo();
|
||||||
|
|
||||||
|
// Body Setting Start ---------------------------------
|
||||||
|
bodyMap.put("uniqId", tokenInfo.getUniqId() );
|
||||||
|
bodyMap.put("otpKey", secretKey );
|
||||||
|
// Body Setting End ---------------------------------
|
||||||
|
|
||||||
|
// RestApi Call Start ---------------------------------
|
||||||
|
returnMap = restApiCallUtil.RestApiCall(bodyMap, "/sys/updateOtpKey.do");
|
||||||
|
// RestApi Call End ---------------------------------
|
||||||
|
|
||||||
|
model.addAttribute("key", secretKey);
|
||||||
|
model.addAttribute("qr", GoogleOtpService.getQrCodeUrl("urITSM", secretKey));
|
||||||
|
|
||||||
|
log.info("<<<<<<<<<<<<<<< /otpOrRegist.do >>>>>>>>>>>>>>>");
|
||||||
|
|
||||||
|
return "/main/Login_otp_create";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* otp 인증화면으로 이동처리
|
||||||
|
* @author urp 인프라본부 나혁제
|
||||||
|
* 작성일 : 2026.04.03
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/otp/checkView.do")
|
||||||
|
public String checkView ( HttpServletRequest request
|
||||||
|
, HttpServletResponse response
|
||||||
|
, Model model) throws Exception
|
||||||
|
{
|
||||||
|
log.info(">>>>>>>>>>>>>>> /otp/checkView.do <<<<<<<<<<<<<<<");
|
||||||
|
|
||||||
|
Map<String, Object> bodyMap = new LinkedHashMap();
|
||||||
|
Map<String, Object> returnMap = new LinkedHashMap();
|
||||||
|
|
||||||
|
log.info("<<<<<<<<<<<<<<< /otp/checkView.do >>>>>>>>>>>>>>>");
|
||||||
|
|
||||||
|
return "/main/Login_otp_check";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/otp/checkOtp.do")
|
||||||
|
public String check( HttpServletRequest request
|
||||||
|
, HttpServletResponse response
|
||||||
|
, Model model)
|
||||||
|
{
|
||||||
|
String strOtpSecretKey = CommonUtil.nvl(request.getSession().getAttribute("otpSecretKey")); // 인증키
|
||||||
|
String strUserOtp = CommonUtil.nvl(request.getParameter("userOtp")); // otp
|
||||||
|
|
||||||
|
boolean strOtpCheckYn = GoogleOtpService.checkOtp(strOtpSecretKey, strUserOtp);
|
||||||
|
|
||||||
|
// 세션에 인증성공 처리
|
||||||
|
if(strOtpCheckYn)
|
||||||
|
{
|
||||||
|
request.getSession().setAttribute("otpCheckYn", "Y");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "forward:/main/mainPage.do";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -15,7 +15,12 @@ import org.egovframe.rte.fdl.property.EgovPropertyService;
|
|||||||
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
|
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
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.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
@ -31,9 +36,11 @@ import com.google.gson.Gson;
|
|||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.urpsys.basefront.common.egov.util.EgovStringUtil;
|
import com.urpsys.basefront.common.egov.util.EgovStringUtil;
|
||||||
import com.urpsys.basefront.common.service.CommonService;
|
import com.urpsys.basefront.common.service.CommonService;
|
||||||
|
import com.urpsys.basefront.common.service.LoginService;
|
||||||
import com.urpsys.basefront.common.util.CommonUtil;
|
import com.urpsys.basefront.common.util.CommonUtil;
|
||||||
import com.urpsys.basefront.common.util.ConvertUtils;
|
import com.urpsys.basefront.common.util.ConvertUtils;
|
||||||
import com.urpsys.basefront.common.util.RestApiCallUtil;
|
import com.urpsys.basefront.common.util.RestApiCallUtil;
|
||||||
|
import com.urpsys.basefront.config.handler.CustomSuccessHandler;
|
||||||
import com.urpsys.basefront.domain.MemberVO;
|
import com.urpsys.basefront.domain.MemberVO;
|
||||||
import com.urpsys.basefront.domain.TokenInfo;
|
import com.urpsys.basefront.domain.TokenInfo;
|
||||||
import com.urpsys.itmsfront.cmm.domain.ComDefaultCodeVO;
|
import com.urpsys.itmsfront.cmm.domain.ComDefaultCodeVO;
|
||||||
@ -86,6 +93,12 @@ public class MainController
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CommonService commonService;
|
private CommonService commonService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LoginService loginService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CustomSuccessHandler customSuccessHandler;
|
||||||
|
|
||||||
// @Autowired
|
// @Autowired
|
||||||
// HtmlEmailUtil htmlEmailUtil;
|
// HtmlEmailUtil htmlEmailUtil;
|
||||||
|
|
||||||
@ -150,6 +163,10 @@ public class MainController
|
|||||||
{
|
{
|
||||||
strErrorMsg = "사용자 정보는 존재하나 권한정보가 존재하지 않습니다. 시스템 관리자에게 연락해 주세요.";
|
strErrorMsg = "사용자 정보는 존재하나 권한정보가 존재하지 않습니다. 시스템 관리자에게 연락해 주세요.";
|
||||||
}
|
}
|
||||||
|
else if(srError[0].equals("-5"))
|
||||||
|
{
|
||||||
|
strErrorMsg = "SSO 인증처리 실패하였습니다. 시스템 관리자에게 연락해 주세요.";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strErrorMsg = "";
|
strErrorMsg = "";
|
||||||
@ -174,6 +191,8 @@ public class MainController
|
|||||||
{
|
{
|
||||||
// 메인 페이지 이동
|
// 메인 페이지 이동
|
||||||
strReturnJsp = "forward:/main/mainPage.do";
|
strReturnJsp = "forward:/main/mainPage.do";
|
||||||
|
// strReturnJsp = "forward:/otpOrRegist.do";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("<<<<<<<<<<<<<<< /main/actionMain.do >>>>>>>>>>>>>>>");
|
log.info("<<<<<<<<<<<<<<< /main/actionMain.do >>>>>>>>>>>>>>>");
|
||||||
@ -203,11 +222,11 @@ public class MainController
|
|||||||
|
|
||||||
String strAuthUrl = strAuthServer+"/oauth/token";
|
String strAuthUrl = strAuthServer+"/oauth/token";
|
||||||
HttpResponse<String> resAuth = Unirest.post(strAuthUrl)
|
HttpResponse<String> resAuth = Unirest.post(strAuthUrl)
|
||||||
.basicAuth("clientId", "secretKey")
|
.basicAuth("clientId", "secretKey")
|
||||||
.queryString("grant_type", "password")
|
.queryString("grant_type", "password")
|
||||||
.queryString("username", strId)
|
.queryString("username", strId)
|
||||||
.queryString("password", strPassWord)
|
.queryString("password", strPassWord)
|
||||||
.asString();
|
.asString();
|
||||||
|
|
||||||
String returnAuth = resAuth.getBody();
|
String returnAuth = resAuth.getBody();
|
||||||
|
|
||||||
@ -684,11 +703,6 @@ public class MainController
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
169
src/main/java/com/urpsys/basefront/controller/SsoController.java
Normal file
169
src/main/java/com/urpsys/basefront/controller/SsoController.java
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
package com.urpsys.basefront.controller;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.egovframe.rte.fdl.property.EgovPropertyService;
|
||||||
|
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import com.google.gson.FieldNamingPolicy;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.urpsys.basefront.common.egov.util.EgovStringUtil;
|
||||||
|
import com.urpsys.basefront.common.service.CommonService;
|
||||||
|
import com.urpsys.basefront.common.service.LoginService;
|
||||||
|
import com.urpsys.basefront.common.util.CommonUtil;
|
||||||
|
import com.urpsys.basefront.common.util.ConvertUtils;
|
||||||
|
import com.urpsys.basefront.common.util.RestApiCallUtil;
|
||||||
|
import com.urpsys.basefront.config.handler.CustomSuccessHandler;
|
||||||
|
import com.urpsys.basefront.domain.MemberVO;
|
||||||
|
import com.urpsys.basefront.domain.TokenInfo;
|
||||||
|
import com.urpsys.itmsfront.cmm.domain.ComDefaultCodeVO;
|
||||||
|
import com.urpsys.itmsfront.sys.domain.PrsnlPortletCreateVO;
|
||||||
|
import com.urpsys.itmsfront.sys.domain.PrsnlPortletManageVO;
|
||||||
|
import com.urpsys.itmsfront.sys.domain.UserDefaultVO;
|
||||||
|
import com.urpsys.itmsfront.sys.domain.UserManageVO;
|
||||||
|
|
||||||
|
import kong.unirest.HttpResponse;
|
||||||
|
import kong.unirest.JsonNode;
|
||||||
|
import kong.unirest.Unirest;
|
||||||
|
import kong.unirest.json.JSONObject;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSO 처리 Controller
|
||||||
|
* @author urp 인프라본부 나혁제
|
||||||
|
* @since 2026.04.02
|
||||||
|
* @version 1.0
|
||||||
|
* @see
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* << 개정이력(Modification Information) >>
|
||||||
|
*
|
||||||
|
* 수정일 수정자 수정내용
|
||||||
|
* ---------- -------- ---------------------------
|
||||||
|
* 2026.04.02 나혁제 최초 생성
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Controller
|
||||||
|
public class SsoController
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private LoginService loginService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CustomSuccessHandler customSuccessHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSO 연동 로그인 처리
|
||||||
|
* @author urp 인프라본부 나혁제
|
||||||
|
* 작성일 : 2026.04.02
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/main/ssoDirectlogin.do")
|
||||||
|
public String ssoDirectlogin( HttpServletRequest request
|
||||||
|
, HttpServletResponse response
|
||||||
|
, ModelMap model) throws Exception
|
||||||
|
{
|
||||||
|
log.info(">>>>>>>>>>>>>>> /main/ssoDirectlogin.do <<<<<<<<<<<<<<<");
|
||||||
|
|
||||||
|
// --- SSO 연동 Start ---------------------------------
|
||||||
|
// boolean bSsoAuthYn = false;
|
||||||
|
boolean bSsoAuthYn = true;
|
||||||
|
|
||||||
|
// sso 인증처리
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(!bSsoAuthYn)
|
||||||
|
{
|
||||||
|
return "forward:/main/actionMain.do?error=-5:ssoFail";
|
||||||
|
}
|
||||||
|
// --- SSO 연동 End ---------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 인증 Start ----
|
||||||
|
// String username = (String)request.getParameter("userId");
|
||||||
|
// String password = "";
|
||||||
|
|
||||||
|
String username = (String)request.getParameter("userId");
|
||||||
|
String password = "sso";
|
||||||
|
|
||||||
|
log.info("username => {}" , username );
|
||||||
|
log.info("password => {}" , password );
|
||||||
|
|
||||||
|
String strLoginInfo = username+","+password+","+"Y";
|
||||||
|
|
||||||
|
UserDetails info = loginService.loadUserByUsername(strLoginInfo); // 사용자 정보 추출
|
||||||
|
|
||||||
|
MemberVO member = (MemberVO) info;
|
||||||
|
|
||||||
|
if(info == null)
|
||||||
|
{
|
||||||
|
return "forward:/main/actionMain.do?error=-5:ssoFail";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 시스템 토큰 등록
|
||||||
|
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(info, null, info.getAuthorities());
|
||||||
|
|
||||||
|
// 시스템 보안 등록
|
||||||
|
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||||
|
context.setAuthentication(auth);
|
||||||
|
SecurityContextHolder.setContext(context);
|
||||||
|
|
||||||
|
//
|
||||||
|
request.getSession(true).setAttribute("SPRING_SECURITY_CONTEXT", context);
|
||||||
|
|
||||||
|
// 로그인 성공처리
|
||||||
|
customSuccessHandler.onAuthenticationSuccess(request, response, auth);
|
||||||
|
|
||||||
|
log.info("<<<<<<<<<<<<<<< /main/ssoDirectlogin.do >>>>>>>>>>>>>>>");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
package com.urpsys.basefront.interceptor;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import com.urpsys.basefront.common.util.CommonUtil;
|
||||||
|
import com.urpsys.basefront.common.util.RestApiCallUtil;
|
||||||
|
import com.urpsys.basefront.domain.TokenInfo;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller Google OTP Check interceptor 클리스
|
||||||
|
*
|
||||||
|
* @author urp 인프라본부 나혁제
|
||||||
|
* @since 2026.04.03
|
||||||
|
* @version 1.0.0
|
||||||
|
* @see
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* << 개정이력(Modification information) >>
|
||||||
|
*
|
||||||
|
* 수정일 수정자 수정내용
|
||||||
|
* ----------- --------- ------------------------
|
||||||
|
* 2026.04.03 나혁제 최초작성
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class GoogleOtpCheckFrontInterceptor implements HandlerInterceptor
|
||||||
|
{
|
||||||
|
@Resource(name="RestApiCallUtil")
|
||||||
|
private RestApiCallUtil restApiCallUtil;
|
||||||
|
|
||||||
|
// 컨트롤러가 호출되기 전
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
|
||||||
|
{
|
||||||
|
log.info(" >>>>>>>>>> preHandle <<<<<<<<<< ");
|
||||||
|
|
||||||
|
Map<String, Object> bodyMap = new LinkedHashMap();
|
||||||
|
Map<String, Object> returnMap = new LinkedHashMap();
|
||||||
|
|
||||||
|
// 로그아웃인경우 return;
|
||||||
|
if(request.getSession().getAttribute("tokenInfo") == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 인증키 체크
|
||||||
|
String strOtpSecretKey = CommonUtil.nvl(request.getSession().getAttribute("otpSecretKey"));
|
||||||
|
|
||||||
|
// 키가 없는경우 개인키 추출
|
||||||
|
if(strOtpSecretKey.equals(""))
|
||||||
|
{
|
||||||
|
TokenInfo tokenInfo = CommonUtil.getTokenInfo();
|
||||||
|
|
||||||
|
// Body Setting Start ---------------------------------
|
||||||
|
bodyMap.put("uniqId" , tokenInfo.getUniqId());
|
||||||
|
// Body Setting End ---------------------------------
|
||||||
|
|
||||||
|
// RestApi Call Start ---------------------------------
|
||||||
|
returnMap = restApiCallUtil.RestApiCall(bodyMap, "/sys/selectOtpKey.do");
|
||||||
|
// RestApi Call End ---------------------------------
|
||||||
|
|
||||||
|
strOtpSecretKey = CommonUtil.nvl(returnMap.get("strOtpKey"));
|
||||||
|
|
||||||
|
// 키 발급이 안된경우 키 발급처리
|
||||||
|
if(strOtpSecretKey.equals(""))
|
||||||
|
{
|
||||||
|
response.sendRedirect("/otp/OrRegist.do");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 세션 키 등록 처리
|
||||||
|
request.getSession().setAttribute("otpSecretKey", strOtpSecretKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// otp 인증여부 확인
|
||||||
|
String strOtpCheckYn = CommonUtil.nvl(request.getSession().getAttribute("otpCheckYn"));
|
||||||
|
|
||||||
|
if(!strOtpCheckYn.equals("Y"))
|
||||||
|
{
|
||||||
|
// otp 인증 페이지로 이동처리
|
||||||
|
response.sendRedirect("/otp/checkView.do");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log.info(" <<<<<<<<<< preHandle >>>>>>>>>> ");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// controller의 handler가 끝나면 처리됨
|
||||||
|
@Override
|
||||||
|
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
|
||||||
|
ModelAndView modelAndView) throws Exception
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
log.info(" >>>>>>>>>> postHandle <<<<<<<<<< ");
|
||||||
|
log.info(" <<<<<<<<<< postHandle >>>>>>>>>> ");
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 컨트롤러가 처리 완료후
|
||||||
|
@Override
|
||||||
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
log.info(" >>>>>>>>>> afterCompletion <<<<<<<<<< ");
|
||||||
|
log.info(" <<<<<<<<<< afterCompletion >>>>>>>>>> ");
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.urpsys.basefront.config;
|
package com.urpsys.basefront.interceptor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.urpsys.basefront.config;
|
package com.urpsys.basefront.interceptor;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@ -53,7 +53,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Controller
|
@Controller
|
||||||
public class PortletManageController {
|
public class PortletManageController
|
||||||
|
{
|
||||||
|
|
||||||
@Resource(name="RestApiCallUtil")
|
@Resource(name="RestApiCallUtil")
|
||||||
private RestApiCallUtil restApiCallUtil;
|
private RestApiCallUtil restApiCallUtil;
|
||||||
|
|||||||
@ -53,5 +53,7 @@
|
|||||||
client : kintex
|
client : kintex
|
||||||
# 2026.03.12 URL 권한 체크 여부
|
# 2026.03.12 URL 권한 체크 여부
|
||||||
urlAuthCheck : Y
|
urlAuthCheck : Y
|
||||||
|
# 2026.04.02 GoogleOTP 사용여부 체크
|
||||||
|
GoogleOtpUseYn : N
|
||||||
|
|
||||||
|
|
||||||
109
src/main/webapp/WEB-INF/jsp/main/Login_otp_check.jsp
Normal file
109
src/main/webapp/WEB-INF/jsp/main/Login_otp_check.jsp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
|
||||||
|
<%--
|
||||||
|
Class Name : LoginUsr.jsp
|
||||||
|
Description : 로그인화면
|
||||||
|
Modification Information
|
||||||
|
|
||||||
|
수정일 수정자 수정내용
|
||||||
|
------- -------- ---------------------------
|
||||||
|
2025.01.03 나혁제 최초생성
|
||||||
|
|
||||||
|
author : 인프라본부 나혁제
|
||||||
|
since : 2025.01.02
|
||||||
|
--%>
|
||||||
|
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
|
||||||
|
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||||
|
|
||||||
|
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
|
||||||
|
|
||||||
|
<title> UR-ITSM </title>
|
||||||
|
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>urITSM</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<meta name="keywords" content="uWorks Portal">
|
||||||
|
<meta name="description" content="uWorks Portal에 오신것을 환영합니다.">
|
||||||
|
<link rel="stylesheet" type="text/css" href="${ctx}/css/import.css">
|
||||||
|
<script type="text/javascript" src="${ctx}/js/jquery-2.2.4.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${ctx}/js/common_script.js"></script>
|
||||||
|
<link rel="stylesheet" href="${ctx}/js/js-calendar/calendar-jquery-ui.css">
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${ctx}/js/js-calendar/jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="${ctx}/js/js-calendar/jquery-ui.js"></script>
|
||||||
|
<script type="text/javascript" src="${ctx}/js/js-calendar/calendar.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
//----------------------------------------
|
||||||
|
// 화면 초기화
|
||||||
|
// ----------------------------------------
|
||||||
|
$(document).ready(function()
|
||||||
|
{
|
||||||
|
});
|
||||||
|
|
||||||
|
//----------------------------------------
|
||||||
|
// otp 인증 체크
|
||||||
|
// ----------------------------------------
|
||||||
|
function oto_auth_check()
|
||||||
|
{
|
||||||
|
document.otpAuthForm.action="/otp/checkOtp.do";
|
||||||
|
document.otpAuthForm.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div style="display: flex;align-items: flex-start;">
|
||||||
|
|
||||||
|
<!-- login :s -->
|
||||||
|
<div class="logback">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- login :s -->
|
||||||
|
<div class="logback">
|
||||||
|
<h1><img src="${ctx}/images/main/logo.png" alt="uWorks Portal logo"></h1>
|
||||||
|
<h3>urITSM 에 오신것을 환영합니다.</h3>
|
||||||
|
<!-- login_box :s -->
|
||||||
|
<div class="login_box">
|
||||||
|
<!-- loginWrap :s -->
|
||||||
|
<div class="loginWrap">
|
||||||
|
<div class="input_wrap">
|
||||||
|
|
||||||
|
<form:form id="otpAuthForm" name="otpAuthForm" method="post">
|
||||||
|
<br> OTP 을 입력해주세요.
|
||||||
|
<br>
|
||||||
|
<label for="member_id" class="hidden">OTP 입력</label>
|
||||||
|
<input type="text" name="userOtp" id="userOtp" class="txt_id" placeholder="OTP">
|
||||||
|
<button type="button" class="btn_login" onclick="javascript:oto_auth_check()" >인증</button>
|
||||||
|
</form:form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--//loginWrap :e -->
|
||||||
|
</div>
|
||||||
|
<!--//login_box :e -->
|
||||||
|
</div>
|
||||||
|
<!--//login :e -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
106
src/main/webapp/WEB-INF/jsp/main/Login_otp_create.jsp
Normal file
106
src/main/webapp/WEB-INF/jsp/main/Login_otp_create.jsp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
|
||||||
|
<%--
|
||||||
|
Class Name : LoginUsr.jsp
|
||||||
|
Description : 로그인화면
|
||||||
|
Modification Information
|
||||||
|
|
||||||
|
수정일 수정자 수정내용
|
||||||
|
------- -------- ---------------------------
|
||||||
|
2025.01.03 나혁제 최초생성
|
||||||
|
|
||||||
|
author : 인프라본부 나혁제
|
||||||
|
since : 2025.01.02
|
||||||
|
--%>
|
||||||
|
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
|
||||||
|
|
||||||
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||||
|
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||||
|
|
||||||
|
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
|
||||||
|
|
||||||
|
<title> UR-ITSM </title>
|
||||||
|
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||||
|
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>urITSM</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<meta name="keywords" content="uWorks Portal">
|
||||||
|
<meta name="description" content="uWorks Portal에 오신것을 환영합니다.">
|
||||||
|
<link rel="stylesheet" type="text/css" href="${ctx}/css/import.css">
|
||||||
|
<script type="text/javascript" src="${ctx}/js/jquery-2.2.4.min.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${ctx}/js/common_script.js"></script>
|
||||||
|
<link rel="stylesheet" href="${ctx}/js/js-calendar/calendar-jquery-ui.css">
|
||||||
|
|
||||||
|
<script type="text/javascript" src="${ctx}/js/js-calendar/jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="${ctx}/js/js-calendar/jquery-ui.js"></script>
|
||||||
|
<script type="text/javascript" src="${ctx}/js/js-calendar/calendar.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
//----------------------------------------
|
||||||
|
// 화면 초기화
|
||||||
|
// ----------------------------------------
|
||||||
|
$(document).ready(function()
|
||||||
|
{
|
||||||
|
});
|
||||||
|
|
||||||
|
//----------------------------------------
|
||||||
|
// 메인 접속 처리
|
||||||
|
// ----------------------------------------
|
||||||
|
function oto_re_connect()
|
||||||
|
{
|
||||||
|
document.otpAuthForm.action="/main/actionMain.do";
|
||||||
|
document.otpAuthForm.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div style="display: flex;align-items: flex-start;">
|
||||||
|
|
||||||
|
<!-- login :s -->
|
||||||
|
<div class="logback">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- login :s -->
|
||||||
|
<div class="logback">
|
||||||
|
<h1><img src="${ctx}/images/main/logo.png" alt="uWorks Portal logo"></h1>
|
||||||
|
<h3>urITSM 에 오신것을 환영합니다.</h3>
|
||||||
|
<!-- login_box :s -->
|
||||||
|
<div class="login_box">
|
||||||
|
<!-- loginWrap :s -->
|
||||||
|
<div class="loginWrap">
|
||||||
|
<div class="input_wrap">
|
||||||
|
|
||||||
|
<form:form id="otpAuthForm" name="otpAuthForm" method="post">
|
||||||
|
비밀키 <input type="text" name="secretKey" id="secretKey" value="${key}" readonly class="txt_id">
|
||||||
|
<br> 아래 OR 코드을 스캔하여
|
||||||
|
<br> Authenticator 에 등록해 주시길 바랍니다.
|
||||||
|
<img src="data:image/jpeg;base64, ${qr}" alt="QR Code">
|
||||||
|
<button type="button" class="btn_login" onclick="javascript:oto_re_connect()" >접속하기</button>
|
||||||
|
</form:form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--//loginWrap :e -->
|
||||||
|
</div>
|
||||||
|
<!--//login_box :e -->
|
||||||
|
</div>
|
||||||
|
<!--//login :e -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user