会社でplayframework認証ライブラリのSilhouetteを使ったので雑にまとめ。
実装は公式のExample見ればだいたい行ける。
https://www.silhouette.rocks/docs/examples
Silhouetteでできること
- パスワード認証
- OAuth認証
- Cookie/bearer/basic
Identity
- 認証対象となる存在
- 例えばユーザなど
- 認証用のユニークな識別子を保つ必要がある
- User name, emailなど
- 実装上は
Identity
というマーカートレイトをモデルに継承させる - その上でモデルに
LoginInfo
型のプロパティをもたせる- わざわざモデルに持たせないでも、他に方法があるらしいがこれが一番楽っぽい
Identity Service
- Identityの永続化を担保する
- 言ってしまえばidentity用のrepositoryみたいなもの
- IdentityServiceトレイトを継承し、retrieveメソッドをオーバーライドする
Authenticator
- 認証方式を設定・決定するオブジェクト
- Cookieやbearerなど色々ある
- https://www.silhouette.rocks/docs/authenticator#section-list-of-authenticators
- 各認証方式のpros/consがまとめられてていい
- 具体的な設定
Authenticator Service
- Authenticatorと協調して動作し、tokenの作成、リクエストへの埋め込みなどをおこなう
- 実装はもともと用意されているので自分で実装する必要はない
- ただ永続化のためのキャッシュ層などの設定は行う必要がある
- AuthenticatorRepositoryを与える
BearerTokenAuthenticatorService
- リクエストからbearer tokenを抜き出してそれをAuthenticatorRepositoryから探し、ログインしているかどうかを判断してくれる
- Secureなルートへのフックされる認証を行う
- 成功した場合はlogin infoを返す
AuthInfo
- パスワードやOAuthで使用するtokenなどの認証情報を表す
- パスワードの場合はハッシュ化されたパスワード、ハッシュ方法などが記録される
Provider
- リクエストからの認証情報の読み取り、及び認証操作を担保する
CredentialsProvider
- パスワードベースの認証を行う
- リクエストからの認証の抜き出しは行わずに、Credentialsを用意してauthenticateメソッドに渡すとAuthInfoRepositoryをベースにパスワード認証をこなってくれる
AuthInfoRepository
- AuthInfoを永続化する
Environment
- Silhouetteが用いる認証設定をまとめたオブジェクト
- IdnetityService、AuthenticatorService、Seq(RequestProvider)、EventBusを与えて初期化する
- RequestProviderはなくてもいい
- EnvironmentがアプリケーションにDIされて一連の認証が暗黙的に行われる
Secureなルートへのアクセスの認証手順
- Authenticator serviceがヘッダーなどからtokenを取得する
- Tokenがキャッシュに存在する場合は認証を成功させる
- AuthenticatorSerivceでの認証が失敗した場合に、自前で定義したRequest Providerがある場合はそちらでの認証操作を定義する
Sign Upの流れ
- identifierからlogin infoを作成する
- Login infoから既にあるかもしれないidentityを取得する
- 存在した場合は既に存在するユーザなのでsign upを失敗させる
- 存在しない場合は登録作業を行う
- パスワードをハッシュ化する
- identifierがかぶっていない場合は登録を行う
- Login infoと紐付けてハッシュ化したパスワードを保存する
- Login infoからtokenを作成する
Sign inの流れ
- identifierとpasswordの組み合わせをCredentialsProviderが認証する
- credentialsからlogin infoを作成
- Login infoに紐付いたパスワードを取得
- 取得したパスワードをアンハッシュし生のパスワードと比較
- 認証が成功したらlogin infoを返す
- Login infoをもとにIdentity ServiceからIdentityをretrieve
- Identityが存在すればlogin infoからtokenを作成し、キャッシュに保存
- Identityが存在しない場合は認証が失敗する