by Hippo2000(2000/6/2)
Apache::AuthDBIモジュールなのです。
なおこのドキュメントはCPAN-Searchで出てきたドキュメント(PODを変換したもの)を日本語に訳そうとしたものです。わかりにくい部分は本物を見てください。(^^;;
原本の著作権はEdmund Mergl 氏がお持ちです。
Edmund Mergl さんにはメールで了解をいただきました。なお内容等が間違っていたら修正します。ご連絡ください。
Apache::AuthDBI - PerlのDBIを介した認証(Authentication) と 認定(Authorization)
# httpd.conf または startup.plでのコンフィグレーション :
PerlModule Apache::AuthDBI
# .htaccessでの認証(Authentication) と 認定(Authorization) :
AuthName DBI AuthType Basic
PerlAuthenHandler Apache::AuthDBI::authen PerlAuthzHandler Apache::AuthDBI::authz
PerlSetVar Auth_DBI_data_source dbi:driver:dsn PerlSetVar Auth_DBI_username db_username PerlSetVar Auth_DBI_password db_password #DBI->connect($data_source, $username, $password)
PerlSetVar Auth_DBI_pwd_table users PerlSetVar Auth_DBI_uid_field username PerlSetVar Auth_DBI_pwd_field password # 認証(Authentication): SELECT pwd_field FROM pwd_table WHERE uid_field=$user PerlSetVar Auth_DBI_grp_field groupname # 認定(Authorization): SELECT grp_field FROM pwd_table WHERE uid_field=$user
require valid-user require user user_1 user_2 ... require group group_1 group_2 ...
AuthType はBasicに限られます。1つまたは複数の適切なrequire行を使うことができます。認証(Authentication)ハンドラを使うだけであれば、'valid-user'を要求したり、'user user_1 user_2 ...'を要求する1行のrequire行で十分です。
このモジュールはPerlのDBIを使ってデータベースによる 認証(Authentication) と 認定(Authorization) 可能にします。サポートされているDBIドライバについては以下を参照してください。
http://www.symbolstone.org/technology/perl/DBI/
認証(Authentication):
与えられたユーザ名に対して、パスワードはキャッシュで検索されます。もしキャッシュがコンフィグされていなかったり、ユーザがキャッシュに見つからなかったり、与えられたパスワードがキャッシュされたパスワードとマッチしなければ、データベースから要求されます。
もしユーザ名が存在せず、authoritativeディレクティブが'on'に設定されていれば、そのリクエストは拒絶されます。authoritativeが'off'に設定されていれば、制御は次の行にあるモジュールに渡されます。
もし与えられたユーザ名に対するデータベースからのパスワードが空で、nopasswdディレクティブが'off'に設定されていれば、そのリクエストは拒絶されます。nopasswdが'on'に設定されていればパスワードは受け入れられます。
最後にそのパスワード(ユーザID毎に複数のパスワードが許されています)がデータベースから取り出されます。その結果は環境変数REMOTE_PASSWORDSに設定されます。そして与えられたパスワードと比較されます。encryptedディレクティブが'on'に設定されていれば、与えられたパスワードは比較の前にPerlのcrypt()関数を使って暗号化されます。encryptedディレクティブが'off'に設定されていれば、平文のままパスワードが比較されます。
この比較が失敗したら、そのリクエストは拒絶され、そうでなければそのリクエストは受け入れられ、環境変数REMOTE_PASSWORDに設定されます。
パスワードを取り出すために使われるSQL-selectは以下のようになります:
SELECT pwd_field FROM pwd_table WHERE uid_field = user
pwd_whereclauseがあれば、SQL-selectに付加されます。
このモジュールはさらに簡単なログ機能をサポートしています。log_stringがコンフィグされていれば、ハンドラが呼ばれたときにはいつでもlog_fieldがlog_stringで更新されます。log_stringには−データベースにもよりますが−TODAYのようなマクロが使えます。
ログ機能で使われるSQL-selectは以下のようになります:
UPDATE pwd_table SET log_field = log_string WHERE uid_field =
user
認定(Authorization):
認定(Authorization) ハンドラが呼ばれるときには、認証(Authentication) は既に行われています。つまり、与えられたユーザ名/パスワードは確認されています。
ハンドラは1行ずつ要求事項を解析し処理します。1つの要求事項を満たせば、リクエストは受け入れられます。
'valid-user' の場合、リクエストは受け入れられます。
1つまたは複数のユーザ名の場合、それらは与えられたユーザ名とをマッチするものがあるまで比較されます。
1つもしくは複数のグループ名の場合、与えられたユーザめいのすべてのグループがキャッシュから検索されます。キャッシュがコンフィグされていないか、ユーザがキャッシュに見つからなければ、もしくは要求されたグループがキャッシュされたグループにマッチしなければ、グループはデータベースから要求されます。これらすべてのグループのカンマ区切りのリストが環境変数REMOTE_GROUPSに設定されます。そしてこれらのグループが要求されたグループと最初にマッチするまで比較されます。
マッチせず、authoritativeディレクティブが'on'に設定されていれば、リクエストは拒絶されます。
認定(Authorization)が成功した場合には、環境変数 REMOTE_GROUPにグループ名が設定されます、これはデータベースに再びアクセスすることなくユーザスクリプトで使うことができます。
グループを取り出すために使われるSQL-selectは以下のようになります(grp_tableがあるかないかに依存します):
SELECT grp_field FROM pwd_table WHERE uid_field = user SELECT grp_field FROM grp_table WHERE uid_field = user
グループ情報は、メインのユーザテーブルや、もしユーザとグループの間にm:nの関係があれば特別なテーブルに保持することもできます。選択されたすべてのグループのカンマ区切りのリストが作成されると、それは要求されたグループと比較されます。正規化されたグループのレコードが好きでなければ、単独のグループの代りにgrp_fieldに(空白なしで)そうしたカンマ区切りのリストを設定することができます。
もしgrp_whereclauseがあれば、SQL-selectに付加されます。
キャッシュ:
このモジュールではすべてのパスワード/グループのために、オプションのキャッシュを保持します。キャッシュを有効にする方法についてはメソッド setCacheTime(n) をご覧下さい。各サーバは独自のキャッシュを持ちます。オプションでキャッシュを共有メモリセグメントに設定させることもできます。こうすることによりすべてのサーバで共有することができます。共有メモリの使用を有効にする方法については「コンフィグレーション」セクションをご覧下さい。
無期限にキャッシュを大きくさせないために、CleanupHandlerを初期設定させることができます。これはキャッシュを拾い読み、古くなったものをすべて削除します。クライアントへの応答時間を遅くしないよう、リクエストのたびに応答を送った後で実行されます。CleanupHandlerが2回続いて実行される最小の時間をコンフィグすることができます(「コンフィグレーション」セクションをご覧下さい)。デフォルトは0で、この場合、CleanupHandlerは各リクエストの後に実行されます。
data_source の値の書き方は'dbi:driver:dsn'です。このパラメータは処理のため、connectの時にデータベース・ドライバに渡されます。 data_source パラメータ(username 、 password パラメータも一緒に) は、複数のdata_sourceをチルダ('~') 区切りのリストにしたものにすることもできます。これら3つの要素の組み合わせが接続がうまくいくまで使われます。こうして複数のバックアップ・サーバを設定することができます。data_sourceの代りに環境変数DBI_DSNを使いたいのであれば、このパラメータには何も設定してはいけません。
username引数はconnectの際にデータベース・ドライバに渡されます。このパラメータはチルダ('~')で 区切られたリストにすることもできます。リストの使い方については、上記data_sourceパラメータをご覧下さい。
password 引数はconnectの際にデータベース・ドライバに渡されます。このパラメータはチルダ('~')で 区切られたリストにすることもできます。リストの使い方については、上記data_sourceパラメータをご覧下さい。
少なくともユーザ名と(暗号化されているかもしれない)パスワードを持っているフィールドを持ちます。ユーザ名はユニークでなければなりません。
Auth_DBI_pwd_tableでユーザ名が入っているフィールド名。
Auth_DBI_pwd_tableでパスワードが入っているフィールド名。
SQL-selectにさらに制約を指定するためには、このオプションを使います。
少なくともユーザ名とグループ名を持っているフィールドを持ちます。
Auth_DBI_grp_tableでグループ名が入っているフィールド名。
SQL-selectへさらに制約を指定するためにこのオプションを使います。
Auth_DBI_pwd_tableでログ文字列がはいったフィールド名。
Auth_DBI_pwd_tableのAuth_DBI_log_fieldを更新する文字列。'TODAY'のようなマクロにできるかどうかはデータベースに依存します。
デフォルトは'on'。'on'に設定されると、認証(Authentication)メソッドが失敗すると、失敗しても通すということがなくなります。このディレクティブが'off'に設定されていると、他の認証(Authentication)モジュールに制御が渡されます。'off'に切り替えることを決定するさいには、何をしているのかわかっているかを確認してください。
デフォルトは'off'。'on'に設定されるとデータベースから取り出されたパスワードが空だったときにパスワードの比較が飛ばされます。つまりどんなパスワードも許します。空のAuth_DBI_pwd_fieldがでたらめなパスワードでログインしようとする人たちを許さないようにするため、デフォルトでは'off'です。'onに切り替えることを決定するさいには、何をしているのかわかっているかを確認してください。
デフォルトは'on'。'on'に設定されているとき、データベースから取り出されたパスワードは暗号化されているものと見なされます。そのため与えられたパスワードは比較の前に暗号化されます。このディレクティブが'off'に設定されているとき、入力されたパスワードは平文で直接比較が行われます。
与えられたパスワードを暗号化するとき、AuthDBI はデフォルトではデータベースから選択されたパスワードを暗号化されたもの(salt)として使います。このパラメータに'userid'を設定すると、このモジュールはユーザIDを暗号化されたものとして使います。
デフォルトは'on'。'off'に設定すると、入力されたユーザIDは小文字に変換されます。同様にパスワードのselectステートメントでのユーザIDも小文字に変換されます。
デフォルトは'on'。'off'に設定すると、入力されたパスワードは小文字に変換されます。
デフォルトは'off'。'on'に設定すると、selectステートメントはユーザ名(username)のためのプレースホルダを使うように準備(prepare)されます。このメソッドをサポートしているデータベースにとっては、パフォーマンスを向上させるかもしれません。
このモジュールはApacheデーモンの起動時にロードされなければなりません。以下の行をhttpd.confに追加してください。
PerlModule Apache::AuthDBI
一般的な使い方はStartup.fileでPerlRequireディレクティブによってロードすることです。例としてeg/startup.plをご覧下さい。
3つのコンフィグレーションがあり、それはサーバ特有で、startup.fileでおこなうことができます:
Apache::AuthDBI->setCacheTime(0);
これはキャッシュのなかのエントリのための生存期間を秒で設定します。デフォルトは0で、これはキャッシュを切ります。n>0である値を何か設定すると、すべてのユーザのパスワード/グループが少なくともn秒はキャッシュされます。リクエストが終わった後、特殊なハンドラがキャッシュを拾い読みし、古くなったエントリ(CacheTimeよりも古くなったエントリ)をすべて削除します。
Apache::AuthDBI->setCleanupTime(-1);
これは連続した2つのCleanupHandlerの実行、これによりキャッシュからすべての古くなったエントリが削除されます、の間の最小時間を秒で設定します。デフォルトはすべてのリクエストの後にCleanupHandlerを実行します。-1はCleanupHandlerを使わないようにします。
インターバルが0に設定されている負荷が高くかかったサーバには、これをある値に設定するべきです。おそらくは多くの古くなってしまったエントリを持った巨大なキャッシュをスキャンするか、エントリが少ししかないキャッシュに何回もCleanupHandlerを実行するかの折衷案が、その値に反映されます。
Apache::AuthDBI->initIPC(50000);
これはキャッシュのために共有メモリを使用することを可能にします。各サーバにが独自のキャッシュを維持する代りに、すべてのサーバが共通のキャッシュにアクセスするようにします。これは多くのサーバを実行しているサイトでのデータベース・ロードを考えられうる限り最小化します。この大きさは固定で、より多くのセグメントを動的な占有しません。見積もられる同時にキャッシュされるユーザの最大数に100を掛けるという単純な掛け算のルールに従えば、必要な大きさの大まかな見積もりを取得できます。値が500よりも小さければデフォルトの50000で上書きされます。
デバッグを可能とするためには$Apache::AuthDBI::DEBUGを設定しなければなりません。これはstartup.plでもユーザのスクリプトでもどちらでも可能です。1に設定すると、単に新しい接続について報告されます。2に設定すると、すべてのデバッグ出力が可能になります。
このモジュールはmod_perl-1.08以上、apache_1.3.0以上を必要とします。そしてmod_perlは適切なコールバック・フックでコンフィグされている必要があります:
PERL_AUTHEN=1 PERL_AUTHZ=1 PERL_CLEANUP=1 PERL_STACKED_HANDLERS=1
場合によっては、.htaccessファイルにユーザ名とパスワードを書かないほうがセキュリティが高くなります。以下の例ではこの問題の解決方法を示しています:
httpd.conf:
<Perl>
my($uid,$pwd) = My::dbi_pwd_fetch();
$Location{'/foo/bar'}->{PerlSetVar} = [
[ Auth_DBI_username => $uid ],
[ Auth_DBI_password => $pwd ],
];
</Perl>
The Apache::AuthDBI module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
ご意見、ご質問はこちらの掲示板で受け付けています。
またメールは河馬屋(Nifty)にお願いします。