onload시 a태그에 click이벤트를 부여하여 "aClick"라는 함수를 호출하기

 

 window.onload = function () {
  var aArr = document.getElementsByTagName("A");
  for(var i = 0 ; i < aArr.length ; i++){
   aArr[i].addEventListener("click", function(){
    aClick(this.href);
   });
  }
 }

반응형

WITH와 PIVOT, CONNECT BY, GROUP 등을 이용한 메뉴별 권한 조회하는 쿼리 예제

(엑셀로 손으로 작업하는 것보다 실수가 없이 정확하다.)

 

SELECT 
            '메뉴ID' AS MENU_ID
          , 'NO' AS NO
          , '1 Depth' AS DEPTH_1
          , '2 Depth' AS DEPTH_2
          , '3 Depth' AS DEPTH_3
          , '4 Depth' AS DEPTH_4
          , '5 Depth' AS DEPTH_5
          , 'Url' AS MENU_URL
          , (SELECT USER_GROUP_NM FROM TB_USER_GROUP WHERE USER_GROUP_ID = '001') AS GROUP_001
          , (SELECT USER_GROUP_NM FROM TB_USER_GROUP WHERE USER_GROUP_ID = '002') AS GROUP_002
          , (SELECT USER_GROUP_NM FROM TB_USER_GROUP WHERE USER_GROUP_ID = '003') AS GROUP_003
          , (SELECT USER_GROUP_NM FROM TB_USER_GROUP WHERE USER_GROUP_ID = '004') AS GROUP_004
FROM DUAL
UNION ALL
SELECT
            A.MENU_ID
          , ROWNUM||'' AS NO
          , CASE WHEN A.MENU_LEVEL = '1' THEN A.MENU_NAME ELSE NULL END AS DEPTH_1
          , CASE WHEN A.MENU_LEVEL = '2' THEN A.MENU_NAME ELSE NULL END AS DEPTH_2
          , CASE WHEN A.MENU_LEVEL = '3' THEN A.MENU_NAME ELSE NULL END AS DEPTH_3
          , CASE WHEN A.MENU_LEVEL = '4' THEN A.MENU_NAME ELSE NULL END AS DEPTH_4
          , CASE WHEN A.MENU_LEVEL = '5' THEN A.MENU_NAME ELSE NULL END AS DEPTH_5
          , A.MENU_URL
          , GROUP_001
          , GROUP_002
          , GROUP_003
          , GROUP_004
FROM TB_MENU_INFO A
        , (
            WITH TUG AS (
                SELECT USER_GROUP_ID
                  FROM TB_USR_GRP
                WHERE USE_AT = 'Y'
            )
            SELECT
                        MENU_ID
                      , MAX(CASE WHEN GROUP_001 = USER_GROUP_ID THEN 'O' ELSE NULL END)  AS GROUP_001
                      , MAX(CASE WHEN GROUP_002 = USER_GROUP_ID THEN 'O' ELSE NULL END)  AS GROUP_002
                      , MAX(CASE WHEN GROUP_003 = USER_GROUP_ID THEN 'O' ELSE NULL END)  AS GROUP_003
                      , MAX(CASE WHEN GROUP_004 = USER_GROUP_ID THEN 'O' ELSE NULL END)  AS GROUP_004
              FROM TUG
              PIVOT(MAX(USER_GROUP_ID) FOR USER_GROUP_ID IN ('001' AS GROUP_001, '002' AS GROUP_002, '003' AS GROUP_003, '004' AS GROUP_004) )
                    , TB_GRP_MENU TGM
            WHERE TGM.USE_AT = 'Y'
            GROUP BY MENU_ID
          ) B
WHERE A.USE_YN = 'Y'
AND A.DEL_YN = 'N'
AND A.MENU_ID = B.MENU_ID
START WITH A.MENU_UPPER_ID IS NULL
CONNECT BY PRIOR A.MENU_ID = A.MENU_UPPER_ID

반응형

RedirectAttributes 사용

리다이렉트시 "redivect:/view.do?rMsg=완료되었습니다."와 같이 표시되는것을 "redivect:/view.do"로 깔끔히 표시되도록 해준다.

(인코딩 문제도 해결)

 

@Controller
public class PortalController extends BaseController{

 

@RequestMapping("/list.do")
 public String doList(@ModelAttribute("listVO")ListVO vo, HttpServletRequest request,
   RedirectAttributes redirectAttributes) throws Exception{

   redirectAttributes.addFlashAttribute("rMsg", "완료되었습니다.");
  return "redirect:/view.do";
 }

 

}

 

주의할 점중 하나는 egov-com-servlet.xml 설정파일에 아래 설정이 잡혀있어야된다.

