Struts 2権限制御


References:『Struts 2のブロッカー(三)』[1],『FilterとInterceptorの違い』
    以前のStruts 2プロジェクトでは,再SitemeshのマスターページでStrutsのifタグを用いてセッション判定を行い,未登録のユーザがページを見ることができないようにしたが,これはview層でのみ行われ,未登録のユーザが直接アドレスバーにログインユーザが訪問できるアドレスを入力すれば,対応するactionは実行され,ユーザに見られないだけである.これは明らかによくないので,Struts 2の権限検証を検討した.
           ,               。 
  :            ,              ,          。 
      ,        ,   Struts2     ,        filter 。          ,            ,       。
  filter(フィルタ)とinterceptor(ブロッカー)の違いがよく分からずgoogleしました.[2]博文で紹介されています.
1、      java      ,            。 
2、      servlet  ,        servlet   。 
3、      action     ,                    。 
4、       action   、      ,       。 
5、 action      ,          ,                    。
    学習のために2つの実現方法を試してから、どれを使うかを決めます.
アクセス権検証のFilter実装:
Web.xmlコードクリップ
  <!-- authority filter     Struts2 Filter  -->
  <filter>
    <filter-name>SessionInvalidate</filter-name>
    <filter-class>filter.SessionCheckFilter</filter-class>
    <init-param>
      <param-name>checkSessionKey</param-name>
      <param-value>loginName</param-value>
    </init-param>
    <init-param>
      <param-name>redirectURL</param-name>
      <param-value>/entpLogin.jsp</param-value>
    </init-param>
    <init-param>
      <param-name>notCheckURLList</param-name>
      <param-value>/entpLogin.jsp,/rois/loginEntp.action,/entpRegister.jsp,/test.jsp,/rois/registerEntp.action</param-value>
    </init-param>
  </filter>
  <!--  /rois       action  -->
  <filter-mapping>
    <filter-name>SessionInvalidate</filter-name>
    <url-pattern>/rois/*</url-pattern>
  </filter-mapping>
  <!--  /jsp      jsp  -->
  <filter-mapping>
    <filter-name>SessionInvalidate</filter-name>
    <url-pattern>/jsp/*</url-pattern>
  </filter-mapping>
SessionCheckFilter.javaコード
package filter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
 *               ,     ,                 checkSessionKey       Session        
 * redirectURL        ,          ,URL    ContextPath notCheckURLList
 *      URL  ,     ,   URL      ContextPath
 */
public class SessionCheckFilter implements Filter {
  protected FilterConfig filterConfig = null;
  private String redirectURL = null;
  private Set<String> notCheckURLList = new HashSet<String>();
  private String sessionKey = null;
  @Override
  public void destroy() {
    notCheckURLList.clear();
  }
  @Override
  public void doFilter(ServletRequest servletRequest,
      ServletResponse servletResponse, FilterChain filterChain)
      throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    HttpSession session = request.getSession();
    if (sessionKey == null) {
      filterChain.doFilter(request, response);
      return;
    }
    if ((!checkRequestURIIntNotFilterList(request))
        && session.getAttribute(sessionKey) == null) {
      response.sendRedirect(request.getContextPath() + redirectURL);
      return;
    }
    filterChain.doFilter(servletRequest, servletResponse);
  }
  private boolean checkRequestURIIntNotFilterList(HttpServletRequest request) {
    String uri = request.getServletPath()
        + (request.getPathInfo() == null ? "" : request.getPathInfo());
    String temp = request.getRequestURI();
    temp = temp.substring(request.getContextPath().length() + 1);
    // System.out.println("    :"+uri+";"+notCheckURLList+"=="+notCheckURLList.contains(uri));
    return notCheckURLList.contains(uri);
  }
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    this.filterConfig = filterConfig;
    redirectURL = filterConfig.getInitParameter("redirectURL");
    sessionKey = filterConfig.getInitParameter("checkSessionKey");
    String notCheckURLListStr = filterConfig
        .getInitParameter("notCheckURLList");
    if (notCheckURLListStr != null) {
      System.out.println(notCheckURLListStr);
      String[] params = notCheckURLListStr.split(",");
      for (int i = 0; i < params.length; i++) {
        notCheckURLList.add(params[i].trim());
      }
    }
  }
}
パーミッション検証のInterceptor実装:
   Interceptorを使用すると、web.xmlを変更する必要はありません.struts.xmlを構成するだけです.
struts.xmlフラグメント
<!--              -->
    <interceptors>
      <!--        authority     -->
      <interceptor name="authenticationInterceptor" class="interceptor.AuthInterceptor" />
      <interceptor-stack name="defualtSecurityStackWithAuthentication">
        <interceptor-ref name="defaultStack" />
        <interceptor-ref name="authenticationInterceptor" />
      </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="defualtSecurityStackWithAuthentication" />
    <!--   Result -->
    <global-results>
      <result name="error">/error.jsp</result>
      <result name="login">/Login.jsp</result>
    </global-results>
    <action name="login" class="action.LoginAction">
      <param name="withoutAuthentication">true</param>
      <result name="success">/WEB-INF/jsp/welcome.jsp</result>
      <result name="input">/Login.jsp</result>
    </action>
    <action name="viewBook" class="action.ViewBookAction">
        <result name="sucess">/WEB-INF/viewBook.jsp</result>
    </action>
AuthInterceptor.javaコード
package interceptor;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class AuthInterceptor extends AbstractInterceptor {
  private static final long serialVersionUID = -5114658085937727056L;
  private String sessionKey="loginName";
  private String parmKey="withoutAuthentication";
  private boolean excluded;
  @Override
  public String intercept(ActionInvocation invocation) throws Exception {
    
    ActionContext ac=invocation.getInvocationContext();
    Map<?, ?> session =ac.getSession();
    String parm=(String) ac.getParameters().get(parmKey);
    
    if(parm!=null){
      excluded=parm.toUpperCase().equals("TRUE");
    }
    
    String user=(String)session.get(sessionKey);
    if(excluded || user!=null){
      return invocation.invoke();
    }
    ac.put("tip", "      !");
    //     login        
        return Action.LOGIN; 
  }
}
カスタムdefault-interceptorを使用する場合は、以下の点に注意してください.
1.Sturts 2にdefaultStackが付属していることを必ず引用してください.そうでないとStruts 2が持っているブロッキングは使えません.
2.あるパケットの下に上記のデフォルトのブロッキングスタックが定義されると、そのパケットの下にあるすべての Action アクセス権チェック機能が自動的に追加されます.だから永遠にログインできない場合があるかもしれません.
    :

1.        , action               ,   interceptor              

2.              Action         ,           Struts 2          ,          。
3.Interceptorはactionに対するブロックで、jspアドレスを知っていればURLバーにJSPのアドレスを直接入力すると、権限検証は効果がありません!
    :   page  (jsp)  WEB-INF  ,         “   ” 
最后に私のプロジェクトではまだfilterの実现方法を使っていますが、プロジェクトの変动は少ないですか~^^;