For the latest stable version, please use Spring Security 6.4.1!spring-doc.cn

Form Login

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.spring-doc.cn

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.spring-doc.cn

loginurlauthenticationentrypoint
Figure 1. Redirecting to the Log In Page

The figure builds off our SecurityFilterChain diagram.spring-doc.cn

number 1 First, a user makes an unauthenticated request to the resource /private for which it is not authorized.spring-doc.cn

number 2 Spring Security’s FilterSecurityInterceptor indicates that the unauthenticated request is Denied by throwing an AccessDeniedException.spring-doc.cn

number 3 Since the user is not authenticated, ExceptionTranslationFilter initiates Start Authentication and sends a redirect to the log in page with the configured AuthenticationEntryPoint. In most cases the AuthenticationEntryPoint is an instance of LoginUrlAuthenticationEntryPoint.spring-doc.cn

number 4 The browser will then request the log in page that it was redirected to.spring-doc.cn

number 5 Something within the application, must render the log in page.spring-doc.cn

When the username and password are submitted, the UsernamePasswordAuthenticationFilter authenticates the username and password. The UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter, so this diagram should look pretty similar.spring-doc.cn

usernamepasswordauthenticationfilter
Figure 2. Authenticating Username and Password

The figure builds off our SecurityFilterChain diagram.spring-doc.cn

number 1 When the user submits their username and password, the UsernamePasswordAuthenticationFilter creates a UsernamePasswordAuthenticationToken which is a type of Authentication by extracting the username and password from the HttpServletRequest.spring-doc.cn

number 2 Next, the UsernamePasswordAuthenticationToken is passed into the AuthenticationManager to be authenticated. The details of what AuthenticationManager looks like depend on how the user information is stored.spring-doc.cn

number 3 If authentication fails, then Failurespring-doc.cn

number 4 If authentication is successful, then Success.spring-doc.cn

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:spring-doc.cn

Form Log In
public SecurityFilterChain filterChain(HttpSecurity http) {
	http
		.formLogin(withDefaults());
	// ...
}
<http>
	<!-- ... -->
	<form-login />
</http>
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
	http {
		formLogin { }
	}
	// ...
}

In this configuration Spring Security will render a default log in page. Most production applications will require a custom log in form.spring-doc.cn

The configuration below demonstrates how to provide a custom log in form.spring-doc.cn

Custom Log In Form Configuration
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()
		}
	}
	// ...
}

When the login page is specified in the Spring Security configuration, you are responsible for rendering the page. Below is a Thymeleaf template that produces an HTML login form that complies with a login page of /login:spring-doc.cn

Log In Form - src/main/resources/templates/login.html
<!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>

There are a few key points about the default HTML form:spring-doc.cn

Many users will not need much more than to customize the log in page. However, if needed, everything above can be customized with additional configuration.spring-doc.cn

If you are using Spring MVC, you will need a controller that maps GET /login to the login template we created. A minimal sample LoginController can be seen below:spring-doc.cn

LoginController
@Controller
class LoginController {
	@GetMapping("/login")
	String login() {
		return "login";
	}
}
@Controller
class LoginController {
    @GetMapping("/login")
    fun login(): String {
        return "login"
    }
}