작업 개요
- 로그인 했는지 검사하여, 로그인 하지 않았다면, 로그인 페이지나 특정 XML 메세지를 보내기 위한 인터셉터를 작성한다.
- 액션 요청에 대해서만 검증할 것이기 때문에 인터셉터에서의 적용이 적합하겠다.
- 적용 작업은 아래와 같다.
- 커스텀 인터셉터 작성하기
- struts.xml에 인터셉터 정의하여 적용하기
- 처리 프로세스 플로우차트 보기
[편집] 커스텀 인터셉터 작성하기
- // TODO 부분(2군데..)는 해당 애플리케이션에 맞게 작성해 주어야 하겠다.
- 첫번째는 proccessDeniedResponse() 메소드에 있으며, 마이플랫폼 메세지를 던져주는 부분이다.
- 두번째는 isLogined()메소드에 있으며, 세션상에 로그인 정보를 검사하는 부분이다.
- 소스 설명
- 인터셉터가 작동하는 메인 메소드는 intercept(ActionInvocation invocation) 메소드이다.
- 여기서 허용 URL인지, 로그인 했는지 검사하는 것과 요청을 거부하는 프로세스를 처리한다.
- excludeActions 변수는 로그인 했는지 검사하는 것에서 제외하기 위한 액션들이 있는 경우 사용한다.
- redirectWebPage 변수는 일반 웹 요청시 액션 수행 거부(로그인 하지 않음)에 대해 라디이렉트 할 페이지를 지정한다.
- 이와 마찬가지로 마이플랫폼 요청에 대한 거부 메세지도 파라미터화 하여 처리할 수 있겠다.
- 인터셉터가 작동하는 메인 메소드는 intercept(ActionInvocation invocation) 메소드이다.
public class LoginSessionCheckInterceptor extends AbstractInterceptor{ private static Log log = LogFactory.getLog(LoginSessionCheckInterceptor.class); protected Set excludeActions = null; protected String redirectWebPage = "/index.html"; // default page if not setted by param. public void setExcludeActions(String excludeActions) { this.excludeActions = TextParseUtil.commaDelimitedStringToSet(excludeActions); } public void setRedirectWebPage(String redirectWebPage) { if( StringUtils.isNotBlank(redirectWebPage)) this.redirectWebPage = redirectWebPage; } /** * check and deny the request unless rquested action is available action without login or has authenticated session. * */ public String intercept(ActionInvocation invocation) throws Exception { if( isAvailableActionWithoutLogin() ){ // check if action is available action without login return invocation.invoke(); // execute action } else{ if( isLogined()){ // check if logged in or not return invocation.invoke(); // execute action } else{ proccessDeniedResponse(); // redirect to login page, or send denial xml message return null; } } } private void proccessDeniedResponse() throws IOException { if( isMiplatformRequest(ServletActionContext.getRequest()) ){ // TODO send MiResponse denial message // example is following : // MiResponse miresponse = new MiResponse(ServletActionContext.getResponse()); // miresponse.error("-1","sessionout"); } else{ String redirectUrl = null; if( redirectWebPage.startsWith("/") || redirectWebPage.startsWith("\\")){ redirectUrl = ServletActionContext.getRequest().getContextPath() + redirectWebPage; }else{ redirectUrl = ServletActionContext.getRequest().getContextPath() + "/" +redirectWebPage; } ServletActionContext.getResponse().sendRedirect(redirectUrl); } } private boolean isMiplatformRequest(HttpServletRequest request) { String agent = request.getHeader("User-Agent"); if( agent != null && ( agent.indexOf("MiPlatform") != -1 ) ){ return true; }else{ return false; } } private boolean isLogined() { HttpSession session = ServletActionContext.getRequest().getSession(false); if( null == session) return false; // TODO check if session is logined session. // example is following : // if( isLogedin(session) ) return true; // else return false; return false; } private boolean isAvailableActionWithoutLogin() { String requestedResouece = getRequestedResource(ServletActionContext.getRequest()); if( log.isDebugEnabled() ) log.debug("Requested action resource : " + requestedResouece); String action = null; Iterator excludeActionsIter = excludeActions.iterator(); while( excludeActionsIter.hasNext() ){ action = (String) excludeActionsIter.next(); if( requestedResouece.equals(action) ) return true; } return false; } private String getRequestedResource(HttpServletRequest request){ String requestedResouece = null; String contextPath = request.getContextPath(); String requestedUri = request.getRequestURI(); if( "/".equals(contextPath) ){ requestedResouece = requestedUri; } else{ requestedResouece = requestedUri.substring(contextPath.length()); } return requestedResouece; } }
[편집] 인터셉터의 적용
- struts.xml에 우리가 작성한 인터셉터를 정의하고, 이를 이용하여 인터셉터 스택을 만든다.
- 정의가 끝나면 common 패키지를 상속하는 다른 모든 스트럿츠2 패키지들을 모두 디폴트 인터셉터 스택이 commonStack이 될
것이다.
- 여기서는 스트럿츠의 디폴트 인터셉터 스택을 다소 최적화하여 사용하고 있다.
- loginCheck 인터셉터의 정의 부분과 스택에서 사용하는 부분을 주의하여 살펴 본다.
- excludeActions 파라미터에는 샘플로 login.action과 /lab1/hello2.action은 로그인을 하지 않아도 수행할 수 있는 액션으로 정의해 놓았다.
- excludeActions 아래에 <param name="redirectWebPage">/login.jsp</param>를 추가 작성하면, 로그인 하지 않고 접근하는 액션 일반 웹 액션 요청들을 거부하고 login.jsp로 리다이렉트 하게 될 것이다.
- [과제] 웹 요청 말고도 마이플랫폼 요청을 거부하는 경우에 사용하는 에러코드와 에러메시지도 파라미터로 처리하도록 개선해 보자.
<struts> <package name="common" extends="struts-default" namespace=""> <interceptors> <interceptor name="loginCheck" class="kr.ac.catholic.web.struts2.interceptor.LoginSessionCheckInterceptor"/> <interceptor-stack name="commonStack"> <interceptor-ref name="exception"/> <interceptor-ref name="loginCheck"> <param name="excludeActions">login.action, /lab1/hello2.action</param> </interceptor-ref> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="i18n"/> <interceptor-ref name="chain"/> <interceptor-ref name="debugging"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="commonStack"/> </package> </struts>
참조사이트)