3.2. 認可制御実装用の機能¶
認可制御実装用の機能とは、ログインやグループ・メンバー・パーミッションなどの各認可情報を元に、
アクセス制御を実装するための機能です。 Auth
クラス にある、次のメソッドで構成されます。
ログインの判定 | |
メンバーの判定 | |
パーミッションの判定 | |
アクセス可能クエリー | |
ロールからグループ id を取得 | |
ユーザのグループ id を取得 | |
デコレータ用メソッド | |
ログインの判定 | |
メンバーの判定 | |
パーミッションの判定 | |
各種条件での判定 | |
リンク元による判定 |
これらを詳しく説明します。
3.2.1. 通常のメソッド¶
-
Auth.
is_logged_in
() → True/False¶ ログインしているかどうか判定します。
- 使用例
>>> auth.is_logged_in() True
- 戻り値
ログインしている場合は True を、していない場合は False を戻します。
-
Auth.
has_membership
([group_id, user_id, role]) → True/False¶ メンバーかどうかを判定します。グループ id 、ユーザ id 、ロールを指定できます。
- 使用例
>>> auth.has_membership(10) True >>> auth.has_membership(10, 5) False >>> auth.has_membership(user_id=5, role='test') True
- パラメータ
- group_id
グループの id を指定します。デフォルトは None です。ロールで指定する場合は、デフォルト値のままにします。
- user_id
ユーザの id を指定します。デフォルトは None です。 None の場合は現在のユーザの id で登録します。
- role
ロールを指定します。デフォルトは None です。グループ id で指定する場合は、デフォルト値のままにします。
パラメータを省略した場合、次のように動作します。
パターン 説明 user_id 省略 ログイン中のユーザidでメンバーを判定に使用します。 group_id 省略 role パラメータ指定がある場合はロールからグループidを検索し判定に使用します。 group_id / role 省略 パラメータが数字の場合はグループ id と判断し、判定に使用します。 パラメータが数字以外の場合はロールと判断し、ロールからグループidを検索し判定に使用します。
- 戻り値
メンバーの場合は True を、違う場合は False を戻します。
-
Auth.
has_permission
([name, table_name, record_id, user_id, group_id]) → True/False¶ パーミッションを所有しているかを判定します。パーミッション名、テーブル名、レコード id 、ユーザ id 、グループ id などを指定できます。
- 使用例
>>> auth.has_permission() True >>> auth.has_permission('read') True >>> auth.has_permission('create', 'comment') True >>> auth.has_permission('update', 'comment', 15) True >>> auth.has_permission('update', 'comment', 15, 5) False >>> auth.has_permission('read', group_id=7) False
- パラメータ
- name
パーミッション名を指定します。デフォルトは ‘any’ です。
- table_name
テーブル名を指定します。デフォルトは ‘’(空値)です。
- record_id
レコード id を指定します。デフォルトは 0 です。
- user_id
- ユーザ id を指定します。デフォルトは None です。user_id, group_id の指定が共に None の時は、現在のユーザ id を使用し判定します。
- group_id
グループ id を指定します。デフォルトは None です。
- 戻り値
登録したパーミッション id を戻します。
-
Auth.
accessible_query
(name, table, user_id) → Queryインスタンス¶ - パーミッション名、テーブル名、及びユーザ id から、 Query インスタンスを作成します。この機能は join や belongs を使用しているため、Google AppEngine(GAE)では動作しません。
- 使用例
>>> print db(auth.accessible_query('read', db.comment)).select(db.comment.text_area) comment.text_area test1 test2 test3 >>> print db(auth.accessible_query('update', db.comment)).select(db.comment.text_area) comment.text_area test2
- パラメータ
- name
パーミッション名を指定します。
- table
Table
インスタンスを指定します。- user_id
- ユーザ id を指定します。デフォルトは None です。None の場合は現在のユーザ id を使用し判定します。
- 戻り値
Query
インスタンスを戻します。
-
Auth.
id_group
(role) → グループ id¶ ロールから関連するグループ id を戻します。
- 使用例
>>> auth.id_group('test') 12
- パラメータ
- role
ロールを指定します。
- 戻り値
グループ id を戻します。
-
Auth.
user_group
(user_id) → ユニークグループ id¶ ユーザ id からグループ id を戻します。
- 使用例
>>> auth.user_group() 10 >>> auth.user_group(5) 5
- パラメータ
- user_id
- ユーザ id を指定します。デフォルトは None です。None の場合は現在のユーザ id を使用します。
- 戻り値
ユーザにユニークなグループ id を戻します。
このメソッドはユーザのユニークなグループ id を戻します。具体的にはロールが user_[id] で設定されるグループの id です。 このためユニークグループが存在しない場合は None を戻します。
create_user_groups
属性値が False の場合、ユーザ登録時にユニークグループは作成されません。
3.2.2. デコレータ用メソッド¶
以下のメソッドはデコレータとして使用します。
-
Auth.
requires_login
()¶ - ログイン状態を確認し、ログインしている場合は置き換えた関数を実行します。ログインしていない場合は、ログイン画面に遷移します。このメソッドは内部で、requires(True) を呼び出しています(
requires()
)。使用例
コントローラに作成した disp_profile 関数に、デコレータを設置します。これにより、disp_profile への アクセス時にはログインが要求されます。
@auth.requires_login() def disp_profile(): return dict(user=BEAUTIFY(auth.user), id=BEAUTIFY(auth.user_id))
- パラメータ
パラメータはありません。
-
Auth.
requires_membership
([role, group_id])¶ - ログインユーザがロール/グループのメンバーかどうか、判定します。メンバーに該当する場合、置き換えた関数を実行します。メンバーに該当しない場合、 権限不足表示 を表示します。またログインしていない場合、ログイン画面に遷移します。
このメソッドは内部で次のメソッドを呼び出しています(
requires()
及びhas_membership()
)。requires(lambda: self.has_membership(group_id=group_id, role=role))
使用例
コントローラに作成した disp_profile 関数に、デコレータを設置します。これにより、disp_profile への アクセスでは ‘manager’ ロールのメンバーであることが要求されます。
@auth.requires_membership('manager') def disp_profile(): return dict(user=BEAUTIFY(auth.user), id=BEAUTIFY(auth.user_id))
- パラメータ
パラメータに、ロール もしくは グループid を指定します。
- role
- ロールを指定します。デフォルトは None です。
- group_id
- グループid を指定します。デフォルトは None です。
-
Auth.
requires_permission
(name[, table_name, record_id])¶ - ログインユーザが、パーミッションを所持しているかどうか判定します。指定したパーミッションを所持している場合、置き換えた関数を実行します。パーミッションを所持していない場合、 権限不足表示 を表示します。またログインしていない場合、ログイン画面に遷移します。
このメソッドは内部で次のメソッドを呼び出しています(
requires()
及びhas_permission()
)。requires(lambda: self.has_permission(name, table_name, record_id))
使用例
コントローラに作成した disp_profile 関数に、デコレータを設置します。これにより、disp_profile への アクセスでは ‘auth_user’ テーブルに対する’read’ のパーミッションを、所持していることを要求されます。
@auth.requires_permission('read', auth.settings.table_user_name) def disp_profile(): return dict(user=BEAUTIFY(auth.user), id=BEAUTIFY(auth.user_id))
- パラメータ
パラメータに、パーミッション名を指定します。またオプションで、テーブル名やレコードidを指定できます。
- name
- パーミッション名を指定します。
- table_name
- テーブル名を指定します。デフォルトは ‘’(空文字列) です。
- record_id
- レコードidを指定します。デフォルトは 0 です。
-
Auth.
requires
(condition[, requires_login])¶ - 指定した条件に合致しているかどうか、判定します。条件に合致している場合、置き換えた関数を実行します。パーミッションを所持していない場合、 権限不足表示 を表示します。またログインしてなく、 requires_login が True(デフォルト値)の場合、ログイン画面に遷移します。
使用例
コントローラに作成した disp_profile 関数に、デコレータを設置します。これにより、disp_profile への アクセスでは 次の条件を要求されます。
ログインユーザのユーザidが 1 で、クライアントのIPアドレスが 127.0.0.1 の時
@auth.requires(auth.user_id==1 or request.client=='127.0.0.1') def disp_profile(): return dict(user=BEAUTIFY(auth.user), id=BEAUTIFY(auth.user_id))
ログインユーザが ‘Secret Agent’ ロールに属しており、アクセスする日が火曜日の時
@auth.requires(auth.has_membership(role='Secret Agent') and request.now.weekday()==1) def disp_profile(): return dict(user=BEAUTIFY(auth.user), id=BEAUTIFY(auth.user_id))
- パラメータ
パラメータに、条件を指定します。またオプション requires_login で、ログインが必要かどうかを指定できます。
- condition
- アクセス条件を指定します。 and/or などの論理演算子を利用し、複数条件の指定が可能です。
- requires_login
- ログインを要求する場合、True を指定します。デフォルトは True です。False を指定した場合、ログインは要求されません。
-
Auth.
requires_signature
()¶ - 認証されたリンクからのアクセスかどうかを判定します。認証されたリンクからのアクセスと判定した場合、置き換えた関数を実行します。正規のリンクからのアクセスではない場合、 権限不足表示 を表示します。またログインしていない場合、ログイン画面に遷移します。
このメソッドは内部で次のメソッドを呼び出しています(
requires()
)。requires(lambda: URL.verify(current.request,user_signature=True))
使用例
コントローラに作成した disp_profile 関数に、デコレータを設置します。これにより、disp_profile への アクセスでは 認証されたリンクからのアクセスを行うことを要求されます。
@auth.requires_signature() def disp_profile(): return dict(user=BEAUTIFY(auth.user), id=BEAUTIFY(auth.user_id))
認証されたリンクを作成するには、次のように URLを生成する URL関数に user_signature=True オプションをつけます。
>>> URL(a='myapp',c='default',f='disp_profile', user_signature=True) '/myapp/default/disp_profile?_signature=d529bedf85662f5fdab83b65edd18e691cc552ce'
生成したURLに、_signature 変数が付加されます。これは HMACにより生成された認証コード(ハッシュ値)です。このコードに合致するかどうかにより、認証されたリンクとそれ以外を判別します。- パラメータ
パラメータはありません。
- 注意点
- 認証コードが合致すればアクセスが許可されますが、呼び出し元の関数ではログインさせる必要があります。 呼び出し元でログインしていない場合、アクセス時にログイン画面が表示されますが、ログイン後に 権限不足表示 に遷移します。
- アプリケーション生成時に default.py の CRUD用の data関数には @auth.requires_signature() が設定されています。 data関数のコメントには、A(‘table’,_href=URL(‘data/tables’,user_signature=True)) とURLを生成すると記述していますが、これではアクセスできません。 URLパラメータに data/tables と記述するのではなく、次のようにパラメータ指定を行う必要があります。 A(‘table’,_href=URL(f=’data’,args=[‘tables’],user_signature=True)