CSRF 보안 토큰 적용 처리
This commit is contained in:
parent
a0b69c0289
commit
6f4e189ad9
@ -29,6 +29,7 @@ import nlib.security.SecUserVO;
|
||||
import nlib.user.service.LoginService;
|
||||
import nlib.user.service.NlibLoginVO;
|
||||
import nlib.util.StringUtil;
|
||||
import nlib.util.UUID;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
@ -404,4 +405,39 @@ public class NlibCommonController {
|
||||
return StringUtil.isEmpty(value) ? defValue : value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 세션에 CSRF 방지를 위한 토큰을 생성한다.
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public final static String SESSION_CSRF_TOKEN_NAME = "SESSION_CSRF_TOKEN";
|
||||
|
||||
public String generateCsrfToken(HttpServletRequest request) {
|
||||
HttpSession session = request.getSession();
|
||||
String token = UUID.getNewUUID();
|
||||
session.setAttribute(SESSION_CSRF_TOKEN_NAME, token);
|
||||
log.debug("generateCsrfToken > " + session.getAttribute(SESSION_CSRF_TOKEN_NAME));
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 입력받은 CSRF 토큰이 유효한지 확인한다.
|
||||
*
|
||||
* @param request
|
||||
* @param pToken
|
||||
* @return
|
||||
*/
|
||||
public boolean isValidCsrfToken(HttpServletRequest request, String pToken) {
|
||||
|
||||
HttpSession session = request.getSession();
|
||||
String sToken = (String)session.getAttribute(SESSION_CSRF_TOKEN_NAME);
|
||||
|
||||
if(request == null || StringUtil.isEmpty(pToken) || StringUtil.isEmpty(sToken)) return false;
|
||||
|
||||
if(sToken.equals(pToken)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ public class ReadController extends NlibCommonController {
|
||||
*/
|
||||
@Secured("ROLE_USER")
|
||||
@RequestMapping(value={"/read/confirmReadFromCart.do", "/read/confirmRead.do"})
|
||||
public String confirmRent(HttpServletRequest request, CollectionVO readVO, ModelMap model) throws Exception {
|
||||
public String confirmRent(HttpServletRequest request, CollectionVO readVO, String csrfToken, ModelMap model) throws Exception {
|
||||
|
||||
String retJsp = "nlib/read/confirmRead";
|
||||
boolean fromCart = request.getServletPath().contains("Cart.do");
|
||||
@ -82,11 +82,17 @@ public class ReadController extends NlibCommonController {
|
||||
return retJsp;
|
||||
}
|
||||
|
||||
if(!fromCart && !isValidCsrfToken(request, csrfToken)) {
|
||||
model.addAttribute("message", "잘못된 접근입니다.");
|
||||
return retJsp;
|
||||
}
|
||||
|
||||
if(readVO == null || StringUtil.isEmpty(readVO.getSelItems())) {
|
||||
model.addAttribute("message", "대출(예약)신청할 정보가 없습니다.");
|
||||
return retJsp;
|
||||
}
|
||||
|
||||
|
||||
String selItems = readVO.getSelItems();
|
||||
|
||||
List<CollectionVO> list = collectionService.makeInfoListOfCollectionVO(selItems, mbInfoId);
|
||||
|
||||
@ -218,7 +218,7 @@ public class RentController extends NlibCommonController
|
||||
|
||||
@Secured("ROLE_USER")
|
||||
@RequestMapping(value={"/rent/confirmRentFromCart.do", "/rent/confirmRent.do"})
|
||||
public String confirmRent(HttpServletRequest request, CollectionVO rentVO, ModelMap model) throws Exception {
|
||||
public String confirmRent(HttpServletRequest request, CollectionVO rentVO, ModelMap model, String csrfToken) throws Exception {
|
||||
|
||||
boolean fromCart = request.getServletPath().contains("Cart.do");
|
||||
|
||||
@ -229,6 +229,11 @@ public class RentController extends NlibCommonController
|
||||
return "nlib/rent/confirmRent";
|
||||
}
|
||||
|
||||
if(!fromCart && !isValidCsrfToken(request, csrfToken)) {
|
||||
model.addAttribute("message", "잘못된 접근입니다.");
|
||||
return "nlib/rent/confirmRent";
|
||||
}
|
||||
|
||||
if(rentVO == null || StringUtil.isEmpty(rentVO.getSelItems())) {
|
||||
model.addAttribute("message", "대출(예약)신청할 정보가 없습니다.");
|
||||
return "nlib/rent/confirmRent";
|
||||
|
||||
@ -352,6 +352,12 @@ public class NlibSearchController extends NlibCommonController {
|
||||
imagePath = StringUtil.getString(vo.getRprsThumbUrl(),"");
|
||||
}
|
||||
|
||||
// CSRF 토큰 생성 (2021.12.02 KKN 추가)
|
||||
String token = generateCsrfToken(request);
|
||||
model.addAttribute("csrfToken", token);
|
||||
log.debug("searchItemDetail > token=" + token);
|
||||
log.debug("searchItemDetail > session token=" + session.getAttribute(SESSION_CSRF_TOKEN_NAME));
|
||||
|
||||
model.addAttribute("imageType",imageType);
|
||||
model.addAttribute("imagePath",imagePath);
|
||||
model.addAttribute("keywordList",keywordList);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
<%@page import="nlib.cmm.NlibCommonController"%>
|
||||
<%
|
||||
/**
|
||||
* <pre>
|
||||
@ -35,6 +36,7 @@
|
||||
<c:set var="pageTitle">${result.title}</c:set>
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
|
||||
fn_setPageTitle("${pageTitle}");
|
||||
//로그
|
||||
$.ajax({
|
||||
@ -216,10 +218,10 @@ function goList(){
|
||||
</ul>
|
||||
</div>
|
||||
<div class="b-btn">
|
||||
<c:if test="${result.ableRentAppNow }"><button type="button" class="btn btn-color" title="새 창 열림" onclick="gfn_rentItem('${result.mngOrgCd}', '${result.masterId}')">대출신청</button></c:if>
|
||||
<c:if test="${not result.ableRentAppNow and result.ableRentResNow }"><button type="button" class="btn btn-color" title="새 창 열림" onclick="gfn_rentItem('${result.mngOrgCd}', '${result.masterId}')">대출예약</button></c:if>
|
||||
<c:if test="${result.ableRentAppNow }"><button type="button" class="btn btn-color" title="새 창 열림" onclick="gfn_rentItem('${result.mngOrgCd}', '${result.masterId}', '${csrfToken }')">대출신청</button></c:if>
|
||||
<c:if test="${not result.ableRentAppNow and result.ableRentResNow }"><button type="button" class="btn btn-color" title="새 창 열림" onclick="gfn_rentItem('${result.mngOrgCd}', '${result.masterId}', '${csrfToken }')">대출예약</button></c:if>
|
||||
|
||||
<c:if test="${result.ableReadNow }"><button type="button" class="btn btn-green" title="새 창 열림" onclick="gfn_reserveReadItem('${result.mngOrgCd}', '${result.masterId}')">방문열람신청</button></c:if>
|
||||
<c:if test="${result.ableReadNow }"><button type="button" class="btn btn-green" title="새 창 열림" onclick="gfn_reserveReadItem('${result.mngOrgCd}', '${result.masterId}', '${csrfToken }')">방문열람신청</button></c:if>
|
||||
|
||||
<c:if test="${result.ableRent or result.ableRead }">
|
||||
<button type="button" class="btn btn-orange" onclick="gfn_addRentCart('${result.masterId}', '${result.ableRent}', '${result.ableRead}')">카트담기</button>
|
||||
|
||||
@ -173,7 +173,6 @@ function gfn_showRis(risId){
|
||||
document.getElementById("export-data").className="popup pop-user-set pop-export";
|
||||
|
||||
var html="";
|
||||
html+='<form name="risDownloadForm" id="risDownloadForm" method="post"><input type="hidden" id="risId" name="risId"></form>';
|
||||
html+='<div class="pop-serge">';
|
||||
html+='<div class="row Title">';
|
||||
html+=' <h3>서지정보 내보내기<span>(Export)</span></h3>';
|
||||
@ -216,10 +215,13 @@ function gfn_focus(obj){
|
||||
$("#"+obj).focus();
|
||||
}
|
||||
function gfn_downloadRis(risId){
|
||||
$("#risId").val(risId);
|
||||
|
||||
document.risDownloadForm.action="/ris/downloadRis.do";
|
||||
document.risDownloadForm.submit();
|
||||
if(gfn_isEmpty(risId)) {
|
||||
alert("잘못된 접근입니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
gfn_gotoUrl("/ris/downloadRis.do?risId=" + risId);
|
||||
}
|
||||
|
||||
function gfn_closeRis(risDownloadForm){
|
||||
@ -494,36 +496,29 @@ function gfn_getDetail(masterId, host) {
|
||||
if(gfn_isEmpty(host)) host = "";
|
||||
else host = "https://" + host + ".nculture.org";
|
||||
|
||||
var form = document.createElement("form");
|
||||
form.style.display = "none";
|
||||
$(form).attr("action", host + "/search/searchItemDetail.do");
|
||||
$(form).attr("method", "post");
|
||||
$(form).attr("target", "_blank");
|
||||
var url = host + "/search/searchItemDetail.do?masterId=" + masterId;
|
||||
|
||||
var element = document.createElement("input");
|
||||
$(element).attr("name", "masterId");
|
||||
$(element).attr("value", masterId);
|
||||
|
||||
form.appendChild(element);
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
|
||||
document.body.removeChild(form);
|
||||
gfn_openNewWindow(url);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
function gfn_rentItem(mngOrgCd, masterId) {
|
||||
function gfn_rentItem(mngOrgCd, masterId, token) {
|
||||
|
||||
if(gfn_isEmpty(masterId)) {
|
||||
alert("자료ID 정보가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(gfn_isEmpty(token)) {
|
||||
alert("잘못된 접근입니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
var form = document.createElement("form");
|
||||
form.style.display = "none";
|
||||
$(form).attr("action", "/rent/confirmRent.do");
|
||||
$(form).attr("method", "get");
|
||||
$(form).attr("method", "post");
|
||||
$(form).attr("target", "_blank");
|
||||
|
||||
var element1 = document.createElement("input");
|
||||
@ -534,8 +529,13 @@ function gfn_rentItem(mngOrgCd, masterId) {
|
||||
$(element2).attr("name", "selItems");
|
||||
$(element2).attr("value", masterId);
|
||||
|
||||
var element3 = document.createElement("input");
|
||||
$(element3).attr("name", "csrfToken");
|
||||
$(element3).attr("value", token);
|
||||
|
||||
form.appendChild(element1);
|
||||
form.appendChild(element2);
|
||||
form.appendChild(element3);
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
@ -545,17 +545,22 @@ function gfn_rentItem(mngOrgCd, masterId) {
|
||||
return;
|
||||
}
|
||||
|
||||
function gfn_reserveReadItem(mngOrgCd, masterId) {
|
||||
function gfn_reserveReadItem(mngOrgCd, masterId, token) {
|
||||
|
||||
if(gfn_isEmpty(masterId)) {
|
||||
alert("자료ID 정보가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(gfn_isEmpty(token)) {
|
||||
alert("잘못된 접근입니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
var form = document.createElement("form");
|
||||
form.style.display = "none";
|
||||
$(form).attr("action", "/read/confirmRead.do");
|
||||
$(form).attr("method", "get");
|
||||
$(form).attr("method", "post");
|
||||
$(form).attr("target", "_blank");
|
||||
|
||||
var element1 = document.createElement("input");
|
||||
@ -566,8 +571,13 @@ function gfn_reserveReadItem(mngOrgCd, masterId) {
|
||||
$(element2).attr("name", "selItems");
|
||||
$(element2).attr("value", masterId);
|
||||
|
||||
var element3 = document.createElement("input");
|
||||
$(element3).attr("name", "csrfToken");
|
||||
$(element3).attr("value", token);
|
||||
|
||||
form.appendChild(element1);
|
||||
form.appendChild(element2);
|
||||
form.appendChild(element3);
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user