リンク ユーザガイド リファレンス Tomcat開発 |
| クイックスタート |
この文書は、ユーザ名、パスワード、ユーザロールが登録されている"データベース"へ接続して動作する、
Tomcatにおけるコンテナ管理のセキュリティを利用するための設定方法について説明しています。
<security-constraint> 要素や<login-config> 要素といった、
ユーザがどのように認証されるかを設定する要素を1つ以上含むWebアプリケーションを使う方だけが気をつけて読んで下さい。
これらの機能を利用しないのであれば、この文書を読み飛ばしても大丈夫です。
コンテナ管理のセキュリティに関する基本的な情報については、
Servlet 仕様書(バージョン2.3)
の第12節を参照してください。
管理者やWebアプリケーション開発者のための入門レベルの文書は、
(未解決 -コンテナ管理のセキュリティに関する情報へのリンクを提供すること)
を参照してください。
Tomcat 5 における統一ログイン[Single Sign On]
(バーチャルホスト内で連携するWebアプリケーション全体を一度の認証でユーザが利用できるようになる)機能の使用方法に関する情報については、
こちらを参照してください。
|
| 概要 |
| レルムとは? |
レルムとは、ユーザ名とパスワードの組み合わせのように、
Webアプリケーション(複数のWebアプリケーションのまとまりの場合もあります)
のユーザを一意に定めるための"データベース"と、
認証された各ユーザに付与されているロールの一覧を列挙するものの両方を合わせたものを指します。
ロールは、Unix系のオペレーティングシステムにおけるグループ
のようなものだと考えてもらってもいいでしょう。
特定のWebアプリケーションリソースへのアクセスは、
(リソースへ関連づけられたユーザ名の一覧を列挙することによってではなく)
ある特別なロールを持つユーザ全員に与えられます。
場合によってユーザは、ユーザ名に紐付くロールをいくつでも持つことができます。
(web.xml、つまり配備記述子に)
セキュリティ要件を宣言することによるアプリケーションのための可搬性の高い機構をサーブレット仕様書では説明していますが、
サーブレットコンテナと関連付けられたユーザとロール情報との間のインタフェースを定義する可搬性の高いAPIはありません。
しかしながら多くの場合、認証用データベースまたは製品環境に付属する認証機構とサーブレットコンテナとの"接続"が必要となります。
そのためTomcat 5では、Javaのインタフェース(org.apache.catalina.Realm)を定義しています。
このインタフェースは、こういった接続を確立するための"プラグイン"コンポーネントに実装されれば良く、
異なる認証情報ソースへの接続をサポートする以下の4つの標準プラグインが現在提供されています:
- DataSourceRealm -
リレーショナルデータベースに保存されている認証情報へアクセスします。
名前付けされた JNDI JDBCデータソースを使ってアクセスします。
- JDBCRealm -
リレーショナルデータベースに保存されている認証情報へアクセスします。
JDBCドライバを使ってアクセスします。
- JNDIRealm -
LDAPベースのディレクトリサーバに保存されている認証情報へアクセスします。
JNDIプロバイダを使ってアクセスします。
- MemoryRealm -
メモリ内のオブジェクト集合に保存されている認証情報へアクセスします。
このオブジェクト集合は、XML文書ファイル (
conf/tomcat-users.xml)を使って初期化されます。
もちろん、開発者は独自にRealm を実装することができますし、
それをTomcat 5 と統合することもできます。
しかしながらその方法を説明することはこの文書の範疇を越えています。
詳細については、(未解決 - 開発スタッフ用リファレンス)を参照してください。
|
|
| 標準レルム実装 |
| JDBCレルム |
はじめに
JDBCレルム は、Tomcat 5 の
Realm インタフェースの実装のうちの1つです。
この実装は、JDBCドライバがアクセスするリレーショナルデータベースからユーザを見つけ出します。
データベース構造が次のような要件を満足しさえすれば、
既存の表の列名との対応づけにより、
十分柔軟な設定をすることができます:
- 以下のユーザ表のように参照可能な表が必要です。
この表には、この
Realmが認識すべき有効な各ユーザに対して1つの行を持ちます。
- ユーザ表は少なくとも2つの列を持たなければなりません。
(アプリケーションに必要な他の列があってもかまいません):
- ユーザログイン時にTomcatがユーザ名として認識する列
- ユーザログイン時にTomcatがパスワードとして認識する列。
この値は、平文あるいはダイジェスト暗号化されたものを指定してください。 - 後述の情報を参考にしてください
- ユーザロール表として参照可能な表が必要です。
この表は、特定のユーザに割り当てられる有効な各ロールに対して1つの行を持ちます。
あるユーザが有効なロールを持たなくても、1つだけ持っても、1つ以上持ってもかまいません。
- ユーザロール表は少なくとも2つの列を持たなければなりません。
(アプリケーションに必要な他の列があってもかまいません):
- Tomcatがユーザ名と認識する列 (
ユーザ 表の対応する列と同じ値を持つ)。
- ユーザに付与された有効なロール名を持つ列
クイックスタート
JDBCレルムを使用するようにTomcatを設定するためには次の手順に従ってください:
- データベースに表をまだ作成していない場合は、前述した条件を満たす列を持つ表を作成します。
- Tomcatが利用するデータベースのユーザ名とパスワードを設定します。
少なくとも、前述した表への検索アクセスが可能でなければなりません。
(これらの表の更新をTomcatがすることはありません。)
- JDBCドライバのコピーを
$CATALINA_HOME/server/libディレクトリ内へ置きます
(もしWebアプリケーションへ見せる必要がない場合)。
あるいは$CATALINA_HOME/common/libへ置きます
(Tomcat 5 と自作アプリケーションの両方によって使用したい場合)。
JARファイルだけが有効となることに注意してください。
$CATALINA_HOME/conf/server.xmlファイルに<Realm>
要素を追加してください。内容は、以下の記述に従ってください。
- Tomcat 5 が既に動作している場合はTomcat 5 の再起動をしてください。
Realm 要素の属性
JDBCレルムを設定するためには、前述の通りに
$CATALINA_HOME/conf/server.xmlファイルへ
<Realm>要素を記述します。この実装では次の属性がサポートされています:
| 属性 | 説明 |
|---|
className |
このレルムを実装するJavaの完全修飾クラス名。
ここには、"org.apache.catalina.realm.JDBCRealm"
を指定しなければなりません。
| connectionName |
JDBC接続をするために使用するデータベースユーザ名
| connectionPassword |
JDBC接続をするために使用するデータベースパスワード
| connectionURL |
JDBC接続をするために使用するデータベースのURL
| debug |
関連するロガーによってこのレルムで記録される詳細デバッグレベル。
数値が高いほどより詳細な出力を生成します。
指定がない場合の詳細デバッグレベルの初期値は零(0)です。
| digest |
平文でないパスワードを保存するために使用するダイジェストアルゴリズム。
java.security.MessageDigestクラスが受け付けるアルゴリズム名が有効です。
詳細については、
ダイジェストパスワード を参照してください。
指定されない場合、パスワードは平文で保存されているとみなします。
| driverName |
使用されるJDBCドライバの完全修飾クラス名。
JDBCドライバによって特有の値なので、そのマニュアルをよく調べてください。
| roleNameCol |
ユーザロール表の列名。
この列には、ユーザに付与されているロール名が入っている必要があります。
| userCredCol |
ユーザ表の列名。この列には、
対応するユーザのパスワードが入っている必要があります(平文、
もしくはdigest 属性が設定されている場合はダイジェストされた値)。
| userNameCol |
ユーザ表とユーザロール表の列名。
このユーザのユーザ名が入っている必要があります。
| userRoleTable |
特定のユーザ名と対応するロールを各行に保持する表の名前。
この表は少なくとも、
userNameCol とroleNameCol 属性で指定された列を持っている必要があります。
| userTable |
Tomcatによって認証されるユーザ名を各行に含む表名。
この表は少なくとも、userNameCol とuserCredCol属性で指定された列を持っている必要があります。
|
例
必要な表を作成するSQL スクリプトの例はここで示すようなものになります。
(使用するデータベースによって文法が若干異なります):
 |  |  |  |
