TERASOLUNA は Java の開発を助ける色々をまとめた総称です。この記事にでは TERASOLUNA のフレームワーク部で用いられているフォームリクエストによるパスワード認証処理(よくある ID とパスワードを入力して POST するアレ)の実装のフローを追います。
多様なシステムを短期間で構築するTERASOLUNA
Server Framework for Java|フレームワーク|TERASOLUNA
terasolunaorg/terasoluna-gfw-web-multi-blank: Blank multi project for web application using TERASOLUNA Server Framework for Java (5.x)
terasoluna.org 開発ガイドライン
開発ガイドラインにあるように TERASOLUNA では Spring Security をいくらか設定して用いています。これを追うことでどこに実装があるかを参照できます。
9.1. Spring Security概要 — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.3.0.RELEASE documentation
追う Spring Security のバージョンは 4.1 系です。この記事では 4.1.4 を参照します。
2.1. TERASOLUNA Server Framework for Java (5.x)のスタック — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.3.0.RELEASE documentation#2.1.2.5. セキュリティ
起点となるのは UsernamePasswordAuthenticationFilter です。
9.2. 認証 — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.3.0.RELEASE documentation
これの実装が次のコードです。
spring-security/UsernamePasswordAuthenticationFilter.java at 4.1.4.RELEASE · spring-projects/spring-security
次の部分で URL を定義し、このクラス中の attemptAuthentication が spring-security/AbstractAuthenticationProcessingFilter.java中で呼ばれることによって認証処理がスタートします(AbstractAuthenticationProcessingFilter より先は追ってませんが、おそらくリクエストに応じて各フィルターを通して処理を分けて……といった感じです)。
// UsernamePasswordAuthenticationFilter.java public UsernamePasswordAuthenticationFilter() { super(new AntPathRequestMatcher("/login", "POST")); }
attemptAuthentication では認証プロバイダーの管理者と管理者を介した認証プロバイダーが持つ認証処理が呼ばれます。認証プロバイダーの管理者はデフォルトでは ProviderManager であり、次が ProviderManager 中の認証処理で呼ばれるメソッドです。
spring-security/ProviderManager.java at 4.1.4.RELEASE · spring-projects/spring-security
このメソッドの中の次のループ中で認証処理が回され、認証に成功する時があればログインといった具合です。
for (AuthenticationProvider provider : getProviders()) { if (!provider.supports(toTest)) { continue; } if (debug) { logger.debug("Authentication attempt using " + provider.getClass().getName()); } try { result = provider.authenticate(authentication); if (result != null) { copyDetails(authentication, result); break; } }
認証プロバイダーの実体のデフォルトが DaoAuthenticationProvider です。少々ややこしいですが、↑のコードで呼ばれている authenticate メソッドは DaoAuthenticationProvider の親クラスの AbstractUserDetailsAuthenticationProvider 中の次のメソッドです。
spring-security/AbstractUserDetailsAuthenticationProvider.java at 4.1.4.RELEASE · spring-projects/spring-security
このメソッド中の次の部分で呼ばれる additionalAuthenticationChecks で DaoAuthenticationProvider がパスワード認証を行います。
try { preAuthenticationChecks.check(user); additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication); } catch (AuthenticationException exception) { if (cacheWasUsed) {
DaoAuthenticationProvider が次のメソッドの中で、あらかじめ applicationContext.xml で定義したパスワード処理クラスを使ってパスワードが正当かの結果を得て、認証処理完了です。
spring-security/DaoAuthenticationProvider.java at 4.1.4.RELEASE · spring-projects/spring-security
9.2. 認証 — TERASOLUNA Server Framework for Java (5.x) Development Guideline 5.3.0.RELEASE documentation#9.2.2.5.1. BCryptPasswordEncoder