Play Framework を始めたばかりの方向けに、サンプルを進めるうえで困ったところを共有する目的で書いています。
Play Framework 2.8.x 、および play-pac4j v5.1 を使って、Cache にあるデータとの Authority check を実装した時のメモです。
以下、目次
できたこと
- Cache に認可用のデータ(本実装は typedID、および role)があるかどうかチェック処理
- 認可用データの更新時間と、サインインした時間との比較チェック処理
pac4j の認可機能ではだめだった理由
pac4j v5.1 で用意されている Default Authorizer は、
- Profile のもつ Role or Permission or Attribute
- Authorizer の持つ文字列
の2つを(String の Matcher で)比較チェックするタイプ。
また、pac4j の認可機能は、
Authorizer (認可判定部分)を Config に登録
-> Default Security Logic で、Config 登録された Authorizer を検索し呼び出す
といった流れになる。
本実装では、Authority に有効期間を設定し、期限切れであれば拒否したかった(かつ、有効期間は一定ではない)ので、 RequireAnyRoleAuthorizer 等は使えなかった。
大まかな設計内容
pac4j の認可機能の流れはそのままで、チェック部分だけ変更したかった(Security Logic には触りたくない)ので、 大きく、以下の2つを実装した。
- 認可用のデータを(本実装ではキャッシュから)取得する部分 (repository)
- 認可判定時に、データを都度取得するよう呼び出す部分 (authorizer)
認可用のデータを(本実装ではキャッシュから)取得する部分 (repository)
認可用データを取得する部分を、関数自体を定義・渡す ことで、都度取得させている
trait AuthorityRepository { def getTypedIdRoleAndUpdateAtMap: ResourceId => TypedIdRoleAndUpdateAtMap }
認可判定時に、データを都度取得するよう呼び出す部分 (authorizer)
class RequireAnyNewerRole
の引数を遅延評価する
ことで、 Config に登録しても認可判定時に都度データ取得させている。
class RequireAnyNewerRole( allowedTypeIdRoleAndUpdateMap: => TypedIdRoleAndUpdateAtMap ) extends ProfileAuthorizer
なお、認可用データの更新時間と、サインインした時間との比較チェック処理は、 Role
でやっている。
参考にしたところ
以上でした。