Reputation: 470
I'm implementing an example of spring security with the remember-me feature based on Persistent Token Approach. Actually i'm using a custom authentication manager how can i activate forever the option remember-me without adding the checkbox remember me on login form(i don't want also to put the checkbox input hidden and activate by default). How can i achieve that? here the spring security java configuration that i made:
@Override
protected void configure(HttpSecurity http) throws Exception {
RequestMatcher matcher = new RequestHeaderRequestMatcher("X-Requested-With");
LOGGER.debug("Creating Security Context ...");
http.
sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().
csrf().requireCsrfProtectionMatcher(createCSRFMathers()).and();
//Add autologin filter
http.addFilter(autoLoginFilter)
.addFilterBefore(new TransactionIdRequestFilter(), AutoLoginFilter.class)
.exceptionHandling().defaultAuthenticationEntryPointFor(new Http401TimeoutEntryPoint(), matcher)
.and();
//Add form login
http.formLogin()
.successHandler(savedRequestAwareAuthenticationSuccessHandler())
.loginPage("/page/login")
.loginProcessingUrl("/page/login/authenticate")
.failureUrl("/page/login?loginError=true")
.and();
// Configures the logout function
http.logout()
.deleteCookies("JSESSIONID")
.logoutUrl("/logout")
.logoutSuccessUrl("/page/login?loginError=false")
.and();
// Configures url based authorization
// Anyone can access the following urls
http.authorizeRequests()
.antMatchers("posc://**",
"/connectedUser/mobileInfos",
"/dashboard/config/**",
"/page/checklogintoken/**",
"/page/httpError",
"/page/login/**",
"/page/manifest",
"/page/token/**",
"/service-scripting/**",
"/script/**")
.permitAll()
.antMatchers("/**")
.hasRole("USER").and().rememberMe().rememberMeServices(rememberMeServices());
}
@Bean
public AbstractRememberMeServices rememberMeServices() {
PersistentTokenBasedRememberMeServices rememberMeServices =
new PersistentTokenBasedRememberMeServices("AppKey",customUserDetailsService,persistentTokenRepository());
rememberMeServices.setAlwaysRemember(true);
return rememberMeServices;
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
CassandraTokenRepository db = new CassandraTokenRepository(persistanceTokenDao);
return db;
}
@Bean
public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler() {
SavedRequestAwareAuthenticationSuccessHandler auth = new SavedRequestAwareAuthenticationSuccessHandler();
auth.setTargetUrlParameter("targetUrl");
return auth;
}
I have an AbstractPreAuthenticatedProcessingFilter with a custom authentication manager used to make custom features before authenticating user. how can i use this filter to set the remember me option to true ?
@Component
public class AutoLoginFilter extends AbstractPreAuthenticatedProcessingFilter {
@Override
public void doFilter(final ServletRequest request,
final ServletResponse response,
final FilterChain chain) throws IOException, ServletException {
...
}
}
Thanks.
Upvotes: 2
Views: 5678
Reputation: 470
I implement a full example that resolves the problem.Enabling the remember me feature without adding the input checkbox on login form and Using the persistent token approach to save token on database while authentication.
here is the spring security conf:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Autowired
AuthenticationService customUserDetailsService;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(customUserDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.rememberMe().rememberMeServices(rememberMeServices()).key("posc").and();
http.csrf()
.disable()
.authorizeRequests()
.antMatchers("/admin/**")
.access("hasRole('ROLE_ADMIN')")
.antMatchers("/admin/update**")
.access("hasRole('ROLE_ADMIN')")
.and()
.formLogin()
.successHandler(savedRequestAwareAuthenticationSuccessHandler())
.loginPage("/login").failureUrl("/login?error")
.loginProcessingUrl("/auth/login_check")
.usernameParameter("username").passwordParameter("password")
.and().logout().logoutUrl("/logout")
.logoutSuccessUrl("/login?logout");
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
@Bean
public AbstractRememberMeServices rememberMeServices() {
PersistentTokenBasedRememberMeServices rememberMeServices =
new PersistentTokenBasedRememberMeServices("posc",customUserDetailsService,persistentTokenRepository());
rememberMeServices.setAlwaysRemember(true);
rememberMeServices.setCookieName("remember-me-posc");
rememberMeServices.setTokenValiditySeconds(1209600);
return rememberMeServices;
}
@Bean
public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler() {
SavedRequestAwareAuthenticationSuccessHandler auth = new SavedRequestAwareAuthenticationSuccessHandler();
auth.setTargetUrlParameter("targetUrl");
return auth;
}
}
and here the full example on my github : https://github.com/Moussi/SpringSecurity-RememberMe-AlwaysEnabled-JavaConfig
Upvotes: 2
Reputation: 8955
Instead of configuring a tokenRepository
, you could configure a rememberMeService
. When creating the rememberMe service, there is a alwaysRemember
flag which could be set. Like this:
@Bean
public AbstractRememberMeServices rememberMeServices() {
PersistentTokenBasedRememberMeServices rememberMeServices =
new PersistentTokenBasedRememberMeServices(...
...
rememberMeServices.setAlwaysRemember(true);
...
return rememberMeServices;
}
The above rememberMeServices
can then be supplied to Spring Security like this:
...
.rememberMe()
.rememberMeServices(rememberMeServices())
...
Upvotes: 2