Spring Boot/Spring Securityを使って、認証部分のカスタマイズについていろいろ調べてみた、ときの備忘録
というか、やってみたこと、というか、おぼえがき
認証全体の流れ
リクエストが来たら
- SecurityFilter/AuthenticationFilterを通って
- AuthenticationManagerがAuthenticationProviderを呼び出し、
- AuthenticationProviderがUserDetailsSerivceを呼び出し、
- UserDetailsSerivceが、UserDetailsを返す。
- 認証が成功すると、AuthenticationFilterが、AuthenticationSuccessHandlerを呼び出す
- 認証が失敗すると、AuthenticationFilterが、AuthenticationFailureHandlerを呼び出す
多いし複雑。。さらに、認証が行われると認証イベントが発生し、それもハンドリングできる。
データベース認証をカスタマイズしたい(UserDetailsSerivce+UserDetails)
以下の2つを用意すればOK
- UserDetailsを実装した資格情報を格納するクラス
- UserDetailsSerivceを実装したDBからUserDetailsを取得するクラス
前の記事でも書いているので省略。
wannabe-jellyfish.hatenablog.com
認証処理の前にリクエストをフィルタしたり、追加情報を使いたい(AuthenticationFilter)
- 認証処理に行く前に何かしたい場合は、AuthenticationFilterの実装をする
- form認証の場合、デフォルトではUsernamePasswordAuthenticationFilterが使われる
- UsernamePasswordAuthenticationFilterを拡張してゴニョゴニョするのがよい
public class MyUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { if (!request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } String username = obtainUsername(request); String password = obtainPassword(request); // このあたりでゴニョゴニョする。 UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password); // Allow subclasses to set the "details" property setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } }
@Override protected void configure(HttpSecurity http) throws Exception { // Java Configではこんな感じ http.addFilterAt(new MyUsernamePasswordAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); }
認証成功時の処理をカスタマイズしたい(AuthenticationSuccessHandler)
- AuthenticationSuccessHandlerを実装したクラスを使う
- デフォルトはForwardAuthenticationSuccessHandler?SavedRequestAwareAuthenticationSuccessHandler?のよう
- ForwardAuthenticationSuccessHandlerの実装はこんな感じ。authenticationを見て、遷移先とかをゴニョゴニョできる
public class ForwardAuthenticationSuccessHandler implements AuthenticationSuccessHandler { private final String forwardUrl; /** * @param forwardUrl */ public ForwardAuthenticationSuccessHandler(String forwardUrl) { Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl), "'" + forwardUrl + "' is not a valid forward URL"); this.forwardUrl = forwardUrl; } public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { request.getRequestDispatcher(forwardUrl).forward(request, response); } }
認証失敗時の処理をカスタマイズしたい(AuthenticationFailureHandler)
- AuthenticationSuccessHandlerを実装したクラスを使う
- デフォルトはForwardAuthenticationFailureHandler?SimpleUrlAuthenticationFailureHandler?のよう
- ForwardAuthenticationFailureHandlerの実装はこんな感じ。exceptionを見て、遷移先とかをゴニョゴニョできる
public class ForwardAuthenticationFailureHandler implements AuthenticationFailureHandler { private final String forwardUrl; /** * @param forwardUrl */ public ForwardAuthenticationFailureHandler(String forwardUrl) { Assert.isTrue(UrlUtils.isValidRedirectUrl(forwardUrl), "'" + forwardUrl + "' is not a valid forward URL"); this.forwardUrl = forwardUrl; } public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception); request.getRequestDispatcher(forwardUrl).forward(request, response); } }
以上!!
参考になる書籍

Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発
- 作者: 株式会社NTTデータ
- 出版社/メーカー: 翔泳社
- 発売日: 2016/07/21
- メディア: 大型本
- この商品を含むブログ (1件) を見る

- 作者: 掌田津耶乃
- 出版社/メーカー: 秀和システム
- 発売日: 2017/12/20
- メディア: 単行本
- この商品を含むブログを見る

- 作者: 掌田津耶乃
- 出版社/メーカー: 秀和システム
- 発売日: 2018/01/30
- メディア: 単行本
- この商品を含むブログを見る

はじめてのSpring Boot―スプリング・フレームワークで簡単Javaアプリ開発 (I・O BOOKS)
- 作者: 槙俊明
- 出版社/メーカー: 工学社
- 発売日: 2016/09/01
- メディア: 単行本
- この商品を含むブログ (1件) を見る
参考にしたサイト様
- Spring Boot で 認証機能を実装してみる - Qiita
- Spring Boot + Spring Securityでパスワードをハッシュ化(ソルト付、ストレッチングあり) - Qiita
- UserDetailServiceでカスタムPrincipalをつくる | Laboratory | R-SQUARE.net
- Spring Security Reference
- SpringSecurityで独自テーブルを使って認証を行う - Webサービスで起業を目指すプログラマーblog
- 6.3. 認証 — TERASOLUNA Global Framework Development Guideline 1.0.0.publicreview documentation
- Spring Securityを適用するときの作業メモ - なみひらブログ
- Spring Bootで入力値の検証 - かずきのBlog@hatena
- DaoAuthenticationProvider (Spring Security 4.1.3.RELEASE API)
- Spring Boot/ログインエラーのメッセージをカスタマイズする - ポケットがチケットでいっぱい
- 4.1. 入力チェック — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.2.0.RELEASE documentation
- Localization of Spring Security Error Messages in Spring Boot - codecentric AG Blog
- JavaEE7をはじめよう(23) - Bean Validationの基本 - エンタープライズギークス (Enterprise Geeks)
- BeanValidationの組み込みアノテーション - シュンツのつまづき日記
- AuthenticationException (Spring Security 4.0.3.RELEASE API)
- Spring Security 4.1 主な変更点 - Qiita
- Spring Security - ORMを使った認証 - Qiita
- Spring Boot Securityを使ってみる - Qiita
- Spring Security 使い方メモ 認証・認可 - Qiita
- How to represent the Spring Security "custom-filter" using Java configuration? - Stack Overflow
- テックノート – spring security 認証処理を自作する方法を解説
- Spring Boot でログイン画面 + 一覧画面 + 登録画面の Webアプリケーションを作る ( その10 )( ログイン画面作成3 ) - かんがるーさんの日記