OrmAuth - はじめに
Ormauth は、 Simpleauth と同様の機能を提供し、しかし、データを設定ファイルの代わりにデータベースへ保存する認証と承認のドライバのセットです。 データへは ORM モデルを通じてアクセスされます。
このほかに、Ormauth はまた追加機能が付属しています。 Simpleauth とは異なり、Ormauth はユーザーに直接割り当てられたロールと、 ユーザーおよびグループの両方に割り当てられたパーミッションをサポートした、遥かにきめ細かなパーミッションシステムが可能になっています。 ユーザーのメタデータはシリアライズされた配列では保存されませんが、独立したメタデータテーブル内に ORM の EAV 機能を使用し保存され、 ユーザーの他のプロパティと同様にメタデータにアクセスできるようになります。 また、さらなるセキュリティ対策として、前回のログイン時間を記録しログイン時にユーザに表示することがでます。
Auth のセットアップ
設定は、Ormauth ドライバを使用しようとしていることを Auth パッケージを伝えることから始まります。 これは auth.php 設定ファイルを介して行われます。 Auth パッケージにはデフォルトのファイルが提供されています。 任意の変更を加える前に、このファイルを app/config フォルダにコピーする必要があります。デフォルトのファイルは Simpleauth ドライバー用に構成されているので、それを変更する必要があります。この設定ファイルについての説明をここで見るけることができます。
上記の後に、パッケージをオートロードするかどうかを app/config/config.php の always_load セクションで指定します。
OrmAuth がデータベースへアクセスするために ORM を使用していることから always_load セクションに 'orm' パッケージを追加したことも確認してください!
ACL's
OrmAuth は SimpleAuth より遥かにきめ細かいACLシステムを持っています。 任意のユーザーのアクセスパーミッションセットを構築するために標準的な ORM の関係を使用しており、以下の特徴があります:
- すべてのユーザーはいずれかのメンバーであり厳密に一つでありグループである
- すべてのユーザーは 0 個以上のロールを割り当てられ持っている
- すべてのグループは 0 個以上のロールを割り当てられ持っている
- すべてのユーザーは 0 個以上のパーミッションを割り当て持つことができる
- すべてのグループは 0 個以上のパーミッションを割り当て持つことができる
- すべてのロールは 0 個以上のパーミッションを割り当て持つことができる
- すべてのパーミッションはパーミッション領域に属している
- すべてのパーミッションは 0 個以上の関連するアクションを持つことができる
すべてのパーミッションは、ユーザーごとに集約されます。ロールは割り当てられた集約パーミッションを変更することができる特別な パーミッションフィルタを持つことができます。これらは:
- "All access(すべてアクセス可)" は "A" として格納されている。このロールを持つユーザーはすべてのアクセス権を持っている。一般的には 'super-admin' のロールで使用される。すべてのアクセスパーミッションセットを却下する。
- "No access(アクセス不可)" は "D" として格納されている。このロールを持つユーザーはアクセスできません。一般的には 'banned' のロールで使用される。これは、すべてのアクセス許可セットを却下。
- "Revoke permissions(パーミッション取り消し)" は "R" として格納されている。パーミッションをロールに指定すると、集約されたパーミッションセットから削除される。
"revoked(取り消し)" パーミッションは他のすべてのパーミッションの前に検査されることに注意してください。これは「アプリケーションの極秘エリアを除き、 super-admin はすべてアクセス可」のようなパーミッション構造を作成することができます。
パーミッションの割り当ては非常に簡単で標準的な ORM を使用しています:
// $role_id で識別されるロールを取得
$role = \Model\Auth_Role::find($role_id);
// $perm_id で識別されるパーミッションを取得
$perm = \Model\Auth_Permission::find($perm_id);
// 2 つを関連付け
$role->permissions = $perm;
// そして、関連付けを保存
$role->save();
アクション
前述のように、パーミッションにアクションのリストを追加することによってさらなる粒度を追加することができます (領域とパーミッションの組み合わせ) 。
アクションは、パーミッションレコードに添字付き文字列型配列として格納され、 ORM によりシリアライズとアンシリアライズが自動的に行われます。 好きな文字列を選択し、あなたが望むように多くのアクションとして定義することができます。 必要であればフォーム上で一人ひとりのアクションに対するパーミッションを設定することができます。よりきめ細かく制御しようとすればこれも必要となるでしょう。
ユーザー、グループ、もしくはロールのどれかに対する権限を割り当てるときに、どの実行可能なアクションがパーミッションに指定することが可能か をアクションリストで定義します。割り当てられたアクションは、キーを持つ配列として格納されており、それがどのアクションが割り当てられているかを定義しています。
// 実行可能なアクションである場合:
array('add', 'view', 'edit', 'delete')
// 次に 'view' と 'edit' に割り当てる時に、これを保存する必要があります
array(1, 2)
これを保存するには、テーブルを通じて、もしくはリレーションシップへの直接アクセスのために提供されている ORM モデルで、ユーザーかロールもしくはグループのどれかをパーミッションと接続します。
// $role_id で識別されるロールを取得
$role = \Model\Auth_Role::find($role_id);
// $perm_id で識別されるパーミッションを取得
$perm = \Model\Auth_Permission::find($perm_id);
// アクションのサブセレクションを追加し 2 つを関連付け
$role->rolepermission[] = \Model\Auth_Rolepermission::forge(array(
'role_id' => $role->id,
'perms_id' => $perm->id,
'actions' => array(1,2),
));
// そして、関連付けを保存
$role->save();
アクセスを検査するときは次のいずれかで必要なアクセス権を指定します。一つの権利を検査したい場合は area.permission
、
一度に複数のパーミッションを検査したい場合は area.[permission,permission,...]
、
もし、関連するアクションを検査したい場合は、 area.permission[action,action,...]
を使用することができます。
これは AND チェックなので、複数の権限を指定した場合には、すべてにおいてアクセス許可が割り当てられている必要があります。
これは blog.comments[read,create,write,write-own,delete,delete-own]
ように構築しチェックすることができます。
キャッシュ
データベース I/O を軽減するために、 OrmAuth ドライバはすべてのページ要求でログインしているユーザのための完全なパーミッションセットを取得することを避けキャッシングを多用します。 OrmAuth の使用を開始する前に、キャッシュ設定がセットアップされていることを確認してください。
すべてのキャッシュエントリは OrmAuth 設定ファイルに定義されたプレフィックスを使用して作成されています。 これらは有効期限のタイムスタンプは指定せず作成されていますが、あなたの設計した管理バックエンドで、必ず必要となるキャッシュエントリを更新後に削除するので、キャッシュをリフレッシュすることができます。
次のキャッシュキーが OrmAuth で使用されます:
- <prefix>.groups - すべての定義されたグループの完全なリスト
- <prefix>.roles - すべての定義されたロールの完全なリスト
- <prefix>.permissions.user_<id> - ユーザー <id> の有効なパーミッション
パーミッションシステムの更新後にはキャッシュされたパーミッションをフラッシュするようにし、 そして、ロールまたはグループ定義のいずれかを変更した場合にも、同じくフラッシュします。
// キャッシュされているすべてのパーミッションをフラッシュ
\Cache::delete(\Config::get('ormauth.cache_prefix', 'auth').'.permissions');
// キャッシュされたすべてのグループをフラッシュ
\Cache::delete(\Config::get('ormauth.cache_prefix', 'auth').'.groups');
// キャッシュされたすべてのロールをフラッシュ
\Cache::delete(\Config::get('ormauth.cache_prefix', 'auth').'.roles');
// ユーザーごとのパーミッションをフラッシュする (id 12211 とともに)
\Cache::delete(\Config::get('ormauth.cache_prefix', 'auth').'.permissions.user_12211');
設定
Ormauth 認証システムは、設定ファイルを使用して構成されており、予想通り 'ormauth.php' を呼び出している。 Auth パッケージにはデフォルトのファイルが提供されています。 任意の変更を加える前には、app/config フォルダにこのファイルをコピーする必要があります。
下記の設定値が定義されています:
パラメータ | 型 | デフォルト | 説明 |
---|---|---|---|
db_connection | string |
|
利用するデータベース接続の名前。 db.php の config ファイルでの名称と一致させる必要があります。 null でデフォルトの DB インスタンスを使います。 |
table_name | string |
|
利用するユーザ情報を定義したテーブル名。 |
table_columns | array |
|
ユーザ情報のテーブルのうち、 select するカラムのリスト。 '*' で全カラムを select 。少なくとも、 'username', 'password', 'email', 'last_login', 'login_hash', 'group', 'profile_fields' を含んでいる必要があります。 |
cache_prefix | string |
|
ORM データをキャッシュする時に使用するキャッシュキーのためのプリフィックス。 |
guest_login | boolean |
|
true の場合には誰もログインしていない場合にダミーの 'guest' ユーザーが作成されます。 誰もログインしていない場合でさえグループと ACL のドライバを使用することが可能となります。 |
remember_me | array |
|
Ormauth の 'remember_me' 機能のための設定 |
multiple_logins | boolean |
|
true の場合、同一ユーザの複数の同時ログインが許可されています。 false の場合、ユーザーがログインしたときに以前のログインが取り消されます。 これを有効にすると、いくつかのログインセッションハイジャック対策が無効になることに注意してください! |
login_hash_salt | string |
|
OrmAuth で利用されるパスワードをよりセキュアにするために、パスワードのハッシュ値をデータベースに保存する際に、サルトが使われています。 デフォルトのものから、ランダムな文字列に変更することを忘れないように! パスワードのハッシュ化にあたり、 OrmAuth は非常にセキュアな機構である PBKDF2 を利用しています。 |
username_post_key | string |
|
ログインフォームのユーザ名を入力するフィールド名。 |
password_post_key | string |
|
ログインフォームのパスワードを入力するフィールド名。 |
'remember-me' 機能を使用したい場合は、記憶されるユーザ情報を格納するために暗号化されたクッキーを使用するため、有効な Crypt 設定を持っていることを確認してください。
データベーステーブル
OrmAuth はすべての情報を格納するためにかなりの数のテーブルに依存しています。 Auth パッケージにはこれらのテーブルを作成するために必要なマイグレーションファイルが含まれています。
oil refine migrate --packages=auth
を実行すればあなたのために作成されたテーブルを持つことができます。
例
これはログイン処理のサンプルです:
public function action_login()
{
$data = array();
// もし、あなたが送信ボタンを押下したならば、ステップを超えてへ行こう。
if (Input::post())
{
// 資格を確認。これは前述のテーブルが作成され、
// 上記のようにテーブルの定義および設定を使用していることが前提となります。
if (Auth::login())
{
// 認証情報は OK 、ただちに下記へ
Response::redirect('success_page');
}
else
{
// おっと!あなたにはあげれません。 再度ログインしてみてください。 username フィールドを再設定し、
// ビューに戻っていくつかのエラーテキストを与えるためにいくつかの値を設定します。
$data['username'] = Input::post('username');
$data['login_error'] = 'Wrong username/password combo. Try again';
}
}
// ログインフォームを表示
echo View::forge('auth/login',$data);
}