Remember-Me in Spring Security Example

By Arvind Rai, November 26, 2019
This page will walk through Remember-Me in Spring Security example. Remember-me functionality enables a user to keep logged-in. In our application we provide an option, usually checkbox, to the user to select remember-me and if the 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. Spring performs remember-me functionality by creating token using authentication details. There are two approach to achieve remember-me functionality, one is simple hash-based token approach and another is persistent token approach. Here on this page we will provide example using both approach with annotation as well as XML configuration. In our example, we are using spring 4 security. CSRF is enabled by default in JavaConfig as well as XML configuration. When we use spring form tag in our UI and JavaConfig is annotated with @EnableWebSecurity, we need not to include HTML hidden input field for CSRF parameter, it will be automatically included at run time.

Software Used

Find the software used in our demo.
1. Java 8
2. Spring 4.2.5.RELEASE
3. Spring-Security 4.0.3.RELEASE
4. Tomcat 8
5. Gradle
6. Eclipse
7. MySQL

"Remember Me" in Spring Security

Remember-me is a functionality using which a user can be identified between sessions. It means once the user logins in web application with remember-me option, he will be able to access secure application even after session expired. This is also called persistent-login authentication. To achieve it spring sends an additional cookie to the browser and once the session is expired, user is automatically authenticated and is logged in using remember-me cookie. While configuring remember me functionality we can also set the remember me cookie expiry time. To achieve this functionality, spring provides below approaches.

Simple hash-based token approach : Hashing strategy 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 security issue and is commonly not recommended.
Persistent token approach : In this approach we need to create a table with name persistent_logins where token is saved. In remember-me configuration, we need to configure datasource while using XML and PersistentTokenRepository class while using JavaConfig.

Create Login and Logout Views

Find the login page.
customLogin.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
    <head>
        <title>Spring Security Example</title>
    </head>
    <body>
       <h3>Spring Security Example</h3>
        <font color="red">
		   ${SPRING_SECURITY_LAST_EXCEPTION.message}
        </font>
	<form:form action="${pageContext.request.contextPath}/appLogin" method="POST">
		Enter UserName:	<input type="text" name="app_username"/><br/><br/>
		Enter Password: <input type="password" name="app_password"/> <br/><br/>		
		<input type='checkbox' name="remember-me-param"/>Remember Me? <br/>	
		<input type="submit" value="Login"/>
	</form:form>
    <body>
</html>   
Here we have created a HTML checkbox. The name attribute of it is specified in remember-me configuration. After successful login, it goes to a secure page given below.
home.jsp
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
    <head>
        <title>Spring Security Example</title>
    </head>
    <body>
        <form:form action="${pageContext.request.contextPath}/appLogout" method="POST">
           <input type="submit" value="Logout"/>
        </form:form>   
        Welcome to you. Find secure data. <br/>
	<c:forEach var="ob" items="${list}">
	    <br/><c:out value="${ob.stdId}"></c:out>
	      <c:out value="${ob.stdName}"></c:out>	        
	</c:forEach>
    </body>
</html> 

Hash-Based Token Approach using Annotation

Find the JavaConfig for hash-based token approach.
SecurityConfig.java
package com.concretepage.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		//authorize requests		
		http.authorizeRequests().
		antMatchers("/app/secure/**").
		access("hasRole('ROLE_ADMIN')");
		
		//login configuration
		http.formLogin().  
                loginPage("/app").
                loginProcessingUrl("/appLogin").
                usernameParameter("app_username").
                passwordParameter("app_password").
                defaultSuccessUrl("/app/secure/home");
		
		//remember me configuration
		http.rememberMe(). 
                key("rem-me-key").
                rememberMeParameter("remember-me-param").
                rememberMeCookieName("my-remember-me").
                tokenValiditySeconds(86400);
		
		//logout configuration
                http.logout().    
		logoutUrl("/appLogout"). 
		logoutSuccessUrl("/app");
	} 
	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
		auth.inMemoryAuthentication().withUser("ram").password("ram123").roles("ADMIN");
	}	
} 
Look at the below code snippet.
//remember me configuration
http.rememberMe(). 
key("rem-me-key").
rememberMeParameter("remember-me-param").
rememberMeCookieName("my-remember-me").
tokenValiditySeconds(86400); 

rememberMe(): It returns RememberMeConfigurer class using which remember-me configuration is done.
key(): It specifies the key to identify tokens.
rememberMeParameter(): It specifies the name attribute which we use to create HTML checkbox.
rememberMeCookieName(): It specifies the cookie name stored in the browser.
tokenValiditySeconds(): Specifies the time in seconds after which is token is expired.