create table users (
user_name varchar(15) not null primary key,
user_pass varchar(15) not null
);
create table user_roles (
user_name varchar(15) not null,
role_name varchar(15) not null,
primary key (user_name, role_name)
);
|  |  |  |  |
デフォルトの$CATALINA_HOME/conf/server.xml ファイルに、
(コメントアウトされていますが)Realm要素の例が記述されています。
ここでは、"authority"というMySQLのデータベースを使った一例を示します。
前述の通りに設定した表を用意し、ユーザ名"dbuser" とパスワード"dbpass"でアクセスしています:
 |  |  |  |
<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"
driverName="org.gjt.mm.mysql.Driver"
connectionURL="jdbc:mysql://localhost/authority?user=dbuser&password=dbpass"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
|  |  |  |  |
さらなる注意点
JDBCレルムは次の規則に従って処理をします:
- 保護されたリソースへのアクセスをユーザが初めて試みたときに、
Tomcat 5 はこの
Realmのauthenticate() メソッドを呼び出します。
従って、データベースディレクトリに対する変更(新しいユーザを追加したりパスワードやロールを変更するなど)は、
どんなものでも即座に反映されます。
- ユーザログインの持続のためユーザ(個人だけでなく付与されているロールも含めて)情報は、
一度認証されるとTomcatにキャッシュされます。
(FORM-based 認証においては、セッションの期限切れや無効化されるまでを意味します。
BASIC 認証においては、ユーザがブラウザを閉じるまでを意味します。)
すでに認証されたユーザに関するデータベースの情報に対するいかなる変更も、
ユーザが再度ログインするときまで反映されません。
- ユーザ表とユーザロール表に関する情報の管理については、
使用しているアプリケーションの責務になります。
ユーザとロールの保守をするための組み込み機能をTomcat は一切提供しません。
- この
Realm によって記録されるデバッグ用途と例外のメッセージは、
Context, Host, やEngineで囲まれて関連づけられた
Loggerによって行われます。
デフォルトでは、連携しているロガーは$CATALINA_HOME/logs
ディレクトリにログファイルを作成します。
|
| データソースレルム |
はじめに
データソースレルム はTomcat 5 の
Realm インタフェースの実装のうちの1つです。
この実装は、JNDI名を持つJDBCデータソースへのアクセスによって
リレーショナルデータベースからユーザを見つけ出します。
データベース構造が次のような要件を満足しさえすれば、
既存表の列名との対応づけにより十分柔軟な設定をすることができます:
- ユーザ表として参照可能な表が必要です。
この表には、この
Realmが認識可能で有効な各ユーザに対して1つの行を持ちます。
- ユーザ 表は少なくとも2つの列を持たなければなりません。
(アプリケーションに必要な他の列があってもかまいません):
- ユーザログイン時にTomcatがユーザ名として認識する列
- ユーザログイン時にTomcatがパスワードとして認識する列。
この値は、平文かダイジェスト暗号化されたものを指定してください。 - 後述の情報を参照にしてください
- ユーザロール 表として参照可能な表が必要です。
この表は、特定のユーザに割り当てられる有効な各ロールに対して1つの行を持ちます。
あるユーザが有効なロールを持たなくても、1つだけ持っても、1つ以上持ってもかまいません。
- ユーザロール 表は少なくとも2つの列を持たなければなりません。
(アプリケーションに必要な他の列があってもかまいません):
- Tomcatがユーザ名と認識する列 (
ユーザ 表の対応する列と同じ値を持つ)。
- ユーザに付与された有効なロール名を持つ列
クイックスタート
データソースレルムを使用するようにTomcatを設定するためには、次のステップに従ってください:
- まだデータベースに表を作成していない場合は、前述した条件を満たす列を持つ表を作成します。
- Tomcatが利用するデータベースのユーザ名とパスワードを設定します。
少なくとも、前述した表への検索アクセスが可能でなければなりません。
(これらの表の更新をTomcatがすることはありません。)
- JNDI名を持つJDBCデータソースとして対象のデータベースを設定します。
設定に関する詳細については、
JDBCデータソースを参照してください。
$CATALINA_HOME/conf/server.xmlファイルに
<Realm>要素を追加してください。
内容は、以下に記述するようにしてください。
- Tomcat 5 が既に動作している場合は再起動をしてください。
Realm 要素の属性
データソースレルムを設定するためには、前述の通りに
$CATALINA_HOME/conf/server.xmlファイルへ
<Realm>要素を記述します。この実装では次の属性がサポートされています:
| 属性 | 説明 |
|---|
className |
このレルムを実装するJavaの完全修飾クラス名。
ここには、"org.apache.catalina.realm.DataSourceRealm"
を指定しなければなりません。
| dataSourceName |
使用するデータベースに対するJNDIのJDBCデータソース名。
| debug |
関連するロガーによってこのレルムで記録される詳細デバッグレベル。
数値が高いほどより詳細な出力を生成します。
指定がない場合の詳細デバッグレベルの初期値は零(0)です。
| digest |
平文でないパスワードを保存するために使用するダイジェストアルゴリズム。
java.security.MessageDigestクラスが受け付けるアルゴリズム名が有効です。
詳細については、
ダイジェストパスワード を参照してください。
指定されない場合、パスワードは平文で保存されているとみなします。
| roleNameCol |
ユーザロール表の列名。
この列には、ユーザに付与されているロール名が入っている必要があります。
| userCredCol |
ユーザ表の列名。この列には、
対応するユーザのパスワードが入っている必要があります(平文、
もしくはdigest 属性が設定されている場合はダイジェストされた値)。
| userNameCol |
ユーザ表とユーザロール表の列名。
このユーザのユーザ名が入っている必要があります。
| userRoleTable |
特定のユーザ名と対応するロールを各行に保持する表名。
この表は少なくとも、
userNameCol とroleNameCol 属性で指定された列を持っている必要があります。
| userTable |
Tomcatによって認証されるユーザ名を各行に含む表名。
この表は少なくともuserNameCol とuserCredCol属性で指定された列を持っている必要があります。
|
例
必要な表を作成するSQL スクリプトの例はここで示すようなものになります。
(使用するデータベースによって文法が若干異なります):
 |  |  |  |
create table users (
user_name varchar(15) not null primary key,
user_pass varchar(15) not null
);
create table user_roles (
user_name varchar(15) not null,
role_name varchar(15) not null,
primary key (user_name, role_name)
);
|  |  |  |  |
ここでは、"authority"というMySQLのデータベースを使った一例を示します。
前述の通りに設定した表を用意して、
JNDI JDBC データソース名が"java:/comp/env/jdbc/authority"でアクセスしています:
 |  |  |  |
<Realm className="org.apache.catalina.realm.DataSourceRealm" debug="99"
dataSourceName="java:/comp/env/jdbc/authority"
userTable="users" userNameCol="user_name" userCredCol="user_pass"
userRoleTable="user_roles" roleNameCol="role_name"/>
|  |  |  |  |
さらなる注意点
データソースレルムは次の規則に従って処理をします:
- 保護されたリソースへのアクセスをユーザが初めて試みたときに、
Tomcat 5 はこの
Realmのauthenticate() メソッドを呼び出します。
従って、データベースディレクトリに対する変更(新しいユーザを追加したりパスワードやロールを変更するなど)は、
どんなものでも即座に反映されます。
- ユーザログインの持続のためユーザ(個人だけでなく付与されているロールも含めて)情報は、
一度認証されるとTomcatにキャッシュされます。
(FORM-based 認証においては、セッションの期限切れや無効化されるまでを意味します。
BASIC 認証においては、ユーザがブラウザを閉じるまでを意味します。)
すでに認証されたユーザに関するデータベースの情報に対するいかなる変更も、
ユーザが再度ログインするときまで反映されません。
- ユーザ表とユーザロール表に関する情報の管理については、
使用しているアプリケーションの責務になります。
ユーザとロールの保守をするための組み込み機能をTomcat は一切提供しません。
- この
Realm によって記録されるデバッグ用途と例外のメッセージは、
Context, Host, やEngineで囲まれて関連づけられた
Loggerによって行われます。
デフォルトでは、連携しているロガーは$CATALINA_HOME/logs
ディレクトリにログファイルを作成します。
|
| JNDIレルム |
はじめに
JNDIレルム はTomcat 5 の
Realm インタフェースの実装のうちの1つです。
この実装は、JNDIプロバイダ(典型的には、
JNDI API クラスで有効な標準LDAPプロバイダ)
によるアクセスによって、
LDAPディレクトリサーバからユーザを見つけ出します。
認証でディレクトリを利用するために、
このレルムは様々なアプローチをサポートします:
ディレクトリへの接続
レルムのディレクトリ接続はconnectionURL 設定属性によって定義されます。
JNDIプロバイダによって定義されるフォーマットのURLをここに指定します。
これは、ディレクトリサーバへ接続するためのドメイン名指定に通常使われるLDAP URL です。
ポート番号と、コンテキスト名となるルートの識別名(DN)もオプションで指定できます。
1つ以上のプロバイダがある場合はalternateURLを設定します。
connectionURLで指定されたプロバイダへのソケット接続ができない場合は、
alternateURLを使っての接続を試みます。
ディレクトリを検索してユーザとロールを取り出すための接続ができたら、
connectionNameとconnectionPassword
属性で指定されたユーザ名とパスワードを使ってディレクトリの認証をレルムは受けます。
これらの属性が指定されていない場合は匿名(anonymous)で接続が行われます。
ほとんどの場合、匿名接続で十分です。
ユーザのディレクトリエントリの選択
認証され得るそれぞれのユーザは、
個々のエントリによってディレクトリ内で表されなければなりません。
このエントリは、connectionURL
属性によって定義された初期DirContextの要素と一致します。
このユーザエントリは、
認証のために使われるユーザ名を含む属性を持っていなければなりません。
ユーザのエントリに対応する識別名(DN)は認証のために使われるユーザ名を含んでいますが、
すべてのユーザにとってユーザ名以外は同じである場合がほとんどです。
こういった場合は、
ユーザ名を表す部分を"{0}"とする特別な識別名(DN)をuserPattern属性に指定できます。
その他の場合レルムはディレクトリを検索し、
ユーザ名を持った唯一のエントリを見つけなければなりません。
次の属性はこの検索を制御します:
- userBase -
ユーザを含む部分木の開始点となるエントリ。
指定されなかった場合、
検索の出発点は最上位のコンテキストとなります。
- userSubtree - 検索範囲。
userBaseエントリを根とする部分木に対して検索したい場合に
trueを指定します。初期値はfalseで、
この場合は最上位のみを対象とする単一階層の検索を要求したことになります。
- userSearch -
LDAP検索フィルターのパターンを指定します。
このフィルターはユーザ名の後方一致で使用されます。
ユーザの認証
-
バインドモード
初期設定では、ユーザに対応するエントリーの識別名(DN)のディレクトリと、
ユーザが入力したパスワードとをバインドすることによってレルムはユーザを認証します。
この単純なバインドが成功した場合ユーザは認証されたとみなされます。
セキュリティ確保のため、平文よりも、
ダイジェスト化されたユーザパスワードをディレクトリへ保存するようにして下さい
(詳細はダイジェストパスワードを参照のこと)。
この場合、ユーザが入力した平文パスワードの正しいダイジェストを、
単純なバインド操作の一部としてディレクトリは自動的に計算します。
保存された値に対して検査をする前にこの計算は行われます。
このためバインドモードでは、レルムはダイジェスト処理に含まれません。
ダイジェスト 属性は使われず、設定しても無視されます。
-
比較モード
他の手段として、保存されたパスワードをディレクトリからレルムが検索し、
それとユーザが入力した値とを比較する方法があります。このモードは、
userPassword属性を指定することによって制御できます。
userPassword属性には、
パスワードを入れておくユーザエントリのディレクトリ属性の名前を指定します。
比較モードにはいくつか不便な点があります。
1つめは、ユーザのパスワードをディレクトリにおいてレルムが読み取るれように、
connectionName属性とconnectionPassword
属性を設定する必要があることです。
セキュリティ確保のため、通常はこの指定をしません。代わりに多くのディレクトリ実装は、
ディレクトリ管理者であってもこれらのパスワードを読み込めないようにしています。
さらにレルムは、使用される様々なアルゴリズムとパスワードをハッシュする方法をディレクトリ内部に用意し、
パスワードダイジェスト化を自前で行わなければなりません。
しかしながら、保存されたパスワードへのアクセスが必要なときもレルムにはあるでしょう。
例えば、HTTPダイジェストアクセス認証(RFC 2069)のサポートのためといった場合です。
(ダイジェスト化されたパスワードをユーザ情報向けのリポジトリに保存しておく上述の方式とHTTPダイジェスト認証とは異なることに注意)
ユーザへのロールの割り当て
ディレクトリ内でロールを表す2つの方法をディレクトリレルムはサポートします:
ロールを指定する方式は両方とも組み合わせて使われます。
クイックスタート
JNDIレルムを使用するようにTomcatを設定するためには次のステップに従ってください:
- 上述した要件に合致する内容でディレクトリサーバが設定されているかを確認してください。
- 必要なら、Tomcatが使うユーザ名とパスワードを設定します。
前述したように読み込むためだけにその情報へアクセスします。
(Tomcat はこの情報を決して変更しようとしません。)
- 使用するJNDIドライバ(典型的にはJNDIを有効にする
ldap.jar)のコピーを、
(もしWebアプリケーションへ見せる必要がない場合は)
$CATALINA_HOME/server/lib ディレクトリ内へ置きます。
または、(Tomcat 5 と自作アプリケーションの両方によって使用したい場合は)
$CATALINA_HOME/common/lib ディレクトリ内へ置きます。
$CATALINA_HOME/conf/server.xmlファイルへ、
<Realm>要素を追加してください。
内容は、以下に記述されたように設定してください。
- Tomcat 5 が既に動作している場合は再起動をしてください。
Realm 要素の属性
JNDIレルムを設定するためには、前述の通りに
$CATALINA_HOME/conf/server.xmlファイルへ
<Realm>要素を記述します。
この実装では次の属性がサポートされています:
| 属性 | 説明 |
|---|
className |
このレルムを実装するJavaの完全修飾クラス名。
ここには、"org.apache.catalina.realm.JNDIRealm"
を指定しなければなりません。
| connectionName |
LDAP検索操作のためのディレクトリ接続を確立するときに使うディレクトリユーザ名。
指定されていない場合は匿名接続になります。
userPassword属性を指定しない限りは匿名接続で十分です。
| connectionPassword |
LDAP検索操作のためのディレクトリ接続を確立するときに使うディレクトリパスワード。
指定されていない場合は、匿名接続になります。
userPassword属性を指定しない限りは匿名接続で十分です。
| connectionURL |
ディレクトリへの接続を確立するときにJNDIドライバに渡される接続URL
| contextFactory |
この接続で使用されるJNDIコンテキストファクトリのJavaの完全修飾クラス名。
初期設定では、標準のJNDI LDAP プロバイダ
(com.sun.jndi.ldap.LdapCtxFactory)が使われます。
| debug |
関連するロガーによってこのレルムで記録される詳細デバッグレベル。
数値が高いほどより詳細な出力を生成します。
指定がない場合の詳細デバッグレベルの初期値は零(0)です。
| digest |
ユーザによって示された平文のパスワードへ適用されるダイジェストアルゴリズム。
ディレクトリから検索される値との比較より前に適用されます。
java.security.MessageDigestクラスが受け付けるアルゴリズム名が有効です。
詳細については、ダイジェストパスワード を参照してください。
指定されない場合は平文パスワードを検索するものとみなします。
userPassword が指定されない限り必要ありません。
| roleBase |
ロール検索実行の出発点となるディレクトリエントリです。
指定されない場合は、ディレクトリコンテキストの最上位の要素が使われます。
| roleName |
ロール検索によって見つけらるディレクトリエントリ内のロール名を持つ属性名です。
加えて、userRoleName プロパティも使えます。このプロパティは、
追加のロール名を持ったユーザエントリ内の属性名を指定します。
roleNameが指定されない場合ロール検索は行われず、
ユーザエントリからのみロールを取得することになります。
| roleSearch |
ロール検索の実行で使われるLDAPフィルタの式です。
java.text.MessageFormatクラスによってサポートされる構文に従います。
ユーザの識別子名(DN)を置き換えるには{0}を、
ユーザ名を置き換えるには{1}を使います。
指定されなかった場合ロール検索は行われず、
userRoleName属性によって指定されたユーザエントリにある属性からのみロールを取得します。
| roleSubtree |
ユーザに割り当てられたロールエントリをroleBase
属性によって指定された要素の部分木から検索したい場合は
trueを指定します。
初期設定値であるfalseは最上位からしか検索しないことになります。
| userBase |
userSearch式を使って実行されるユーザ検索のための出発点です。
指定されない場合は、ディレクトリコンテキストの最上位の要素が使われます。
userPattern式を使っている場合は指定しないでください。
| userPassword |
ユーザのパスワードを保存するユーザエントリの属性名。
この値が指定されない場合は、connectionNameとconnectionPassword
属性によって指定された値を使ってJNDIレルムはディレクトリをバインドします。
そして、認証中のユーザが指定したパスワード値と比較するため、
対応する属性を検索します。
digest属性が設定されている場合は、
指定されたダイジェストアルゴリズがユーザの入力したパスワードに適用されます。
これは、入力されたパスワードとディレクトリから検索された値との比較が行われる前に適用されます。
この値を指定しない場合JNDIレルムは、
ユーザのエントリの識別名(DN)とユーザによって指定されたパスワードを使ってディレクトリを単純にバインドしようとします。
認証されたユーザとして解釈されればバインドは成功します。
| userPattern |
ユーザのディレクトリエントリの識別名(DN)のためのパターン。
java.text.MessageFormatクラスによってサポートされる構文に従います。
実際のユーザ名が挿入される位置の印としては{0}を使います。
識別名(DN)がユーザ名を含み、かつ、識別名(DN)のうちユーザ名以外の部分が同じ場合は、
この属性をuserSearch、userSubtree、
userBaseの代わりに使うことができます。
| userRoleName |
ユーザに割り当てられたロール名を0個以上持つユーザディレクトリエントリの属性名。
ディレクトリ検索によって見つけられた個々のロールエントリから検索される属性名を指定するために、
roleName属性も一緒に使うことができます。
userRoleNameが指定されない場合は、
ユーザに割り当てられているロールすべてがロール検索から得られます。
| userSearch |
ユーザのディレクトリエントリに対する検索において使われるLDAPフィルター式。
実際のユーザ名が挿入される位置には{0}で印をつけます。
この属性は、ディレクトリからユーザエントリを検索するために、
userPatternの代わりに(userBaseと
userSubtree属性と一緒に)使います。
| userSubtree |
userBase属性によって指定された要素の部分木からユーザエントリを検索したい場合に
trueと指定します。初期設定値である
false は最上位からしか検索しないことになります。
userPattern式を使用する場合は指定しないでください。
|
例
ディレクトリサーバで特定のスキーマを作成することはこの文書の範囲を越えています。
なぜなら、それはディレクトリサーバの実装に依存するからです。
以下の例では、http://www.openldap.org
からダウンロード可能な、OpenLDAPディレクトリサーバ(2.0.11版以降)を使うことを前提とします。
また、(特に)slapd.conf ファイルは次のように設定されているものとします:
 |  |  |  |