(리다이렉트 하기전 자꾸 에러가 나고 PortalController의 /list.do에 접근하기 전에 튕겨버려서 에러찾기가 힘들었다.)

 

<mvc:annotation-driven />

반응형

pdf 생성 라이브러리 itextpdf jar

 

import java.io.File;

import org.terracotta.agent.repkg.de.schlichtherle.io.FileOutputStream;

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

public class TestPdfCreate {

 public void pdfCreate() throws Exception {
  String[] nameArr = {"Mr.Lee", "Mr.Kim", "Mr.Bae", "Mr.Hong"};
  String[] ageArr = {"41", "25", "16", "30"};
  String fileName = "";
  String dir = "E:/Test/Pdf";
  fileName = "testFile.pdf";
  
  File directory = new File(dir);
  if(!directory.exists()) directory.mkdirs();
  File file = new File(dir+"/"+fileName);
  file.createNewFile();
  
  Document document = new Document();
  FileOutputStream fos = new FileOutputStream(file);
  PdfWriter.getInstance(document, fos);
  
  document.open();
  PdfPTable table = new PdfPTable(2);
  
  for(int i = 0 ; i < nameArr.length ; i++){
   table.addCell("name : " + nameArr[i]);
   table.addCell("age : " + ageArr[i]);
  }
  
  document.add(table);
  document.close();
 }
 
 public static void main(String[] args) {
  try {
   TestPdfCreate pbv = new TestPdfCreate();
   pbv.pdfCreate();
   System.out.println("file success");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

반응형

이전 주소 스크립트 :  document.referrer

현재 주소 스크립트 : location.href

반응형

SELECT TO_CHAR(SYSDATE, 'YYYY') - 5 + LEVEL AS YEAR
  FROM DUAL
 CONNECT BY LEVEL < 11

반응형

LEFT JOIN과 LEFT OUTER JOIN는 같다....

 

자주 쓰지 않는 방식이라 헷갈려서 찾아봤더니 결과는 동일하다고 한다.

 

길어서 쓰기가 불편하니 줄인 표현이라고 한다.

반응형

오라클 쿼리결과 이전 행데이터와 이후 행데이터 조회

 

SELECT
            LAG(A.MENU_ID) OVER(ORDER BY A.MENU_ID ASC) AS PRE_MENU_ID --이전 메뉴ID
          , A.MENU_ID --현재 메뉴ID
          , LEAD(A.MENU_ID) OVER(ORDER BY A.MENU_ID ASC) AS NEXT_MENU_ID --다음 메뉴ID
FROM TB_SF_MENU_INFO A
ORDER BY MENU_ID ASC

반응형

pre 태그는 태그안의 내용을 그대로 표시하지만 태그안의 태그사용이 가능

xmp 태그는 태그안의 내용을 그대로 표시하고 태그도 그대로 표시

반응형

--다중 LIKE 검색(오라클 10g부터 가능)

SELECT  * 
  FROM TB_MENU_INFO 
 WHERE  REGEXP_LIKE(MENU_NM, '참여업체|수집안내|메뉴정보')
 
--세번째 변수에 'i'를 추가하면 대소문자 구분하지 않고 검색
SELECT  * 
  FROM TB_MENU_INFO 
 WHERE  REGEXP_LIKE(MENU_URL, 'MYPAGE|user', 'i')

 

--시작하는 문자가 "전 or 지 or 스 or 마" 로 시작하는 데이터 검색
SELECT  * 
  FROM TB_MENU_INFO 
 WHERE  REGEXP_LIKE(MENU_NM, '^[전지스마]')
 
--"분석"으로 끝나는 데이터 검색
SELECT  * 
  FROM TB_MENU_INFO 
 WHERE  REGEXP_LIKE(MENU_NM, '분석$')

반응형

--최근 수정된 데이터조회(수정된지 오래되었으면 오류발생)

SELECT
ORA_ROWSCN AS SCN
, TO_CHAR(SCN_TO_TIMESTAMP(ORA_ROWSCN),'YYYY-MM-DD HH24:MI:SS') AS TM
, MENU_ID
FROM TB_MENU_INFO;

 

 

--10분전 데이터 조회

SELECT  * 
  FROM TB_MENU_INFO  AS OF TIMESTAMP(SYSTIMESTAMP - INTERVAL '10' MINUTE) 
 WHERE  MENU_ID LIKE 'SC_%'

 

cf) SECOND, MINUTE, HOUR, DAY 로 조회 가능

 

--특정 날짜 시간 데이터 조회
SELECT  * 
  FROM TB_MENU_INFO  AS OF TIMESTAMP(TO_TIMESTAMP('2018-11-12 08:30:10', 'YYYY-MM-DD HH24:MI:SS')) 
 WHERE  MENU_ID LIKE 'SC_%'

반응형

/*
 * MENU_ID가 PK임
 * MENU_CATE데이터가 'B', 'I', 'P' 인것의 MENU_TYPE별 개수 구하기
 */
WITH PV AS (
    SELECT MENU_ID
              , MENU_CATE
              , MENU_TYPE
      FROM TB_SF_MENU_INFO
)
SELECT *
  FROM PV
  PIVOT(COUNT(MENU_ID) FOR MENU_TYPE IN ('B' AS TYPE_B, 'I' AS TYPE_I, 'P' AS TYPE_P));

 

--조회결과 중 일부 : MENU_CATE 가 'M'이고 MENU_TYPE가 'P'인 데이터가 9건 조회됨

 

--확인쿼리

 

SELECT COUNT(MENU_ID)
  FROM TB_SF_MENU_INFO
WHERE MENU_CATE = 'M'
     AND MENU_TYPE = 'P';

 

--조회결과 : 9건

반응형

여러행을 하나의 컬럼으로 합치기

 

--Oracle version : 11g
SELECT LISTAGG(CODE, ',') WITHIN GROUP(ORDER BY CODE DESC) AS PLUS_COLUMN 
  FROM COM_CODE
WHERE ROWNUM < 5;

 

--Oracle version : 10g
SELECT WM_CONCAT(CODE) AS PLUS_COLUMN
  FROM COM_CODE
WHERE ROWNUM < 5;

 

--Oracle version : 9i
SELECT SUBSTR(XMLAGG(XMLELEMENT(X, ',', CODE) ORDER BY CODE).EXTRACT('//text()'), 2) AS PLUS_COLUMN
  FROM COM_CODE
WHERE ROWNUM < 5;

 

반응형

--캐릭터셋 조회
SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET';

 

--CONVERT( '대상 문자열', '타겟 인코딩', '소스 인코딩')
SELECT COMMENTS
          , CONVERT(COMMENTS, 'AL32UTF8', 'KO16KSC5601') AS COMMENTS_CONVERT
    FROM ALL_COL_COMMENTS WHERE TABLE_NAME = 'COM_CODE';

반응형

--1시간전
SELECT * FROM TABLE_NAME AS OF TIMESTAMP((SYSDATE-1/24));

 

--특정시간
SELECT * FROM TABLE_NAME AS OF TIMESTAMP(TO_DATE('20181101140000', 'YYYYMMDDHH24MISS'));

반응형

SELECT * FROM v$version WHERE banner LIKE 'Oracle%';

반응형

jquery ztree demo

 

https://emluis.outsystemscloud.com/zTreeExample/

반응형

'개발 > 참고사이트' 카테고리의 다른 글

부트스트랩 무료 템플릿 사이트  (1) 2020.08.11
무료 아이콘 사이트  (0) 2020.07.10
원격데스크탑 연결  (0) 2020.07.10
PPT 무료템플릿 모아놓은 사이트  (2) 2019.06.05
Mybatis 매퍼 설정관련  (0) 2019.02.07


<button type="button" class="btn btn-azure btn-sm btn-scroll btn-scroll-top ti-bookmark addScrap" data-type="customChart">
    <span>스크랩</span>
</button>
<!-- Modal -->
<div id="memoDialogModal" title="메모저장">
 <div>
  <textarea name="memo" id="memo" rows="5" cols="50">Test Memo</textarea>
  <button class="addScrapSave" data-type="customChart">저장</button>
 </div>
</div>

 

 

  $('.addScrap').on('click', function(){
   $('#memo').text('');
   $( "#memoDialogModal" ).dialog({
      resizable: false,
      height: 300,
      width: 500,
      modal: true,
      buttons: {
     "닫기": function() {
        $( this ).dialog( "close" );
     }
      }
    });
  });
  
  $('.addScrapSave').on('click', function(){
   var scrapUrl = window.location.pathname;
   var scrapParam = $('form[name=searchFrm]').serialize();
   var titleName =$('.mainTitle').text().trim();
   var subTitle = $('#tab-nav ul li') ? $('#tab-nav ul li.active-cr').text().trim() : '';
   var scrapAction = $(this).attr('data-type');
   var memo = $('#memo').text();

   if(subTitle)
    titleName += "-" + subTitle;

   var param = {scrapName : titleName, scrapUrl : scrapUrl, scrapParam : scrapParam, scrapAction : scrapAction , memo : memo};
   var url = '/myPage//addScrapAjax.do';

   $.ajaxSubmit(url, param, function(data){
    if(data.result){
     alert("스크랩 되었습니다.");
     $( "#memoDialogModal" ).dialog( "close" );
    }
    else
     alert("에러가 발생하였습니다.");
   });
  });

반응형

package com.collabi.red.sys.openapi.test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.collabi.red.ext.common.utils.StringUtil;

import net.sf.json.JSONObject;

public class OpenApiTest {

 private static final Logger logger = LoggerFactory.getLogger(OpenApiTest.class);

 public OpenApiTest() {

 }

 public Map<String, Object> setParamMap() {
  Map<String, Object> dataMap = new ConcurrentHashMap<String, Object>();
  dataMap.put("PARAM1", "APPLE");
  dataMap.put("PARAM2", "WOOD");
  return dataMap;
 }

 public void callApiCommon() {
  String defUrl = "subinto.test.com";
  String encodType = "UTF-8";
  StringBuffer sb = new StringBuffer();
  sb.append(defUrl);
  Map<String, Object> dataMap = this.setParamMap();
  this.getRedundancyInterLook(sb.toString(), this.setParamMapToJson(dataMap), encodType);
 }

 public String setParamMapToJson(Map<String, Object> dataMap) {
  JSONObject jsonParam = new JSONObject();
  jsonParam.putAll(dataMap);
  StringBuffer sbEqParam = new StringBuffer();
  try {
   sbEqParam.append("paramData=").append(URLEncoder.encode(jsonParam.toString().replaceAll("%", "%25"), "UTF-8"));
  } catch (UnsupportedEncodingException e) {
   logger.error(e.getMessage());
  }
  return sbEqParam.toString();
 }

 private void getRedundancyInterLook(String interLookUrl, String urlParameters, String encodType) {
  System.out.println("############################ : URL " + interLookUrl);
  System.out.println("############################ : urlParameters " + urlParameters);
  JSONObject jsonObj = this.concertFromHTTPtoJSON(interLookUrl, urlParameters, encodType);
  System.out.println(" :::::::::: interLookUrl : " + interLookUrl);
  System.out.println(" :::::::::: viewType   : " + encodType);
  System.out.println(" :::::::::: jsonObj   : " + ToStringBuilder.reflectionToString(jsonObj));
 }

 private JSONObject concertFromHTTPtoJSON(String xmlUrl, String urlParameters, String encodType) {
  URL url = null;
  HttpURLConnection httpUrlConnection = null;
  BufferedWriter bw = null;
  InputStream is = null;
  JSONObject jsonObj = null;

  try {
   url = new URL(xmlUrl);
   URLConnection urlConnection = url.openConnection();
   httpUrlConnection = (HttpURLConnection) urlConnection;

   String postData = urlParameters;

   httpUrlConnection.setDoInput(true);
   httpUrlConnection.setDoOutput(true);
   httpUrlConnection.setRequestMethod("POST");
   httpUrlConnection.setUseCaches(false);
   httpUrlConnection.setDefaultUseCaches(false);
   httpUrlConnection.setRequestProperty("Content-Length", "0");
   httpUrlConnection.setRequestProperty("Content-Language", encodType);

   bw = new BufferedWriter(new OutputStreamWriter(httpUrlConnection.getOutputStream(), "UTF-8"));
   bw.write(postData);
   bw.flush();

   is = httpUrlConnection.getInputStream();

   BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
   String jsonText = this.readAll(rd);
   jsonObj = JSONObject.fromObject(StringUtil.converterDecoding(jsonText, encodType));

   bw.close();
   is.close();
   is = null;
  } catch (MalformedURLException e) {
   logger.error(e.getMessage());
  } catch (IOException e) {
   logger.error(e.getMessage());
  } finally {

   if (httpUrlConnection != null)
    try {
     httpUrlConnection.disconnect();
     httpUrlConnection = null;
    } catch (Exception e) {
     logger.error(e.getMessage());
    }

   if (bw != null)
    try {
     bw.close();
    } catch (Exception e) {
     logger.error(e.getMessage());
    }

   if (is != null)
    try {
     is.close();
     is = null;
    } catch (Exception e) {
     logger.error(e.getMessage());
    }
  }

  return jsonObj;
 }

 private String readAll(BufferedReader rd) throws IOException {
  StringBuilder sb = new StringBuilder();

  String inputStr;
  while ((inputStr = rd.readLine()) != null) {
   sb.append(inputStr);
  }

  return sb.toString();
 }

 public static void main(String[] args) {
  new OpenApiTest().callApiCommon();
 }

}

반응형
###############################################################
## 작업 #1 프로젝트 준비

## WEB-INF/lib
commons-logging.jar
org.springframework.aop-3.0.1.RELEASE.jar
org.springframework.asm-3.0.1.RELEASE.jar
org.springframework.beans-3.0.1.RELEASE.jar
org.springframework.context-3.0.1.RELEASE.jar
org.springframework.core-3.0.1.RELEASE.jar
org.springframework.expression-3.0.1.RELEASE.jar
org.springframework.transaction-3.0.1.RELEASE.jar
org.springframework.web-3.0.1.RELEASE.jar
spring-security-config-3.0.2.RELEASE.jar
spring-security-core-3.0.2.RELEASE.jar
spring-security-web-3.0.2.RELEASE.jar


###############################################################
## 작업 #2 초간단 HTTP 보안

## web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext*.xml</param-value>
</context-param>

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


## applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security
           http://www.springframework.org/schema/security/spring-security-3.0.xsd">

<http auto-config='true'>
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
</http>

<authentication-manager>
<authentication-provider>
<user-service>
<user name="jimi" password="jimis" authorities="ROLE_USER, ROLE_ADMIN" />
<user name="bob" password="bobs" authorities="ROLE_USER" />
</user-service>
</authentication-provider>
</authentication-manager>

</beans:beans>


## /index.jsp
<h1>메인 페이지</h1>
<br/>
<a href="/admin">관리자 페이지</a>


## /admin/index.jsp
<h1>Admin Main Page</h1>
Administrator only!!!
<br/>
<a href="/">메인 페이지</a>


###############################################################
## 응용 #1 직접 만든 로그인 폼

## applicationContext-security.xml
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/login.jsp"/>


## login.jsp
<h1>로그인 페이지</h1>
<form name='f' action='/j_spring_security_check' method='POST'>
 <table border="1">
    <tr><td>아이디 </td><td><input type='text' name='j_username' value=''></td></tr>
    <tr><td>비밀번호 </td><td><input type='password' name='j_password'/></td></tr>
    <tr><td colspan='2'><input name="submit" type="submit" value="로그인"/></td></tr>
  </table>
</form>


###############################################################
## 응용 #2 로그아웃

## /index.jsp
<br/>
<a href="/j_spring_security_logout">로그아웃</a>


###############################################################
## 응용 #3 사용자 로그인 확인

## index.jsp
<%@page import="org.springframework.security.core.*"%>
<%@page import="org.springframework.security.core.context.*"%>
<%@page import="org.springframework.security.core.userdetails.*"%>
<%
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

String username = null;
boolean isAnonymous = true;
if (principal instanceof UserDetails) {
username = ((UserDetails) principal).getUsername();
isAnonymous = false;
} else {
username = principal.toString();
isAnonymous = true;
}
%>

...

<%
if(isAnonymous) {
%>
<a href="/login.jsp">로그인</a>
<%
} else {
%>
<%=username %>님 반갑습니다!
<br/>
<a href="/j_spring_security_logout">로그아웃</a>
<%
}
%>


###############################################################
## 응용 #4 친절한 안내

## applicationContext-security.xml
<http auto-config='true' access-denied-page="/noAuthorized.jsp">


## noAuthorized.jsp
<h1>접근 권한 없음!!</h1>
<br/>
<a href="/">메인 페이지</a>


###############################################################
## 응용 #5 로그인 실패 메시지

## applicationContext-security.xml
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"/>


## login.jsp
<%@page import="org.springframework.security.core.*"%>
<%@page import="org.springframework.security.web.authentication.*"%>
<%
boolean loginError = request.getParameter("login_error") != null;

String errorMsg = "none";
if (loginError) {
AuthenticationException ex = (AuthenticationException) session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
errorMsg = ex != null ? ex.getMessage() : "none";
}
%>

...

<%
if(loginError) {
if("Bad credentials".equals(errorMsg)) {
%>
<font color="red">아이디나 비밀번호 입력이 틀렸습니다.</font>
<%
} else {
%> 
<font color="red">로그인 에러 : <%=errorMsg %></font>
<%
}
}
%> 


###############################################################
## 응용 #6 로그인 성공 페이지

## applicationContext-security.xml
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"
default-target-url="/" always-use-default-target="true"/>


###############################################################
## 응용 #7 특정 URL 통과시키기

## applicationContext-security.xml
<intercept-url pattern="/login.jsp" filters="none"/>
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<intercept-url pattern="/**" access="ROLE_USER" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"
default-target-url="/" always-use-default-target="true"/>


###############################################################
## 응용 #8-1 동시에 1명만 접속(기존 세션 만료)

## applicationContext-security.xml
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"
default-target-url="/" always-use-default-target="true"/>
<session-management>
<concurrency-control max-sessions="1"/>
</session-management>


###############################################################
## 응용 #8-2 동시에 1명만 접속(로그인 에러)

## applicationContext-security.xml
<session-management>
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>


###############################################################
## 응용 #9 사용자 정보 DB에서 가져오기

## postgresql-8.4-701.jdbc4.jar
## org.springframework.jdbc-3.0.1.RELEASE-A.jar


## db
  create table users(
      username varchar(50) not null primary key,
      password varchar(50) not null,
      enabled boolean not null);

  create table authorities (
      username varchar(50) not null,
      authority varchar(50) not null,
      constraint fk_authorities_users foreign key(username) references users(username));
      create unique index ix_auth_username on authorities (username,authority);

INSERT INTO users(username, "password", enabled) VALUES ('bob', 'bobs', true);
INSERT INTO users(username, "password", enabled) VALUES ('jimi', 'jimis', true);

INSERT INTO authorities(username, authority) VALUES ('bob', 'ROLE_USER');
INSERT INTO authorities(username, authority) VALUES ('jimi', 'ROLE_USER');
INSERT INTO authorities(username, authority) VALUES ('jimi', 'ROLE_ADMIN');


## applicationContext-security.xml
<authentication-manager>
<authentication-provider>
<jdbc-user-service data-source-ref="securityDataSource" />
</authentication-provider>
</authentication-manager>

..

<beans:bean id="securityDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="org.postgresql.Driver" />
<beans:property name="url" value="jdbc:postgresql:security" />
<beans:property name="username" value="security" />
<beans:property name="password" value="security" />
</beans:bean>



/** 심화 **/


###############################################################
## 심화 #1 메서드 권한제어

## com.springsource.org.aopalliance-1.0.0.jar
## com.springsource.org.aspectj.tools-1.6.6.RELEASE.jar
## com.springsource.net.sf.cglib-2.1.3.jar
## org.springframework.web.servlet-3.0.1.RELEASE-A.jar


## web.xml
    <servlet>
        <servlet-name>security</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>security</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>


## security-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-package="my.controller" />
<context:annotation-config />

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>

</beans>


## my.controller.MyController.java
@Controller
public class MyController {

@RequestMapping("/mvcHello")
public void mvcHello() {
}
}


## WEB-INF/view/mvcHello.jsp
<h1>MVC Hello</h1>


## applicationContext-security.xml
<intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error"
default-target-url="/" always-use-default-target="true"/>

----

## applicationContext-security.xml
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

...

<context:component-scan base-package="my.service" />

<global-method-security secured-annotations="enabled"/>  


## my.service.MyService.java
@Service
public class MyService {

@Secured("ROLE_ADMIN")
public String getSecurity() {
return "success";
}
}


## my.controller.MyController.java
@Autowired MyService myService;
@RequestMapping("/hasSomeSecurity")
public void hasSomeSecurity(Model model) {
String result = myService.getSecurity();
model.addAttribute("result", result);
}


## index.jsp
<a href="/hasSomeSecurity.do">보안 페이지</a>
<br/>


## WEB-INF/view/hasSomeSecurity.jsp
<h1>무언가 보안요소를 가지고 있는 페이지</h1>
보안결과 : ${result }


###############################################################
## 심화 #2 MyUserDeatilsService

## applicationContext-security.xml
<authentication-manager>
<authentication-provider user-service-ref="myUserDetailsService"/>
</authentication-manager>

<beans:bean id="myUserDetailsService"
class="my.service.MyUserDetailsService">
<beans:property name="myDao">
<beans:bean class="my.dao.MyDao">
<beans:property name="dataSource" ref="securityDataSource"/>
</beans:bean>
</beans:property>
</beans:bean>


## my.domain.MyUserDetails
public class MyUserDetails implements UserDetails {

private String username;
private String password;
private boolean isEnabled = true;
private boolean isAccountNonExpired = true;
private boolean isAccountNonLocked = true;
private boolean isCredentialsNonExpired = true;
private Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
public MyUserDetails(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public Collection<GrantedAuthority> getAuthorities() {
return authorities;
}

@Override
public String getPassword() {
return password;
}

@Override
public String getUsername() {
return username;
}

@Override
public boolean isAccountNonExpired() {
return isAccountNonExpired;
}

@Override
public boolean isAccountNonLocked() {
return isAccountNonLocked;
}

@Override
public boolean isCredentialsNonExpired() {
return isCredentialsNonExpired;
}

@Override
public boolean isEnabled() {
return isEnabled;
}

}


## my.service.MyUserDetailsService
public class MyUserDetailsService implements UserDetailsService {

private MyDao myDao;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
UserDetails userDetails = myDao.getUserDetails(username);
Collection<GrantedAuthority> authorities = myDao.getAuthorities(username);
userDetails.getAuthorities().addAll(authorities);
return userDetails;
}

public void setMyDao(MyDao myDao) {
this.myDao = myDao;
}
}


## my.dao.MyDao.java
public class MyDao extends JdbcDaoSupport {

    public static final String DEF_USERS_BY_USERNAME_QUERY =
        "select username,password " +
        "from users " +
        "where username = ?";
    public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY =
        "select username,authority " +
        "from authorities " +
        "where username = ?";
    
public UserDetails getUserDetails(String username) {
        List<UserDetails> userDetailsList = getJdbcTemplate().query(DEF_USERS_BY_USERNAME_QUERY, new String[] {username}, new RowMapper<UserDetails>() {
            public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
                String username = rs.getString(1);
                String password = rs.getString(2);
                return new MyUserDetails(username, password);
            }

        });
        
        if(userDetailsList.size() == 1)
        return userDetailsList.get(0);
        else 
        return null;
}

public Collection<GrantedAuthority> getAuthorities(String username) {
        return getJdbcTemplate().query(DEF_AUTHORITIES_BY_USERNAME_QUERY, new String[] {username}, new RowMapper<GrantedAuthority>() {
            public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
                String roleName = rs.getString(2);
                return new GrantedAuthorityImpl(roleName);
            }
        });
}

}


###############################################################
## 심화 #3 XML-Based Configuration

## applicationContext-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
<sec:filter-chain-map path-type="ant">
<sec:filter-chain pattern="/login.jsp" filters="none"/>
<sec:filter-chain pattern="/sessionExpired.jsp" filters="none"/>
<sec:filter-chain pattern="/**" filters="
     securityContextPersistenceFilter,
     logoutFilter,
     formLoginFilter,
     exceptionTranslationFilter,
     filterSecurityInterceptor" />
</sec:filter-chain-map>
</bean>

<bean id="securityContextPersistenceFilter"
class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
<property name="securityContextRepository">
<bean class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
</property>
</bean>
<bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg><bean class="org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler"/></constructor-arg>
<constructor-arg><bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/></constructor-arg>
<property name="filterProcessesUrl" value="/j_spring_security_logout"></property>
</bean>

<bean id="formLoginFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="filterProcessesUrl" value="/j_spring_security_check"/>
<property name="authenticationSuccessHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/"></property>
<property name="alwaysUseDefaultTargetUrl" value="true"></property>
</bean>
</property>
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login.jsp?login_error"></property>
</bean>
</property>
<property name="sessionAuthenticationStrategy">
<bean class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg>
<bean class="org.springframework.security.core.session.SessionRegistryImpl"></bean>
</constructor-arg>
<property name="maximumSessions" value="1"></property>
</bean>
</property>
</bean> 

