Understanding Form Login in Spring Boot
This article explains the default behaviour of spring-boot-starter-security. In this article, we will see how to secure a simple web application with a username and password.
To start with, I have written a simple web application with an API that prints hello world.
@RestController
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello() {
return "Hello World!";
}
}
There is nothing special about this Controller. When we open http://localhost:8080/hello from the browser, we get to see a ”Hello World!” message.
Let’s add the spring security module to this project by adding the following starter dependency.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
Once you have added the above dependency, Restart the application and try accessing http://localhost:8080/hello again in the browser. This time you are redirected to a Login form that asks for a username and password.
This behaviour is due to the magic of auto-configuration. Let’s dive into details.
Security auto-configuration
This starter for security does the following auto-configurations.
- Creates a servlet
Filter
calledspringSecurityFilterChain
which is responsible for most of the security stuff like login form redirection, username password validation, session creation and destruction etc. ThisspringSecurityFilterChain
will be registered to intercept all URLs of your application. -
Sets up BasicAuth and a form login for all the requests. This setup is equivalent to the following.
protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and().formLogin() .and().httpBasic(); }
We will see these builder methods in upcoming posts.
- Creates a simple in-memory
UserDetailService
that can only allow a username calleduser
with a generated password. This password can be found at the startup logs.This is the password that I provided in the above example.
By default, Spring Security enables a logout endpoint at http://localhost:8080/logout. On opening this URL, You will be presented with a logout Screen with a single logout button. clicking this button will log you out of the session, and a login page will be presented to you post Logout.
Login flow
Here is a simple illustration of the form login works.
To understand the flow, you need to learn a little about cookies.
- Cookies are key-value pair with occasional expiry time associated with it.
- Cookies are created when the server/website/web-application sends an HTTP response with a Set-Cookie header.
- By design, All browsers will send cookies associated with the website when accessing any resource from that specific server/website/web-application.
- Websites cannot get hold of cookies from other websites.
When a login request comes to the server, the spring security logic validates the credentials and if successful, creates
a session id and associates it with the logged-in user and keeps this mapping somewhere. The same session-id also sent
back to the browser in the form of Set-Cookie
header with the name JSESSIONID
.
Now whenever the request goes to the server, the cookie will also be sent along with the request. When the server
notices JSESSIONID
, it can look at the session map and find appropriate user associated with that session. If no
mappings found, the request will be redirected to a log in page.
Logout flow
Here is the logout flow for simple form login
In the next post, we will see how we can supply our custom login and logout pages.