database ldbm
suffix dc="mycompany",dc="com"
rootdn "cn=Manager,dc=mycompany,dc=com"
rootpw secret
|  |  |  |  |
connectionURLの指定にあたっては、
Tomcatが動作しているマシンと同じマシンでディレクトリサーバが動作しているものとします。
設定とJNDI LDAP プロバイダの使用に関する詳細については、http://java.sun.com/products/jndi/docs.html
を参照してください。
次に、このディレクトリサーバは、
(LDIFフォーマット形式で)次に示すような要素を実装しているものとします:
 |  |  |  |
# Define top-level entry
dn: dc=mycompany,dc=com
objectClass: dcObject
dc:mycompany
# Define an entry to contain people
# searches for users are based on this entry
dn: ou=people,dc=mycompany,dc=com
objectClass: organizationalUnit
ou: people
# Define a user entry for Janet Jones
dn: uid=jjones,ou=people,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: jjones
sn: jones
cn: janet jones
mail: j.jones@mycompany.com
userPassword: janet
# Define a user entry for Fred Bloggs
dn: uid=fbloggs,ou=people,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: fbloggs
sn: bloggs
cn: fred bloggs
mail: f.bloggs@mycompany.com
userPassword: fred
# Define an entry to contain LDAP groups
# searches for roles are based on this entry
dn: ou=groups,dc=mycompany,dc=com
objectClass: organizationalUnit
ou: groups
# Define an entry for the "tomcat" role
dn: cn=tomcat,ou=groups,dc=mycompany,dc=com
objectClass: groupOfUniqueNames
cn: tomcat
uniqueMember: uid=jjones,ou=people,dc=mycompany,dc=com
uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com
# Define an entry for the "role1" role
dn: cn=role1,ou=groups,dc=mycompany,dc=com
objectClass: groupOfUniqueNames
cn: role1
uniqueMember: uid=fbloggs,ou=people,dc=mycompany,dc=com
|  |  |  |  |
上記で説明した通りに設定されたOpenLDAP ディレクトリサーバのためのRealm
要素の例は次のようになります。
ここでは、ユーザはuid(例 jjones)を使ってアプリケーションへログインし、
ディレクトリ検索とロール情報の検索をするのには匿名接続で十分であるものとします:
 |  |  |  |