<bean id="exceptionTranslationFilter"
    class="org.springframework.security.web.access.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<property name="loginFormUrl" value="/login.jsp"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.springframework.security.web.access.AccessDeniedHandlerImpl">
<property name="errorPage" value="/noAuthorized.jsp"/>
</bean>
</property>
</bean>

<bean id="filterSecurityInterceptor"
       class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager"/>
<property name="accessDecisionManager" ref="accessDecisionManager"/>
<property name="securityMetadataSource">
<sec:filter-security-metadata-source>
<sec:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<sec:intercept-url pattern="/**" access="ROLE_USER" />
</sec:filter-security-metadata-source>
</property>
</bean>

<bean id="authenticationManager"
class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
<bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="myUserDetailsService" />
</bean>
</property>
</bean>
<bean id="myUserDetailsService"
class="my.service.MyUserDetailsService">
<property name="myDao">
<bean class="my.dao.MyDao">
<property name="dataSource" ref="securityDataSource"/>
</bean>
</property>
</bean>

<bean id="securityDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver" />
<property name="url" value="jdbc:postgresql:security" />
<property name="username" value="security" />
<property name="password" value="security" />
</bean>

<bean id="accessDecisionManager" class="org.springframework.security.access.vote.ConsensusBased">
<property name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"></bean>
</list>
</property>
</bean>