Now find the print screen of project structure in eclipse.
Remember-Me in Spring Security Example
AppConfig.java
package com.concretepage.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration
@ComponentScan("com.concretepage")
@Import(SecurityConfig.class)
@EnableWebMvc
public class AppConfig {
    @Bean  
    public InternalResourceViewResolver viewResolver() {  
	InternalResourceViewResolver resolver = new InternalResourceViewResolver();  
        resolver.setPrefix("/WEB-INF/secure/");  
        resolver.setSuffix(".jsp");
        return resolver;  
    }	
} 
SecurityInitializer.java
package com.concretepage.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
} 
WebAppInitializer.java
package com.concretepage.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class[] { AppConfig.class };
	}
	@Override
	protected Class<?>[] getServletConfigClasses() {
		return null;
	}
	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}
} 
StudentController.java
package com.concretepage.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.concretepage.bean.Student;
@Controller
@RequestMapping("/app")
public class StudentController {
	@RequestMapping
	public String login() {
 		return "customLogin";
 	} 	
	@RequestMapping("/secure/home")
	public String homePage(Model model) {
		List list = new ArrayList<>();
		list.add(new Student(1, "Shankar"));
		list.add(new Student(2, "Vishnu"));
		list.add(new Student(3, "Bhahma"));
		model.addAttribute("list", list);
 		return "home";
 	}    
} 
Student.java
package com.concretepage.bean;
public class Student {
	private int stdId;
	private String stdName;
	public Student(int stdId, String stdName) {
		this.stdId = stdId;
		this.stdName = stdName;
	}
	public int getStdId() {
		return stdId;
	}
	public void setStdId(int stdId) {
		this.stdId = stdId;
	}
	public String getStdName() {
		return stdName;
	}
	public void setStdName(String stdName) {
		this.stdName = stdName;
	}
} 
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'
archivesBaseName = 'spring-security'
version = '1' 
repositories {
    mavenCentral()
}
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web:1.3.3.RELEASE'
    compile 'org.springframework.boot:spring-boot-starter-security:1.3.3.RELEASE'
    compile 'jstl:jstl:1.2'    
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:1.3.3.RELEASE'    
} 

Hash-Based Token Approach using XML Configuration

Find the XML configuration for hash-based token approach.
security-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/security
	http://www.springframework.org/schema/security/spring-security.xsd">

	<http auto-config="true">
		<intercept-url  pattern="/app/secure/**" access="hasRole('ROLE_ADMIN')" />
		<form-login 
		   login-page="/app" 
		   login-processing-url="/appLogin"
		   username-parameter="app_username"
		   password-parameter="app_password"
		   default-target-url="/app/secure/home"/>
		<remember-me  
		   key="rem-me-key" 
		   remember-me-parameter="remember-me-param"
		   remember-me-cookie="my-remember-me"
		   token-validity-seconds="86400"/>
		<logout 
		   logout-url="/appLogout" 
		   logout-success-url="/app"/>  
	</http>
	<authentication-manager>
		<authentication-provider>
			<user-service>
				<user name="ram" password="ram123" authorities="ROLE_ADMIN" />
			</user-service>
		</authentication-provider>
	</authentication-manager>
</beans:beans> 
Look at the below code snippet.
<remember-me  
   key="rem-me-key" 
   remember-me-parameter="remember-me-param"
   remember-me-cookie="my-remember-me"
   token-validity-seconds="86400"/> 

remember-me: XML security tag to configure remember-me.
key: It defines a key to identify cookie.
remember-me-parameter : Defines the name attribute which is used to create HTML checkbox.
remember-me-cookie : Defines the cookie name stored in browser.
token-validity-seconds : Specifies the time in seconds after which is token is expired.

Now find the print screen of project structure in eclipse.
Remember-Me in Spring Security Example
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
        
	<context:component-scan base-package="com.concretepage" />
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	    <property name="prefix" value="/WEB-INF/secure/"/>
	    <property name="suffix" value=".jsp"/> 
        </bean>
        <import resource="security-config.xml"/>
</beans> 
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

	<display-name>Spring Security Example</display-name>
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
		   /WEB-INF/dispatcher-servlet.xml
		</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- Spring Security Configuration -->
	<filter>
		<filter-name>springSecurityFilterChain</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>springSecurityFilterChain</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app> 


Create Database for Persistent Token Approach

