最新の安定バージョンについては、Spring Security 6.4.2 を使用してください! |
フォームログイン
Spring Security は、html フォームで提供されるユーザー名とパスワードのサポートを提供します。このセクションでは、Spring Security 内でのフォームベース認証の動作について詳しく説明します。
フォームベースのログインが Spring Security 内でどのように機能するかを見てみましょう。まず、ユーザーがログインフォームにリダイレクトされる方法を確認します。
この図は、SecurityFilterChain
ダイアグラムから構築されています。
最初に、ユーザーが認可されていないリソース /private
に対して認証されていないリクエストを行います。
Spring Security の FilterSecurityInterceptor
は、認証されていないリクエストが AccessDeniedException
をスローすることによって拒否されたことを示します。
ユーザーが認証されていないため、ExceptionTranslationFilter
は認証の開始を開始し、構成された AuthenticationEntryPoint
を使用してログインページにリダイレクトを送信します。ほとんどの場合、AuthenticationEntryPoint
は LoginUrlAuthenticationEntryPoint
(Javadoc) のインスタンスです。
ブラウザーは、リダイレクト先のログインページをリクエストします。
アプリケーション内の何かで、ログインページをレンダリングする必要があります。
ユーザー名とパスワードが送信されると、UsernamePasswordAuthenticationFilter
はユーザー名とパスワードを認証します。UsernamePasswordAuthenticationFilter
は AbstractAuthenticationProcessingFilter を継承しているため、この図はかなり似ているはずです。
この図は、SecurityFilterChain
ダイアグラムから構築されています。
ユーザーがユーザー名とパスワードを送信すると、UsernamePasswordAuthenticationFilter
は HttpServletRequest
からユーザー名とパスワードを抽出して Authentication
の一種である UsernamePasswordAuthenticationToken
を作成します。
次に、UsernamePasswordAuthenticationToken
が AuthenticationManager
に渡され、認証されます。AuthenticationManager
がどのように見えるかの詳細は、ユーザー情報がどのように保存されているかによって異なります。
認証に失敗した場合、Failure
SecurityContextHolder はクリアされます。
RememberMeServices.loginFail
が呼び出されます。設定されていないことを覚えていれば、これはノーオペレーションです。AuthenticationFailureHandler
が呼び出されます。
認証が成功した場合は、Success .
SessionAuthenticationStrategy
に新しいログインが通知されます。認証は SecurityContextHolder に設定されます。
RememberMeServices.loginSuccess
が呼び出されます。設定されていないことを覚えていれば、これはノーオペレーションです。ApplicationEventPublisher
はInteractiveAuthenticationSuccessEvent
を公開します。AuthenticationSuccessHandler
が呼び出されます。通常、これはログインページにリダイレクトするときにExceptionTranslationFilter
によって保存されたリクエストにリダイレクトするSimpleUrlAuthenticationSuccessHandler
です。
Spring Security フォームログインはデフォルトで有効になっています。ただし、サーブレットベースの構成が提供されるとすぐに、フォームベースのログインを明示的に提供する必要があります。最小限の明示的な Java 構成を以下に示します。
Java
XML
Kotlin
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.formLogin(withDefaults());
// ...
}
<http>
<!-- ... -->
<form-login />
</http>
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
formLogin { }
}
// ...
}
この構成では、Spring Security はデフォルトのログインページをレンダリングします。ほとんどの本番アプリケーションでは、カスタムログインフォームが必要です。
以下の構成は、カスタムログインフォームを提供する方法を示しています。
Java
XML
Kotlin
public SecurityFilterChain filterChain(HttpSecurity http) {
http
.formLogin(form -> form
.loginPage("/login")
.permitAll()
);
// ...
}
<http>
<!-- ... -->
<intercept-url pattern="/login" access="permitAll" />
<form-login login-page="/login" />
</http>
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
formLogin {
loginPage = "/login"
permitAll()
}
}
// ...
}
ログインページが Spring Security 構成で指定されている場合、ページをレンダリングするのはユーザーの責任です。以下は、/login
のログインページに準拠する HTML ログインフォームを生成する Thymeleaf (英語) テンプレートです。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org">
<head>
<title>Please Log In</title>
</head>
<body>
<h1>Please Log In</h1>
<div th:if="${param.error}">
Invalid username and password.</div>
<div th:if="${param.logout}">
You have been logged out.</div>
<form th:action="@{/login}" method="post">
<div>
<input type="text" name="username" placeholder="Username"/>
</div>
<div>
<input type="password" name="password" placeholder="Password"/>
</div>
<input type="submit" value="Log in" />
</form>
</body>
</html>
デフォルトの HTML フォームにはいくつかの重要なポイントがあります。
多くのユーザーは、ログインページをカスタマイズする以上のことは必要ありません。ただし、必要に応じて、上記のすべてを追加の構成でカスタマイズできます。
Spring MVC を使用している場合は、GET /login
を作成したログインテンプレートにマップするコントローラーが必要になります。最小限のサンプル LoginController
を以下に示します。
Java
Kotlin
@Controller
class LoginController {
@GetMapping("/login")
String login() {
return "login";
}
}
@Controller
class LoginController {
@GetMapping("/login")
fun login(): String {
return "login"
}
}