Moussi
Moussi

Reputation: 470

spring security activate remember me feature always

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

Answers (2)

Moussi
Moussi

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

Sanjay
Sanjay

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

Related Questions