In persistent token approach, we need to create a table with name persistent_logins as follows.
Table: persistent_logins
CREATE TABLE `persistent_logins` (
	`username` VARCHAR(64) NOT NULL,
	`series` VARCHAR(64) NOT NULL,
	`token` VARCHAR(64) NOT NULL,
	`last_used` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	PRIMARY KEY (`series`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB; 
Find the complete database used in our example.
-- Dumping database structure for mydb
CREATE DATABASE IF NOT EXISTS `mydb`;
USE `mydb`;

-- Dumping structure for table mydb.authorities
CREATE TABLE IF NOT EXISTS `authorities` (
  `username` varchar(50) NOT NULL,
  `authority` varchar(50) NOT NULL,
  UNIQUE KEY `ix_auth_username` (`username`,`authority`),
  CONSTRAINT `fk_authorities_users` FOREIGN KEY (`username`) REFERENCES `users` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- Dumping data for table mydb.authorities: ~1 rows (approximately)
INSERT INTO `authorities` (`username`, `authority`) VALUES
	('ram', 'ROLE_ADMIN');

-- Dumping structure for table mydb.persistent_logins
CREATE TABLE IF NOT EXISTS `persistent_logins` (
  `username` varchar(64) NOT NULL,
  `series` varchar(64) NOT NULL,
  `token` varchar(64) NOT NULL,
  `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- Dumping structure for table mydb.users
CREATE TABLE IF NOT EXISTS `users` (
  `username` varchar(50) NOT NULL,
  `password` varchar(50) NOT NULL,
  `enabled` tinyint(1) NOT NULL,
  PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

-- Dumping data for table mydb.users: ~1 rows (approximately)
INSERT INTO `users` (`username`, `password`, `enabled`) VALUES
	('ram', 'e17e5425a021224b63e91499ff8ac491c87567db', 1); 

Persistent Token Approach using Annotation

Find the JavaConfig to configure remember-me using persistent token approach .
SecurityConfig.java
package com.concretepage.config;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import com.concretepage.service.AuthenticationService;
@Configuration
@EnableWebSecurity
@PropertySource("classpath:jdbc.properties")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Autowired
	Environment env;
	@Autowired
	AuthenticationService authenticationService;	
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		//authorize requests
		http.authorizeRequests().
		antMatchers("/app/secure/**").
		access("hasRole('ROLE_ADMIN')");
		
		//login configuration
		http.formLogin().  
                loginPage("/app").
                loginProcessingUrl("/appLogin").
                usernameParameter("app_username").
                passwordParameter("app_password").
                defaultSuccessUrl("/app/secure/home");
		
		//remember me configuration
		http.rememberMe(). 
		tokenRepository(persistentTokenRepository()).
                rememberMeParameter("remember-me-param").
                rememberMeCookieName("my-remember-me").
                tokenValiditySeconds(86400);
		
		//logout configuration
                http.logout().    
		logoutUrl("/appLogout"). 
		logoutSuccessUrl("/app");
	} 
	@Autowired
	public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
	        ShaPasswordEncoder encoder = new ShaPasswordEncoder();
	        auth.userDetailsService(authenticationService).passwordEncoder(encoder);
	}
	@Bean
	public DataSource getDataSource() {
	       BasicDataSource dataSource = new BasicDataSource();
	       dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
	       dataSource.setUrl(env.getProperty("jdbc.url"));
	       dataSource.setUsername(env.getProperty("jdbc.username"));
	       dataSource.setPassword(env.getProperty("jdbc.password"));
	       return dataSource;
	}
	@Bean
	public PersistentTokenRepository persistentTokenRepository() {
		JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
		tokenRepository.setDataSource(getDataSource());
		return tokenRepository;
	}
} 
Look at the below code snippet.
//remember me configuration
http.rememberMe(). 
tokenRepository(persistentTokenRepository()).
rememberMeParameter("remember-me-param").
rememberMeCookieName("my-remember-me").
tokenValiditySeconds(86400); 
tokenRepository: It specifies PersistentTokenRepository which is used to query persistent_logins table.

Now find the print screen of project structure in eclipse.
Remember-Me in Spring Security Example
UserInfo.java
package com.concretepage.bean;
public class UserInfo {
	private String username;
	private String password;
	private String role;
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getRole() {
		return role;
	}
	public void setRole(String role) {
		this.role = role;
	}
}  
UserDAO.java
package com.concretepage.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import com.concretepage.bean.UserInfo;
@Repository
public class UserDAO {
    private JdbcTemplate jdbcTemplate;
    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }
    public UserInfo getUserInfo(String username){
    	String sql = "SELECT u.username name, u.password pass, a.authority role FROM "+
    			     "users u INNER JOIN authorities a on u.username=a.username WHERE "+
    			     "u.enabled =1 and u.username = ?";
    	UserInfo userInfo = (UserInfo)jdbcTemplate.queryForObject(sql, new Object[]{username},
    		new RowMapper<UserInfo>() {
	            public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
	                UserInfo user = new UserInfo();
	                user.setUsername(rs.getString("name"));
	                user.setPassword(rs.getString("pass"));
	                user.setRole(rs.getString("role"));
	                return user;
	            }
        });
    	return userInfo;
    }
}  
AuthenticationService.java
package com.concretepage.service;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.concretepage.bean.UserInfo;
import com.concretepage.dao.UserDAO;
@Service
public class AuthenticationService implements UserDetailsService {
	@Autowired
	private UserDAO userDAO;
	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		UserInfo userInfo = userDAO.getUserInfo(username);
		GrantedAuthority authority = new SimpleGrantedAuthority(userInfo.getRole());
		UserDetails userDetails = (UserDetails)new User(userInfo.getUsername(), 
				userInfo.getPassword(), Arrays.asList(authority));
		return userDetails;
	}
} 
jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.username=root
jdbc.password= 
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'
archivesBaseName = 'spring-security'
version = '1' 
repositories {
    mavenCentral()
}
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web:1.3.3.RELEASE'
    compile 'org.springframework.boot:spring-boot-starter-security:1.3.3.RELEASE'
    compile 'org.springframework.boot:spring-boot-starter-jdbc:1.3.3.RELEASE'
    compile 'jstl:jstl:1.2'    
    compile 'mysql:mysql-connector-java:5.1.31'
    compile 'commons-dbcp:commons-dbcp:1.4'    
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat:1.3.3.RELEASE'    
} 

Persistent Token Approach using XML Configuration

Find the XML configuration to configure remember-me using persistent token approach .
security-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
		xmlns:beans="http://www.springframework.org/schema/beans"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/security
		http://www.springframework.org/schema/security/spring-security.xsd">

	<http auto-config="true">
		<intercept-url  pattern="/app/secure/**" access="hasRole('ROLE_ADMIN')" />
		<form-login 
		   login-page="/app" 
		   login-processing-url="/appLogin"
		   username-parameter="app_username"
		   password-parameter="app_password"
		   default-target-url="/app/secure/home"/>
		<remember-me  
		   data-source-ref="dataSource"  
		   remember-me-parameter="remember-me-param"
		   remember-me-cookie="my-remember-me"
		   token-validity-seconds="86400"/>
		<logout 
		   logout-url="/appLogout" 
		   logout-success-url="/app"/>  
	</http>
	<authentication-manager>
	    <authentication-provider>
	        <password-encoder hash="sha"/>
             <jdbc-user-service 
                data-source-ref="dataSource" 
                authorities-by-username-query="SELECT username, authority FROM authorities WHERE username = ?"
                users-by-username-query="SELECT username, password, enabled FROM users WHERE username = ?"/>
	    </authentication-provider>
	</authentication-manager> 
        <beans:bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
            <beans:property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <beans:property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
            <beans:property name="username" value="root"/>
            <beans:property name="password" value=""/>
        </beans:bean>
</beans:beans> 
Look at the below code snippet.
<remember-me  
   data-source-ref="dataSource"  
   remember-me-parameter="remember-me-param"
   remember-me-cookie="my-remember-me"
   token-validity-seconds="86400"/> 
data-source-ref: Specifies datasource to query persistent_logins table.

Now find the print screen of project structure in eclipse.
Remember-Me in Spring Security Example

Run Application

To run the application find the below steps.
1. Download the project source code.
2. Go to root directory of the project using command prompt.
3. Run gradle clean build
4. We will get WAR file in build/lib directory.
5. Deploy WAR file in tomcat.
6. Run the application using URL http://localhost:8080/spring-security-1/app/secure/home

Page will be redirected to login page.
Remember-Me in Spring Security Example
Select remember me checkbox and login using ram/ram123 authentication. It will go to a secure page.
Remember-Me in Spring Security Example
Check the cookies. There will be two cookies related to our web application that are JSESSIONID and my-remember-me as given below.
Remember-Me in Spring Security Example
Now to test remember-me, just delete JSESSIONID cookie. After deleting this cookie, session is expired and also restart the server. Now access the URL http://localhost:8080/spring-security-1/app/secure/home again. This time it will not be redirected to login page. This is because of my-remember-me cookie using which application will automatically authenticate user. In case we are using persistent token approach, a row for token will be inserted in persistent_logins table.
Remember-Me in Spring Security Example
After logout, token will be deleted.

Now I am done. Happy spring security learning!

Download Complete Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us