<context:component-scan base-package="my.service" />

<sec:global-method-security secured-annotations="enabled"></sec:global-method-security>  
반응형

자바 프로그래머로써 일을하다보면 남이 만들어둔 .jar 안에 .class 파일을 열어서 확인하고 싶을때가 있다.

이때 Jad 를 사용하면 .class 파일을 .java 로 디컴파일하여 소스코드를 확인할수있다.



우선 아래 경로에서 jad.exe 파일을 다운받아야한다.

https://varaneckas.com/jad/


이제는 바로 사용하여도 좋다.


이제 콘솔창을 열어 jad.exe가 설치된 경로로 이동하여 jad 를입력해본다.

그러면 아래와 같이 option들의 대한 설명이 적혀있는 문자열이 출력된다.





현재 아래 와 같이 폴더안에는 .class 파일 하나와 dir 폴더 jad 파일이 존재한다.

클래스 파일과 dir 은 테스트 용도로 넣었다.


※ Readme.txt 를 보면 좀더 자세한 설명이 나와있다.






.class 파일 하나를 디컴파일


명렁어

jad -o -sjava ComUtil.class


-o : 디컴파일후에 생성된 파일과 동일한 파일이 있을경우 덮어쓴다.

-s<ext> : 확장자명을 지정한다.  -sjava 는 .java 로 생성한다는 뜻이다.

 






