Spring Boot Security – Form Based Authentication – Remember Me

Authentication – Remember Me

The example Spring Boot Security form based authentication remember me will show you how to use custom login form with Spring’s j_spring_security_check to authenticate a user with remember me option. You may also look into form based authentication – remember me – on Spring MVC framework. The similar example we will implement here but using Spring Boot framework. We will add additional field as remember me into the login form.

This tutorial will show you how to remember your credentials for a specific time period for auto-login without providing any login credentials into the login form.

Remember-me or persistent-login authentication refers to web sites being able to remember the identity of a principal between sessions. This is typically accomplished by sending a cookie to the browser, with the cookie being detected during future sessions and causing automated login to take place.

Spring Security provides the necessary hooks for these operations to take place, and has two concrete remember-me implementations. One uses hashing to preserve the security of cookie-based tokens and the other uses a database or other persistent storage mechanism to store the generated tokens.

You can implement remember me functionality using various approaches, such as, using token validity, using always remember, cookie remember etc. We will use here token validity and keep this token valid for one day. You can change according to your requirement.

We will also use here in-memory authentication, you can use JDBC authentication and you can check my other Spring Security tutorials.

Prerequisites

Java 1.8/19, Gradle 5.4.1, Spring Boot 2.1.6/3.1.4, Maven 3.8.5

Read tutorial Spring Boot Security Form based Authentication before proceeding below sections.

Security Config

I am not going to tell you from the initial project creation but I will modify the existing application as I asked you to read tutorial in Prerequisites section before coming here.

You may also download the complete source code later from this tutorial.

The file is quite self-explanation and I have added the following code snippets in addition to the existing code base.

The following security configuration is for spring boot 3.x.x.

@Configuration
public class SecurityConfig {

	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		http.authorizeHttpRequests(auth -> auth
				// ignore home, login, error pages and css files
				.requestMatchers("/", "/login", "/css/**", "/error**").permitAll().requestMatchers("/admin")
				.hasRole("ADMIN").anyRequest().authenticated()); // check for admin url with ADMIN role
		// allow users to authenticate with form based login
		http.formLogin(form -> form.loginPage("/login") // specifies custom login page
				.permitAll().usernameParameter("username") // overrides spring's default j_username with username
															// parameter
				.passwordParameter("password") // overrides spring's default j_password with password parameter
				.loginProcessingUrl("/j_spring_security_check") // login processing url
				.defaultSuccessUrl("/admin") // default target url which will be shown after successful login
				.failureUrl("/login?error")); // authenticate failure url
		http.logout((logout) -> logout.permitAll()); // logout
		http.rememberMe(remember -> remember.rememberMeServices(rememberMeServices())); // remember me

		return http.build();
	}

	@Bean
	public UserDetailsService userDetailsService() {
		UserDetails admin = User.builder().username("admin")
				.password("{bcrypt}$2a$10$dl8TemMlPH7Z/mpBurCX8O4lu0FoWbXnhsHTYXVsmgXyzagn..8rK").roles("ADMIN")
				.build();

		return new InMemoryUserDetailsManager(admin);
	}

	@Bean
	RememberMeServices rememberMeServices() {
		RememberMeTokenAlgorithm encodingAlgorithm = RememberMeTokenAlgorithm.SHA256;
		TokenBasedRememberMeServices rememberMe = new TokenBasedRememberMeServices("rememberKey", userDetailsService(),
				encodingAlgorithm);
		rememberMe.setMatchingAlgorithm(RememberMeTokenAlgorithm.MD5);
		rememberMe.setParameter("remember"); // remember me field name in login form
		rememberMe.setTokenValiditySeconds(86400); // remember me for one day
		return rememberMe;
	}

}

The following security configuration is for spring boot 2.x.x.

.rememberMe()// configure remember me,
	.key("rememberKey")// key for remember me,
	.rememberMeParameter("remember")// remember me field name in
									// login form,
	.tokenValiditySeconds(86400);// keep for one day

The updated SecurityConfig.java file is shown below:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
		auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).withUser("admin")
				.password("$2a$10$dl8TemMlPH7Z/mpBurCX8O4lu0FoWbXnhsHTYXVsmgXyzagn..8rK").roles("ADMIN"); // password -
																											// admin
	}
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http// ,
				.authorizeRequests()// , authorize request
				.antMatchers("/", "/login", "/static/**", "/error**").permitAll().anyRequest().authenticated()// ,
																												// ignore
																												// /,login
																												// page,static
				// resources, error
				// pages
				.antMatchers("/admin")// Ensures that request with "/admin" to
										// our application requires the user to
										// be authenticated
				.access("hasRole('ADMIN')")// Any URL that starts with
											// "/admin" will
				// be restricted to users who have the
				// role "ROLE_ADMIN",
				.and()// ,
				.formLogin()// Allows users to authenticate with form based
							// login,
				.loginPage("/login")// specifies the location of the log in
									// page,
				.loginProcessingUrl("/j_spring_security_check")// login
																// processing
																// URL,
				.defaultSuccessUrl("/admin")// default-target-url,
				.failureUrl("/login?error")// authentication-failure-url,
				.usernameParameter("username")// overrides Spring's default
												// j_username with
												// username-parameter,
				.passwordParameter("password")// overrides Spring's default
												// j_password with
												// password-parameter,
				.and().rememberMe()// remember me,
				.key("rememberKey")// key for remember me,
				.rememberMeParameter("remember")// remember me field name in login form,
				.tokenValiditySeconds(86400);// remember me for one day
	}
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
}

The above configuration is simple hash-based token approach, so here hashing technique is used to create token. The token is created using username, expiration time, password and a key. After successful authentication a cookie using token value is sent to the browser.

This approach has a security threat, because a captured remember-me token will be usable from any user agent until such time as the token expires and is usually not recommended.

Login Form

For spring boot 3.x.x I will use Thymeleaf framework for the view technology and I will use HTML pages. The HTML pages and the CSS file will be kept under src/main/resources folder. The HTML pages are kept under templates sub-folder and CSS file is kept under static/css sub-folder.

The JSP pages are used for spring boot 2.x.x version.

I will use the existing login.jsp page and update the login form to include additional checkbox for remember me option.

The following code snippets have been added to the login form.

<tr>
	<td>Remember Me:</td>
	<td><input type='checkbox' name="remember" /></td>
</tr>

I have provided an option, usually checkbox, to the user to select Remember Me and if a user checks it then after successful login, spring application sends a remember-me cookie to the browser in addition to session cookie. Once the session cookie is expired, then if user accesses the secure page, it will automatically be logged-in using remember-me cookie.

Deploying and Testing Remember Me Application

Deploying and testing application is same as Spring Boot Security Form based Authentication.

Now when you try to access the admin page you will be redirected to login page and you will see the Remember Me checkbox for next time auto-login.

spring boot security form based authentication remember me

So once you login with checkbox checked and next time when you hit the direct URL http://localhost:8080/admin into the browser you will automatically be redirected to the admin page and you are no longer required to login using credentials.

Or even if you click on the link Go to Administrator page from home page, you will be automatically redirected to the admin page.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *