Spring Security を理解する

Spring Security を一度しっかり理解しておこうかと思って。

やってみたこと

Springは色々と便利な機能がある反面、その設定だとか動き方だとかが良くも悪くもブラックボックス化されています。数あるSpring関連のプロジェクトの中でも特に複雑&理解が難しいのがSecurityかな、と思いましてどうやって理解すればいいものかと考えていたところMannningからSpring Security in Actionが発売されたので読んでみました。

Manning Spring Security in Action

というわけで、とりあえず基本的なところだけをおさえてみたので、基本的な認証認可の流れをまとめておきます。

基本的な認証認可の流れ

Spring Securityの基本的な認証認可の流れはこんなかんじ。

  1. 認証を行うサーブレットフィルターがリクエストを受け取り、 AuthenticationManager に処理を委譲する。

  2. AuthenticationManagerAuthenticationProvider を使用し認証処理を行う。

  3. AuthenticationProviderUserDetailsServicePasswordEncoder を使って認証処理を行う。

  4. 認証に成功するとユーザ情報がSecurity Contextに保存される。

  5. 認可を行うサーブレットフィルターがリクエストの許可・拒否の判断を行う。

Authentication
Filter
Authentication...
<interface>
Authentication
Manager
<interface>...
<interface>
UserDetails
Service
<interface>...
<interface>
Password
Encoder
<interface>...
<interface>
Authentication
Provider
<interface>...
Filter
Filter
Filter
Filter
Request
Request
Security Context
Security Context
<interface>
UserDetail
<interface>...
Viewer does not support full SVG 1.1

ほとんどインターフェイスになっていますがこれはSpringの思想で、フレームワーク利用者が動作をカスタマイズできるようにするためですね。図ではインターフェイス間に依存があるように書きましたが、これは正確に言うと実装クラスによります。でも一般的には実装クラスにおいてこのような依存が発生することを想定してSpring Securityが作られているので、図の通りに理解しても問題ないと思います。

それぞれの役割はこんな感じ。

インターフェイス 役割

AuthenticationManager

認証情報をAuthenticationProviderに委譲する。

AuthenticationProvider

認証を行う。

UserDetailsService

UserDetailの管理を行う。(取得や保存など)

PasswordEncoder

パスワードのエンコード、突合を行う。

UserDetails

ユーザを表現する。

AuthenticationManagerは複数のAuthenticationProviderに問い合わせ、認証の種類に対応しているかを確認し、処理を委譲するという役割があります。図で示したようにAuthenticationProviderは複数存在することができます。これは、認証方法に応じて(ユーザ名とパスワードで認証するのか?トークンにより認証するのか?)AuthenticationProviderが存在するためです。AuthenticationManagerはそれらを束ねて管理し適切なAuthenticationProviderを呼び出す、という責任を持っています。

一般的にアプリケーションごとに独自に実装しなければならないのは、ユーザー情報を表すクラスと、それを取得する方法かなと思います。その他の処理についてはSpringSecurityがデフォルトで実装してくれているのでそれを使えば良さそう。PasswordEncoderについてもいくつも便利な実装が提供されているので特別なことをしなければならない場合を除いて提供されている実装を選択するだけになるかなと思いました。