|
@@ -1,18 +1,73 @@
|
|
|
[[servlet-authentication-form]]
|
|
|
= Form Login
|
|
|
+:figures: images/servlet/authentication/unpwd
|
|
|
+:icondir: images/icons
|
|
|
|
|
|
Spring Security provides support for username and password being provided through an html form.
|
|
|
This section provides details on how form based authentication works within Spring Security.
|
|
|
// FIXME: describe authenticationentrypoint, authenticationfailurehandler, authenticationsuccesshandler
|
|
|
|
|
|
-[[servlet-authentication-form-min]]
|
|
|
-== Form Login Configuration
|
|
|
+Let's take a look at how form based log in works within Spring Security.
|
|
|
+First, we see how the user is redirected to the log in form.
|
|
|
+
|
|
|
+.Redirecting to the Log In Page
|
|
|
+image::{figures}/request-credentials.png[]
|
|
|
+
|
|
|
+The figure builds off our <<servlet-securityfilterchain,`SecurityFilterChain`>> diagram.
|
|
|
+
|
|
|
+image:{icondir}/number_1.png[] First, a user makes an unauthenticated request to the resource `/private` for which it is not authorized.
|
|
|
+
|
|
|
+image:{icondir}/number_2.png[] Spring Security's <<servlet-authorization-filtersecurityinterceptor,`FilterSecurityInterceptor`>> indicates that the unauthenticated request is __Denied__ by throwing an `AccessDeniedException`.
|
|
|
+
|
|
|
+image:{icondir}/number_3.png[] Since the user is not authenticated, <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>> initiates __Start Authentication__ and sends a redirect to the log in page with the configured <<servlet-authentication-authenticationentrypoint,`AuthenticationEntryPoint`>>.
|
|
|
+In most cases the `AuthenticationEntryPoint` is an instance of {security-api-url}org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.html[`LoginUrlAuthenticationEntryPoint`].
|
|
|
+
|
|
|
+image:{icondir}/number_4.png[] The browser will then request the log in page that it was redirected to.
|
|
|
+
|
|
|
+image:{icondir}/number_5.png[] Something within the application, must <<servlet-authentication-form-custom,render the log in page>>.
|
|
|
+
|
|
|
+[[servlet-authentication-usernamepasswordauthenticationfilter]]
|
|
|
+When the username and password are submitted, the `UsernamePasswordAuthenticationFilter` authenticates the username and password.
|
|
|
+The `UsernamePasswordAuthenticationFilter` extends <<servlet-authentication-abstractprocessingfilter>>, so this diagram should look pretty similar.
|
|
|
+
|
|
|
+.Authenticating Username and Password
|
|
|
+image::{figures}/usernamepasswordauthenticationfilter.png[]
|
|
|
|
|
|
+The figure builds off our <<servlet-securityfilterchain,`SecurityFilterChain`>> diagram.
|
|
|
+
|
|
|
+
|
|
|
+image:{icondir}/number_1.png[] When the user submits their username and password, the `UsernamePasswordAuthenticationFilter` creates a `UsernamePasswordAuthenticationToken` which is a type of <<servlet-authentication-authentication,`Authentication`>> by extracting the username and password from the `HttpServletRequest`.
|
|
|
+
|
|
|
+image:{icondir}/number_2.png[] Next, the `UsernamePasswordAuthenticationToken` is passed into the `AuthenticationManager` to be authenticated.
|
|
|
+The details of what `AuthenticationManager` look like depend on how the <<servlet-authentication-unpwd-storage,user information is stored>>.
|
|
|
+
|
|
|
+image:{icondir}/number_3.png[] If authentication fails, then __Failure__
|
|
|
+
|
|
|
+* The <<servlet-authentication-securitycontextholder>> is cleared out.
|
|
|
+* `RememberMeServices.loginFail` is invoked.
|
|
|
+If remember me is not configured, this is a no-op.
|
|
|
+// FIXME: link to rememberme
|
|
|
+* `AuthenticationFailureHandler` is invoked.
|
|
|
+// FIXME: link to AuthenticationFailureHandler
|
|
|
+
|
|
|
+image:{icondir}/number_4.png[] If authentication is successful, then __Success__.
|
|
|
+
|
|
|
+* `SessionAuthenticationStrategy` is notified of a new log in.
|
|
|
+// FIXME: Add link to SessionAuthenticationStrategy
|
|
|
+* The <<servlet-authentication-authentication>> is set on the <<servlet-authentication-securitycontextholder>>.
|
|
|
+// FIXME: link securitycontextpersistencefilter
|
|
|
+* `RememberMeServices.loginSuccess` is invoked.
|
|
|
+If remember me is not configured, this is a no-op.
|
|
|
+// FIXME: link to rememberme
|
|
|
+* `ApplicationEventPublisher` publishes an `InteractiveAuthenticationSuccessEvent`.
|
|
|
+* The `AuthenticationSuccessHandler` is invoked. Typically this is a `SimpleUrlAuthenticationSuccessHandler` which will redirect to a request saved by <<servlet-exceptiontranslationfilter,`ExceptionTranslationFilter`>> when we redirect to the log in page.
|
|
|
+
|
|
|
+[[servlet-authentication-form-min]]
|
|
|
Spring Security form log in is enabled by default.
|
|
|
However, as soon as any servlet based configuration is provided, form based log in must be explicitly provided.
|
|
|
A minimal, explicit Java configuration can be found below:
|
|
|
|
|
|
-.Form Log
|
|
|
+.Form Log In
|
|
|
====
|
|
|
.Java
|
|
|
[source,java,role="primary"]
|
|
@@ -49,8 +104,6 @@ In this configuration Spring Security will render a default log in page.
|
|
|
Most production applications will require a custom log in form.
|
|
|
|
|
|
[[servlet-authentication-form-custom]]
|
|
|
-== Custom Log In Form
|
|
|
-
|
|
|
The configuration below demonstrates how to provide a custom log in form.
|
|
|
|
|
|
.Custom Log In Form Configuration
|