I am trying to create Spring Boot Application that uses Remember Me Token that is saved into H2 DB. Token gets saved but when I delete JSSESSIONID and remember-me Cookies and then I try to call http://localhost:8080/Hello again I need to Log in again instead of using Remember Me Token from the DB (if I properly assume what to expect). And another Token is saved with the same Username.
application.properties
# SECURITY
spring.security.user.name = myuser
spring.security.user.password = mypassword
spring.security.user.roles = USER
# H2 DATABASE
spring.h2.console.enabled = true
spring.datasource.url = jdbc:h2:mem:testdb
spring.datasource.initialization-mode = always
schema.sql
create table persistent_logins (
username varchar(64) not null,
series varchar(64) primary key,
token varchar(64) not null,
last_used timestamp not null
);
MyController.java
package com.ivoronline.springboot_security_rememberme_db_h2.controllers;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
//=================================================================
// HELLO
//=================================================================
@RequestMapping("Hello")
String hello() {
return "Hello from Controller";
}
}
WebSecurityConfig.java
package com.ivoronline.springboot_security_rememberme_db_h2.config;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
//PROPERTIES
@Autowired UserDetailsService userDetailsService;
@Autowired PersistentTokenRepository persistentTokenRepository;
//=================================================================
// PERSISTENT TOKEN REPOSITORY
//=================================================================
@Bean
public PersistentTokenRepository persistentTokenRepository(DataSource dataSource) {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
return tokenRepository;
}
//=================================================================
// CONFIGURE
//=================================================================
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
//ENABLE REMEMBER ME COOKIE
httpSecurity.rememberMe()
.tokenRepository(persistentTokenRepository)
.userDetailsService(userDetailsService);
//H2 CONSOLE
httpSecurity.authorizeRequests(authorize -> { authorize.antMatchers("/h2-console/**").permitAll(); });
httpSecurity.headers().frameOptions().sameOrigin();
//DISABLE CSRF
httpSecurity.csrf().disable();
//SECURE ALL RESOURCES
httpSecurity.authorizeRequests().anyRequest().authenticated();
//DEFAULT LOGIN FORM
httpSecurity.formLogin();
}
}
CodePudding user response:
It looks like rememberMe
is not being activated for any of endpoints.
In that case, can you try something like this:
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.rememberMe().tokenRepository(persistentTokenRepository).userDetailService(userDetailsService).and()
.authorizeRequests(authorize -> {
authorize.antMatchers("/h2-console/**").permitAll();
}).headers().frameOptions().sameOrigin().and().csrf().disable().authorizeRequests().anyRequest()
.authenticated().and().formLogin();
}
CodePudding user response:
OK, so I guess I misunderstood how this works. So in both cases there should be Browser's Cookie but with different information.
With Browser based Remember-me Cookie contains Base64 encoded myuser:1648219725190:7e829e8197008d754a39c9df4c3b5386
With DB based Remember-me Cookie contains Base64 encoded series and token that are stored into DB