<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99"
connectionURL="ldap://localhost:389"
userPattern="uid={0},ou=people,dc=mycompany,dc=com"
roleBase="ou=groups,dc=mycompany,dc=com"
roleName="cn"
roleSearch="(uniqueMember={0})"
/>
|  |  |  |  |
この設定によりレルムは、userPatternをユーザ名へ置き換えて、
ユーザの識別名(DN)を決定します。
そして、この識別名(DN)とユーザから受け取ったパスワードをディレクトリへ渡して認証を行い、
ユーザのロールを確定するためにディレクトリを検索します。
ユーザは最近、ユーザIDよりもeメールアドレスの入力をログイン時に求められることが多くあります。
この場合レルムは、ユーザのエントリに対してディレクトリを検索しなければなりません。
(異なる組織単位や会社住所といった複数の部分木にユーザエントリがある場合も検索は必要です。)
そしてさらにグループエントリに加えて、
ロールを固定するためのユーザエントリの属性を使いたい場合もあるでしょう。
Janet Jones のエントリーは次のようになっているはずです:
 |  |  |  |
dn: uid=jjones,ou=people,dc=mycompany,dc=com
objectClass: inetOrgPerson
uid: jjones
sn: jones
cn: janet jones
mail: j.jones@mycompany.com
memberOf: role2
memberOf: role3
userPassword: janet
|  |  |  |  |
次のレルム設定は新しい要求を満たしています:
 |  |  |  |
