From JCFWiKi
|
|
- 산출물: 세션 체크하는 커스텀 인터셉터Spring MVC 개요
- 작성자: 정광선
- 최초작성일 : 2008/06/25
- 최종작성일 : 2008/06/25
Copyright © 2008 Daewoo Information Systems Co., Ltd.
|
|
|
- 스트럿츠2에서 세션 검사하는 커스텀 인터셉터를 작성해 본다.
|
|
|
- 권한별 요청 접근 처리가 아니며, 또한 모든 웹 요청이 아니라 스트럿츠 액션에 대한 요청만 처리하는 모듈 예제이다.
|
[편집] 작업 개요
- 로그인 했는지 검사하여, 로그인 하지 않았다면, 로그인 페이지나 특정 XML 메세지를 보내기 위한 인터셉터를 작성한다.
- 액션 요청에 대해서만 검증할 것이기 때문에 인터셉터에서의 적용이 적합하겠다.
- 적용 작업은 아래와 같다.
- 커스텀 인터셉터 작성하기
- struts.xml에 인터셉터 정의하여 적용하기
- 처리 프로세스 플로우차트 보기
[편집] 커스텀 인터셉터 작성하기
- // TODO 부분(2군데..)는 해당 애플리케이션에 맞게 작성해 주어야 하겠다.
- 첫번째는 proccessDeniedResponse() 메소드에 있으며, 마이플랫폼 메세지를 던져주는 부분이다.
- 두번째는 isLogined()메소드에 있으며, 세션상에 로그인 정보를 검사하는 부분이다.
- 소스 설명
- 인터셉터가 작동하는 메인 메소드는 intercept(ActionInvocation invocation) 메소드이다.
- 여기서 허용 URL인지, 로그인 했는지 검사하는 것과 요청을 거부하는 프로세스를 처리한다.
- excludeActions 변수는 로그인 했는지 검사하는 것에서 제외하기 위한 액션들이 있는 경우 사용한다.
- redirectWebPage 변수는 일반 웹 요청시 액션 수행 거부(로그인 하지 않음)에 대해 라디이렉트 할 페이지를 지정한다.
- 이와 마찬가지로 마이플랫폼 요청에 대한 거부 메세지도 파라미터화 하여 처리할 수 있겠다.
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>