TomcatのBasic認証を使って、「管理画面、会員用コンテンツ、公開コンテンツ」の三段階のアクセス管理を設定してみましょう。
※ちょっと設定を変えるとDIGEST認証にもなるよ。

■目次


ポイント

  • Basic認証を利用するには、まず「web.xml」で認証方式とアクセス制御を設定するURLと権限の設定をします。
  • その上で、認証するユーザー、ロール(役割、権限)の設定をTomcatに指定するために以下の設定が必要になります。
    • server.xml」でレルム(認証情報の取り扱い方法)の設定
      • 今回利用する「UserDatabeseRealm」はTomcatインストール時のデフォルト設定なので、設定を変更していななければ「server.xml」は編集する必要はありません。
    • tomcat-users.xml」でユーザーとロールの設定

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
 
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0">
 
<!-- 管理画面の定義 -->
<security-constraint>
  <!-- URLのパターン設定 -->
  <web-resource-collection>
    <web-resource-name>admin page</web-resource-name> 
    <url-pattern>/admin/*</url-pattern> 
  </web-resource-collection>
 
  <!-- アクセスを許可するロールの設定 -->
  <auth-constraint>
    <role-name>admin</role-name> 
  </auth-constraint>
 
  <!-- 通信方式 NONE=ノーガード INTEGRAL=改竄防止(https) CONFIDENTIAL=盗聴防止(https) -->
  <user-data-constraint>
    <transport-guarantee>NONE</transport-guarantee> 
  </user-data-constraint>
</security-constraint>
 
<!-- 会員用コンテンツの定義 -->
<security-constraint>
  <web-resource-collection>
    <web-resource-name>users page</web-resource-name> 
    <url-pattern>/users/*</url-pattern> 
  </web-resource-collection>
  <auth-constraint>
    <role-name>user</role-name> 
  </auth-constraint>
  <user-data-constraint>
    <transport-guarantee>NONE</transport-guarantee> 
  </user-data-constraint>
</security-constraint>
 
<!-- 認証方法の定義 -->
<login-config>
  <!-- Basic認証 -->
  <auth-method>BASIC</auth-method> 
  <!-- 認証ダイアログに表示されるエリア名的な何か -->
  <realm-name>security area</realm-name>
</login-config>
 
</web-app>
 
  • 今回はサーブレットを作成していないので、認証設定だけのweb.xmlです。
  • web.xmlでは主に、サーバクライアント間の認証方法と、アクセス制御するURLとロールの設定を行います。
  • <security-constraint>で、URLのパターン設定(複数可)、アクセスを許可するロールの設定(複数可)、通信方式の設定をしています。
    • 「/admin/*」で、adminディレクトリ配下全てがアクセス制御の対象となります。
    • httpsの設定は今回行なっていないので、通信方式はNONEを選択しました。
  • <login-config>で、認証方法とダイアログに表示されるエリア名を設定しています。
    • なんか微妙です。


web.xml DIGEST認証の場合

<!-- 認証方法の定義 -->
<login-config>
  <!-- DIGEST認証 -->
  <auth-method>DIGEST</auth-method> 
  <!-- 認証ダイアログに表示されるエリア名的な何か -->
  <realm-name>security area</realm-name>
</login-config>
 
  • 上記web.xmlの設定の<login-config><auth-method>をDIGESTに変更するだけで、DIGEST認証を利用出来ます。
    • Tomcat7はここを変えるだけで利用出来ますが、Tomcat5はレルム方式をメモリレルムにしないとDIGEST認証を利用出来ないそうです。


server.xmlの設定

(認証に関係のある要素を抜粋)※デフォルトなら編集不要
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
 
  <!-- JNDIリソースの設定 conf/tomcat-users.xmlを認証情報に利用します -->
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
 
  <Service name="Catalina">
 
    <Engine name="Catalina" defaultHost="localhost">
 
      <!-- ブルートフォースアタック対策にLockOutRealmでラップします -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- 認証に利用するクラスとリソースを設定 -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
 
    </Engine>
  </Service>
</Server>
 
  • server.xmlでは主に、サーバ内での認証情報(リソース)の取り扱いを設定します。
  • 上記の設定はTomcat7インストール時のデフォルト設定です。
    • デフォルトでUserDatabaseRealmを利用する場合、server.xmlは編集不要です。
  • 前段で「conf/tomcat-users.xml」からログインIDやパスワード等の認証に必要な情報を読取るJNDIリソースの設定。
  • 後段で、リソースの指定と認証に使うクラスの指定に分かれています。
  • ブルートフォースアタック対策のUserDatabaseRealmをブルートフォースアタック対策のLockOutRealmでラッピングしているのが印象的な設定です。


tomcat-users.xml

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
  <role rolename="admin"/>
  <role rolename="user"/>
  <user username="admin" password="password1" roles="admin,user"/>
  <user username="user1" password="password2" roles="user"/>
</tomcat-users>
 
  • ロールは管理者用のadminロールと、会員用のuserロールを作成します。
  • adminユーザーはadminロールとuserロール両方を設定。
  • user1ユーザーはuserロールのみ設定します。
  • 管理者を増やす時は、adminユーザーの設定をコピーしてusernameとpasswordをそれぞれ設定します。
  • ユーザーを増やす時も同様に、user1ユーザーの設定をコピーしてusernameとpasswordをそれぞれ設定します。

index.jsp サンプルダウンロード

  • サンプルをダウンロードして見てみてください。


Tomcatを起動してブラウザでusersディレクトリやadminディレクトリにアクセスすると、上のようなユーザー名とパスワードの入力を求めるダイアログが表示されます。

user1でログインしてadminディレクトリにアクセスすると403エラーになり、adminユーザーでログインすると全てのリソースにアクセスできます。

それぞれのユーザーのアクセス範囲

ログインしてない人のアクセス出来る範囲

/CONTEXT_ROOT
┣ public
┃┗ index.html
┗ index.html
  • ログインしてない人は、usersとadminディレクトリにはアクセス出来ません。
  • ルートのindex.htmlとpublicディレクトリの公開コンテンツのみにアクセス可能です。

会員のアクセス出来る範囲

/CONTEXT_ROOT
┣ public
┃┗ index.html
┣ users
┃┗ index.html
┗ index.html
  • ログインした会員は、adminディレクトリにはアクセス出来ません。
  • 公開コンテンツに加え会員用のusersディレクトリにアクセスが可能です。

管理者のアクセス出来る範囲

/CONTEXT_ROOT
┣ public
┃┗ index.html
┣ users
┃┗ index.html
┣ admin
┃┗ index.html
┗ index.html
  • ログインした管理者は、全てのリソースにアクセス出来ます。


ファイルの配置

/CONTEXT_ROOT
┣ WEB-INF
┃┗ web.xml
┣ public
┃┗ index.html
┣ users
┃┗ index.html
┣ admin
┃┗ index.html
┗ index.html
  • これらの他に、Tomcat自身の設定ファイルserver.xmlとtomcat-users.xmlも設定が必要です。


認証情報をサーブレットやJSPで取得する方法

  • ユーザー名 - HttpServletRequest#getRemoteUser
  • ロール - HttpServletRequest#isUserInRole("user")
    • ロールは直接ロールを取得する方法はなく、isUserInRoleでユーザーがそのロールを持っているかを確認します。

  • サーブレットの場合
// ユーザー名
String user = req.getRemoteUser();
// ロール
boolean isAdmin = req.isUserInRole("admin");

  • JSPの場合
// ユーザー名
String user = request.getRemoteUser();
// ロール
boolean isAdmin = request.isUserInRole("admin");
  • Tomcat7で動作確認していた感じでは、認証の必要なURLでないとユーザー名とロールは取得出来ないようです。
  • 認証の必要ないURLで認証情報を取り扱うには、セッション等に保存して置いたほうがいいかもしれません。

アンケート(このページの情報はお役に立ちましたか?)

順位 選択肢 得票数 得票率 投票
1 分かりにくい 9 (75%)
2 役に立った 3 (25%)
3 役に立たない 0 (0%)
4 間違っている 0 (0%)
その他
投票総数 12

他のTomcatサンプルはこちら


コメント(バグ、間違い、こんな情報が欲しい等ありましたら)

名前: