セッションを使ったカスタム認証(フィルタ処理)

広告

認証が通っているかどうかの判別を各サーブレットにて同じ処理を記述していましたが、フィルタを利用して書き換えてみます。

保護の対象となっている各サーブレットに書かれている次の部分を分離します。

String target = request.getRequestURI();

HttpSession session = request.getSession(false);

if (session == null){
  /* まだ認証されていない */
  session = request.getSession(true);
  session.setAttribute("target", target);

  response.sendRedirect("/auth/Login");
}else{
  Object loginCheck = session.getAttribute("login");
  if (loginCheck == null){
    /* まだ認証されていない */
    session.setAttribute("target", target);
    response.sendRedirect("/auth/Login");
  }
}

認証が通っているかどうかの判別部分をフィルタとして分離し、各サーブレットが呼ばれる前に実行されるように変更します。フィルタを利用することで各サーブレットには認証に関する記述を行う必要がなくなります。

※フィルタについては『フィルタ』を参照して下さい。

フィルタを使ったクラスは次のようになります。

AuthFilter1.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.Filter;
import javax.servlet.FilterChain;

public class AuthFilter1 implements Filter{
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){
    try{
      String target = ((HttpServletRequest)request).getRequestURI();

      HttpSession session = ((HttpServletRequest)request).getSession();

      if (session == null){
        /* まだ認証されていない */
        session = ((HttpServletRequest)request).getSession(true);
        session.setAttribute("target", target);

        ((HttpServletResponse)response).sendRedirect("/auth/Login");
      }else{
        Object loginCheck = session.getAttribute("login");
        if (loginCheck == null){
          /* まだ認証されていない */
          session.setAttribute("target", target);
          ((HttpServletResponse)response).sendRedirect("/auth/Login");
        }
      }

      chain.doFilter(request, response);
    }catch (ServletException se){
    }catch (IOException e){
    }
  }

  public void init(FilterConfig filterConfig) throws ServletException{
  }

  public void destroy(){
  }
}

「doFilter」メソッドの引数は「ServletRequest」インターフェースと「ServletResponse」インターフェースのオブジェクトのため、キャストが必要である点に注意して下さい。

各サーブレットに書かれていた処理を、フィルタを継承したクラス内に記述しただけです。このフィルタを保護の対象となっているサーブレットに設定することで、各サーブレットは認証のことを意識しなくても自動的に認証の確認が行われることになります。

サンプルプログラム

認証部分をフィルタに分離したので、保護の対象となるサーブレットは次のように認証に関する部分は無くなります。

CustomAuth5.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class CustomAuth5 extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws IOException, ServletException{

    response.setContentType("text/html; charset=Shift_JIS");
    PrintWriter out = response.getWriter();

    out.println("<html>");
    out.println("<head>");
    out.println("<title>ユーザー認証テスト</title>");
    out.println("</head>");
    out.println("<body>");

    out.println("<p>テストページ1</p>");

    out.println("<p><a href=\"/auth/CustomAuth2\">テストページ2へ</a></p>");

    out.println("<p><a href=\"/auth/Logout\">ログアウト</a></p>");

    out.println("</body>");
    out.println("</html>");
  }
}

ほぼ同じ内容の「CustomAuth6」サーブレットを次のように作成します。

CustomAuth6.java

web.xmlファイルを次のように修正して下さい。

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4">

  <filter>
    <filter-name>AuthFilter</filter-name>
    <filter-class>AuthFilter1</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>AuthFilter</filter-name>
    <url-pattern>/CustomAuth1</url-pattern>
  </filter-mapping>

  <filter-mapping>
    <filter-name>AuthFilter</filter-name>
    <url-pattern>/CustomAuth2</url-pattern>
  </filter-mapping>

  <servlet>
    <servlet-name>CustomAuth1</servlet-name>
    <servlet-class>CustomAuth5</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>CustomAuth1</servlet-name>
    <url-pattern>/CustomAuth1</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>CustomAuth2</servlet-name>
    <servlet-class>CustomAuth6</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>CustomAuth2</servlet-name>
    <url-pattern>/CustomAuth2</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>Login</servlet-name>
    <servlet-class>Login2</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Login</servlet-name>
    <url-pattern>/Login</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>LoginCheck</servlet-name>
    <servlet-class>LoginCheck2</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>LoginCheck</servlet-name>
    <url-pattern>/LoginCheck</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>Logout</servlet-name>
    <servlet-class>Logout1</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>Logout</servlet-name>
    <url-pattern>/Logout</url-pattern>
  </servlet-mapping>
</web-app>

それでは一度サーブレットを再起動してから、ブラウザで「http://localhost:8080/auth/CustomAuth1」へアクセスして下さい。

カスタム認証

今までと同様にログイン画面へ誘導されます。

データベースに登録されているユーザー名「itou」とパスワード「itou」と値を入力してから「login」ボタンをクリックして下さい。

カスタム認証

リンクがはってある「CustomAuth2」サーブレットにもフィルタは設定されていますが、今度は認証が通っていますのでそのまま表示されます。

カスタム認証

これで完成です。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。