<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99"
connectionURL="ldap://localhost:389"
userBase="ou=people,dc=mycompany,dc=com"
userSearch="(mail={0})"
userRoleName="memberOf"
roleBase="ou=groups,dc=mycompany,dc=com"
roleName="cn"
roleSearch="(uniqueMember={0})"
/>
|  |  |  |  |
ここで、Janet Jones が"j.jones@mycompany.com"でログインするとき、
これと同じmail属性の値を持つ唯一のエントリーをディレクトリからレルムが検索します。
そして、uid=jjones,ou=people,dc=mycompany,dc=com とパスワードでディレクトリの確定を試みます。
もし認証が成功したら、彼女には3つのロールが割り当てられます:
彼女のディレクトリエントリの"memberOf"属性の値である"role2" と"role3"、
そして、彼女が所属するグループのエントリにある"cn"属性の値である"tomcat"です。
最後に、ディレクトリからパスワードを検索し、
レルム内で内部的に比較を行うことによってユーザを認証するためには次のようにレルム設定を使います:
 |  |  |  |
<Realm className="org.apache.catalina.realm.JNDIRealm" debug="99"
connectionName="cn=Manager,dc=mycompany,dc=com"
connectionPassword="secret"
connectionURL="ldap://localhost:389"
userPassword="userPassword"
userPattern="uid={0},ou=people,dc=mycompany,dc=com"
roleBase="ou=groups,dc=mycompany,dc=com"
roleName="cn"
roleSearch="(uniqueMember={0})"
/>
|  |  |  |  |
しかしながらこれまで説明してきた通り、
初期設定されている認証のためのバインドモードを通常使います。
追加の注意点
JNDIレルム は次の規則に従って処理をします:
- 保護されたリソースへのアクセスをユーザが初めて試みたときに、
Tomcat 5 はこの
Realmのauthenticate() メソッドを呼び出します。
ディレクトリに対する変更(新しいユーザを追加したりパスワードやロールを変更するなど)は、
どんなものでもこれで即座に反映されます。
- ユーザログインの持続のために、
一度認証されるとユーザ(個人だけでなく付与されているロールも含めて)情報はTomcatにキャッシュされます。
(FORM-based 認証においては、セッションの期限切れや無効化されるまでを意味します。
;BASIC 認証においては、ユーザがブラウザを閉じるまでを意味します。)
すでに認証されたユーザに関するデータベースの情報に対するいかなる変更も、
ユーザが再度ログインするときまで反映されません。
- ディレクトリサーバー内の情報管理については使用しているアプリケーションの責務になります。
ユーザとロールの保守をするための組み込み機能をTomcat は一切提供しません。
- この
Realm によって記録されるデバッグ用途と例外のメッセージは、
Context, Host, やEngine
で囲まれて関連づけられたLogger によって行われます。
デフォルトでは、連携しているロガーは$CATALINA_HOME/logs
ディレクトリにログファイルを作成します。
|
| メモリレルム |
はじめに
メモリレルム は、
Tomcat 5 のRealm インタフェースの実装のうちの1つで、
簡単なデモンストレーションには利用できますが、製品での利用は想定されていません。
メモリレルムは、すべてのユーザに関する情報とユーザに対応するロールをXML文書から起動時に読み込みます
(デフォルトでは、この文書は$CATALINA_HOME/conf/tomcat-users.xmlから読み込まれます)。
このファイルを変更しても、Tomcatを再起動するまでは反映されません。
Realm 要素の属性
メモリレルムを設定するためには、
前述の通りに
$CATALINA_HOME/conf/server.xmlファイルへ
<Realm>要素を記述します。この実装では次の属性がサポートされています:
| 属性 | 説明 |
|---|
className |
このレルムを実装するJavaの完全修飾クラス名。
ここには、"org.apache.catalina.realm.MemoryRealm"
を指定しなければなりません。
| debug |
関連するロガーによってこのレルムで記録される詳細デバッグレベル。
数値が高いほどより詳細な出力を生成します。
指定がない場合の詳細デバッグレベルの初期値は零(0)です。
| digest |
平文でないパスワードを保存するために使用するダイジェストアルゴリズム。
java.security.MessageDigestクラスが受け付けるアルゴリズム名が有効です。
詳細については、
ダイジェストパスワード を参照してください。
指定されない場合、パスワードは平文で保存されているとみなされます。
| pathname |
有効なユーザ名とパスワードとロールを含むXML文書の絶対パス名または、
($CATALINA_HOMEに対する) 相対パス名。このファイルの形式に関する詳細は以下を参照して下さい。
指定されなかった場合は、conf/tomcat-users.xml が使われます。
|
ユーザファイル形式
ユーザファイル(デフォルトは, conf/tomcat-users.xml)は、
<tomcat-users>をルート要素とするXML文書でなければなりません。
ルート要素には、有効なユーザそれぞれに対応する<user>
要素を入れ子で指定できます。user要素は次の属性から構成されます。
- name - ユーザがログオンで使うユーザ名。
- password - ユーザがログオンで使うパスワード
(
<Realm> 要素にdigestが設定されていない場合は平文、
その他の場合はここ
で説明されているようなダイジェストされた値)。
- roles - このユーザに付与されたロール名一覧をカンマで区切って指定。
例
Tomcat 5 をインストールした直後はメモリレルムを使って設定されています。
このメモリレルムは<Engine> 要素内で指定しているので、
すべての仮想ホストとWebアプリケーションで有効です。
conf/tomcat-users.xml ファイルの初期内容は次の通りです:
 |  |  |  |
<tomcat-users>
<user name="tomcat" password="tomcat" roles="tomcat" />
<user name="role1" password="tomcat" roles="role1" />
<user name="both" password="tomcat" roles="tomcat,role1" />
</tomcat-users>
|  |  |  |  |
追加の注意点
メモリレルムは次の規則に従って処理をします:
- 起動したときTomcatはまず、定義されているユーザと関連する情報全てをユーザファイルから読み込みます。
ファイル内のデータを変更しても、Tomcatが再起動されるまで反映されません。
- 保護されたリソースへのアクセスをユーザが初めて試みたときに、
この
Realmのauthenticate() メソッドをTomcat 5 は呼び出します。
- ユーザログインの持続のためユーザ(個人だけでなく付与されているロールも含めて)情報は、
一度認証されるとTomcatにキャッシュされます。
(FORM-based 認証においては、セッションの期限切れや無効化されるまでを意味します。
;BASIC 認証においては、ユーザがブラウザを閉じるまでを意味します。)
- ユーザファイル内の情報管理については使用しているアプリケーションの責務になります。
ユーザとロールの保守をするための組み込み機能をTomcat は一切提供しません。
- この
Realm によって記録されるデバッグ用途と例外のメッセージは、
Context, Host, やEngine
で囲まれて関連づけられたLogger によって行われます。
デフォルトでは、連携しているロガーは$CATALINA_HOME/logs
ディレクトリにログファイルを作成します。
|
|
| 共通機能 |
| ダイジェストパスワード |
標準Realm 実装はいずれも、
(初期設定では)ユーザパスワードを平文で保存します。
多くの環境でこれは望ましくありません。
認証データを偶然見た人が、
ログオンを成功させるための十分な情報を集め、
他のユーザになりすますことができてしまいます。
この問題を回避するための一般解は、ユーザパスワードのダイジェスティング(digesting)
という概念を実装することです。
これは、(解読困難な形式で)コード化されたパスワードを保存することを可能にします。
また、コード化されてはいますが、Realm実装は認証のためにそれを利用できます。
保存されているパスワードを取り出し、
そのパスワードの値とユーザから提示された値との比較によって標準レルムが認証をするとき、
<Realm>要素のdigest属性を指定することでダイジェストパスワードを使うことができます。
この属性値は、
java.security.MessageDigest
クラスでサポートされるダイジェストアルゴリズム
(SHA, MD2, または MD5)のどれかでなければなりません。
このオプションを選択した場合Realmに保存されるパスワードの中身は、
指定したアルゴリズムによってダイジェスト化されたパスワードでなければなりません。
Realmのauthenticate()メソッドが呼ばれたとき、
ユーザによって指定された(平文の)パスワードは同じアルゴリズムによってダイジェスト化され、
Realmによって返された値とその結果を比較します。
この値が一致する場合は、
オリジナルパスワードの平文版はユーザによって提供されたものと同じである、
ということを意味します。
その結果、このユーザは認証されたことになります。
平文のパスワードからダイジェスト値を計算するために、2つの便利なテクニックがサポートされています:
上記のテクニックのどちらを使うにしても、
$CATALINA_HOME/server/lib/catalina.jar ファイルが必要です。
RealmBaseクラスを使用できるように、このファイルをクラスパスへ追加してください。
|
| マネージャアプリケーション |
インストールしたTomcat 5 の実行時にマネージャアプリケーション
を使ってアプリケーションの配備と配備解除をしたい場合は、
選択したレルム実装において、
少なくとも1つのユーザ名に対して"manager" ロールを付与しなければ*なりません*。
これは、マネージャWebアプリケーション自身がセキュリティ制約を使用するからです。
そのセキュリティ制約とは、
マネージャWebアプリケーション内の*どの*リクエストURIへのアクセスに対しても"manager"ロールを要求する、
というものです。
セキュリティ確保の理由から、初期設定されている
(すなわち、conf/tomcat-users.xmlを使う)
レルムには、"manager"ロールが付与されたユーザ名は1つもありません。
したがって、最低1人のユーザに対してTomcat管理者がこのロールを特別に付与するまでは、
このアプリケーションの機能を誰も使うことができません。
|
|
|