はじめに
springframework.securityでのJWT実装サンプルです調べてみると、「難しい・分からない」みたいなコメントがたくさん出てくるので、まとめます
実際、ほかにもサンプルはあるのですが、コピペしても動かないことが多々あったのでサンプルの1つとしてどうぞまた、「難しい・分からない」を解消するために処理の流れも追っていきたいと思います
ソース
下記のソースをダウンロードしておいてください
必要なクラス群
- SecurityConfig
- springframework.securityのconfigを記載
- User
- springframework.securityの「UserDetails」の実装
- UserRepository
- UserモデルのRepository
- UserServiceImpl
- springframework.securityの「UserDetailsService」の実装
- JsonUsernamePasswordAuthenticationFilter
- ログイン処理をするフィルタ
- JWTAuthenticationSuccessHandler
- JWTを生成するハンドラ
- JWTAuthenticationFilter
- JWTを検証するフィルタ
- JWTProvider
- JWTの生成・検証の実装
JWT生成・検証の流れ
下記と照らし合わせて見ると分かりやすいと思います
JWT生成の処理
- ログインを行う
- 「SecurityConfig」のクラスの「configure」メソッドの「addFilterBefore」で指定した「UsernamePasswordAuthenticationFilter」メソッド内で定義された"/api/v1/web/login/"がJWT生成のURLです
- ログイン認証は「JsonUsernamePasswordAuthenticationFilter」クラスの「Authentication」メソッドで行われます
- 「Authentication」メソッド内の「authenticate」メソッドで「UserServiceImpl」クラスの「loadUserByUsername」メソッドが呼び出され、DBからUserに紐づくUserデータを取得し、パスワードの検証を行います また、ここで行われるパスワード検証は「SecurityConfig」クラスに定義した「passwordEncoder」メソッドのエンコーダーが使用されます
- ログイン成功後JWTを生成しクライアントに返す
- ログイン成功後「JWTAuthenticationSuccessHandler」クラスの「onAuthenticationSuccess」メソッドが呼び出され、「JWTProvider」クラスでJWTが生成され、クライアントに返します
JWT検証の処理
- ヘッダーからJWTを取得
- 「SecurityConfig」のクラスの「configure」メソッドで定義されている通りJWT生成以外の全てのリクエストは「USER」ロールを持っていないとアクセスすることが出来ません ロールを持っているかどうかのAuthenticationを「JWTAuthenticationFilter」で行います
- 「JWTAuthenticationFilter」クラスの「doFilter」メソッドが実行されます
- JWTの検証が行われ、DBからUserに紐づくUserデータを取得し「Authentication」にセットされます ここでセットされたロールが認証に使用されます
- 許可されているロールの場合、controller側へ処理が流れます
実際に叩く
以上。
参考文献
JWTによるREST APIのログインを実現する