Struts 2権限の検証

32835 ワード

以前のStruts 2プロジェクトでは,再SitemeshのマスターページでStrutsのifタグを用いてセッション判定を行い,未登録のユーザがページを見ることができないようにしたが,これはview層でのみ行われ,未登録のユーザが直接アドレスバーにログインユーザが訪問できるアドレスを入力すれば,対応するactionは実行され,ユーザに見られないだけである.これは明らかによくないので,Struts 2の権限検証を検討した.Here i quote
権限の最も核心的なのはビジネスロジックで、具体的にどんな技術で実現すればずっと簡単です.  通常:ユーザーとロールは多対多関係を確立し、ロールとビジネスモジュールは多対多関係を構成し、権限管理は後者の関係にある.  権限のブロックは、システム要求量が大きい場合はStruts 2ブロックで行い、要求量が小さい場合はfilterに置くことができます.しかし、一般的には単段ブロックはまだ十分ではなく、より細粒度の権限制御を行うには、マルチレベルブロックが必要です.
    filter(フィルタ)とinterceptor(ブロッカー)の違いがよく分からずgoogleしました.[2]博文で紹介されています.
1、ブロッキングはjavaの反射メカニズムに基づいており、フィルタは関数コールバックに基づいている.  2、フィルタはservletコンテナに依存し、ブロッカーはservletコンテナに依存しない.  3、ブロッキングはactionリクエストにのみ機能し、フィルタはほとんどのリクエストに機能します.  4、ブロッカーはactionコンテキスト、値スタック内のオブジェクトにアクセスできますが、フィルタはできません.  5、actionのライフサイクルでは、ブロッキングは複数回呼び出すことができ、フィルタはコンテナの初期化時に1回しか呼び出されない.
    学習のために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の の 、プロジェクトの の なさ