폴더(패키지)전체를 디컴파일 


명령어

jad -o -r -sjava dir/*.class


-r : 디렉토리를 기준으로 디컴파일한다.


dir/*.class 는 dir 폴더안에 모든 class 파일을 디컴파일하겠다는 뜻이다.


※ 실제 java파일 생성되는 경로는 class 파일에 들어있는 내용중 패키지내용을 따라서 폴더가 만들어진다.







확인









출처: http://javacpro.tistory.com/23 [버물리의 IT공부]

반응형

GPKI 인증서 로그인 기능을 구현하려고 하는 경우에는 EgovLoginController.java를 다음과 같이 변경한다.

  • 로그인 화면 처리 부분을 다음과 같이 수정한다.
public String loginUsrView(@ModelAttribute("loginVO") LoginVO loginVO,
    HttpServletRequest request,
    HttpServletResponse response,
    ModelMap model) 
    throws Exception {
	// # GPKI 인증을 처리하는 경우 
	GPKIHttpServletResponse gpkiresponse = null;
	GPKIHttpServletRequest gpkirequest = null;
 
	try{
 
		gpkiresponse=new GPKIHttpServletResponse(response); 
		gpkirequest= new GPKIHttpServletRequest(request);
		gpkiresponse.setRequest(gpkirequest);
		model.addAttribute("challenge", gpkiresponse.getChallenge());
		return "cmm/uat/uia/EgovLoginUsr";
 
	}catch(Exception e){
		return "cmm/egovError";
	}
}
  • 인증서 로그인 처리 부분을 다음과 같이 수정한다.
public String actionCrtfctLogin(@ModelAttribute("loginVO") LoginVO loginVO, 
    HttpServletRequest request,
    HttpServletResponse response,
    ModelMap model)
    throws Exception {
    	// # GPKI 인증을 처리하는 경우 
    	// 접속IP
    	String userIp = EgovClntInfo.getClntIP(request);
 
    	// 1. GPKI 인증
    	GPKIHttpServletResponse gpkiresponse = null;
	GPKIHttpServletRequest gpkirequest = null;
	String dn = "";
	try{
		gpkiresponse = new GPKIHttpServletResponse(response);
		gpkirequest = new GPKIHttpServletRequest(request);
		gpkiresponse.setRequest(gpkirequest);
		X509Certificate cert = null; 
 
		byte[] signData = null;
		byte[] privatekey_random = null;
		String signType = "";
		String queryString = "";
 
		cert = gpkirequest.getSignerCert();
		dn = cert.getSubjectDN();
 
		java.math.BigInteger b = cert.getSerialNumber();
		b.toString();
		int message_type =  gpkirequest.getRequestMessageType();
		if( message_type == gpkirequest.ENCRYPTED_SIGNDATA || 
		    message_type == gpkirequest.LOGIN_ENVELOP_SIGN_DATA ||
		    message_type == gpkirequest.ENVELOP_SIGNDATA || 
		    message_type == gpkirequest.SIGNED_DATA){
		    signData = gpkirequest.getSignedData();
		    if(privatekey_random != null) {
			privatekey_random   = gpkirequest.getSignerRValue();
		    }
		    signType = gpkirequest.getSignType();
		}       
		queryString = gpkirequest.getQueryString();
	}catch(Exception e){
		return "cmm/egovError";
	}
 
	// 2. 업무사용자 테이블에서 dn값으로 사용자의 ID, PW를 조회하여
	// 이를 일반로그인 형태로 인증하도록 함
	if (dn != null && !dn.equals("")) {
 
		loginVO.setDn(dn);
		LoginVO resultVO = loginService.actionCrtfctLogin(loginVO);
		if (resultVO != null && resultVO.getId() != null && 
		    !resultVO.getId().equals("")) {	
		    // 3. spring security 연동
		    return "redirect:/j_spring_security_check?j_username=" +
		           resultVO.getUserSe() + resultVO.getId() + 
			   "&j_password=" + resultVO.getUniqId();
		} else {
		    model.addAttribute("message", 
		                       egovMessageSource.getMessage("fail.common.login"));
		    return "cmm/uat/uia/EgovLoginUsr";
		}
	} else {
		model.addAttribute("message", 
		                   egovMessageSource.getMessage("fail.common.login"));
		return "cmm/uat/uia/EgovLoginUsr";
	}
}
반응형

+ Recent posts