I am currently refactoring the security configuration removing WebSecurityConfigurerAdapter and am currently stuck on a config using two Basic Auth configurations with different user stores on different paths.
Current configuration looks like this and works fine:
#EnableWebSecurity
public class SecurityConfig {
#Order(1)
#Configuration
public static class BasicSpecialAuth extends WebSecurityConfigurerAdapter {
// some code
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// some code
auth.inMemoryAuthentication().withUser(specialUser.getId()).password(passwordEncoder().encode(specialUser.getPassword())).roles("SPECIALROLE");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.antMatcher("/very-special-path/**")
//. more code
.authorizeRequests(r -> r
.anyRequest().authenticated());
}
}
#Order(2)
#Configuration
public static class BasicAppAuth extends WebSecurityConfigurerAdapter {
// some code
#Bean
public CustomUserDetailsService customUserDetailsService() {
return new CustomUserDetailsService(userRepository);
}
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService())
.passwordEncoder(encoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
//. more code
.authorizeRequests(auth -> auth
.anyRequest().authenticated());
}
}
}
As can be seen, /very-special-path uses InMemoryAuthentication set up at start by configuration.
All other paths should be authenticated using users from local database. Due to possible duplicates on usernames I am not able to use the database for /very-special-path users too. Requirement is to have these separated.
Following documentation it was quite simple to change this on our apps providing Basic Auth and JWT Auth on different path. But with both using Basic Auth and different user stores, I have no idea how to set up configuration properly.
Any help would be appreciated.
Edit, the current config:
#Configuration
public class SecurityConfig {
// some code
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public UserDetailsService customUserDetailsService() {
return new CustomUserDetailsService(userRepository);
}
#Bean
public InMemoryUserDetailsManager inMemoryUserDetailsService() {
// more code
UserDetails healthUser = User.withUsername(specialUser.getId())
.password(passwordEncoder().encode(specialUser.getPassword()))
.roles("SPECIALROLE")
.build();
return new InMemoryUserDetailsManager(healthUser);
}
#Bean
#Order(1)
public SecurityFilterChain specialFilterChain(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.antMatcher("/very-special-path/**")
.authorizeRequests(auth -> auth
.anyRequest().authenticated());
return http.build();
}
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests(auth -> auth
.anyRequest().authenticated());
return http.build();
}
}
The app starts without any Warning or Error.
Both chains are mentioned in the log:
o.s.s.web.DefaultSecurityFilterChain : Will secure any request with ..
o.s.s.web.DefaultSecurityFilterChain : Will secure Ant [pattern='/very-special-path/**'] with ..
But authentication does not work. Checked for different endpoints and with different users. Every request gets an 401.
This config misses the assignment of the UserDetails to the specific filter chain. Is there a way to do so?
Based on the extra information you provided, there are only a couple of tweaks needed to get your configuration working. Take a look at this blog post that details common patterns for replacing WebSecurityConfigurerAdapter with the component-based approach, specifically the local AuthenticationManager.
For the special/health user, you can manually construct a local authentication manager so as not to collide with the global one declared as an #Bean. Here's a full example:
#EnableWebSecurity
public class SecurityConfig {
// ...
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public UserDetailsService customUserDetailsService() {
return new CustomUserDetailsService(userRepository);
}
#Bean
#Order(1)
public SecurityFilterChain specialFilterChain(HttpSecurity http, PasswordEncoder passwordEncoder) throws Exception {
http
.mvcMatcher("/very-special-path/**")
.authorizeRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults())
.authenticationManager(specialAuthenticationManager(passwordEncoder));
return http.build();
}
private AuthenticationManager specialAuthenticationManager(PasswordEncoder passwordEncoder) {
UserDetailsService userDetailsService = specialUserDetailsService(passwordEncoder);
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setPasswordEncoder(passwordEncoder);
authenticationProvider.setUserDetailsService(userDetailsService);
return new ProviderManager(authenticationProvider);
}
private UserDetailsService specialUserDetailsService(PasswordEncoder passwordEncoder) {
UserDetails specialUser = User.withUsername("specialuser")
.password(passwordEncoder.encode("specialpassword"))
.roles("SPECIALROLE")
.build();
return new InMemoryUserDetailsManager(specialUser);
}
#Bean
#Order(2)
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
Related
I am trying to set up multiple WebsecurityConfigurerAdapter for my project where the spring boot actuator APIs are secured using basic auth and all other endpoints are authenticated using JWtAuthentication. I am just not able to make it work together, only the config with the lower order works. I am using Spring Boot 2.1.5.RELEASE
Security Config One with JWT Authenticator
#Order(1)
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_WHITELIST = {
"/docs/**",
"/csrf/**",
"/webjars/**",
"/**swagger**/**",
"/swagger-resources",
"/swagger-resources/**",
"/v2/api-docs"
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(AUTH_WHITELIST).permitAll()
.antMatchers("/abc/**", "/abc/pdf/**").hasAuthority("ABC")
.antMatchers("/ddd/**").hasAuthority("DDD")
.and()
.csrf().disable()
.oauth2ResourceServer().jwt().jwtAuthenticationConverter(new GrantedAuthoritiesExtractor());
}
}
The basic Auth config with username/password
#Order(2)
#Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
/* #Bean
public UserDetailsService userDetailsService(final PasswordEncoder encoder) {
final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(
User
.withUsername("user1")
.password(encoder.encode("password"))
.roles("ADMIN")
.build()
);
return manager;
}
#Bean PasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}*/
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/actuator/**").hasRole("ADMIN")
.and()
.httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("password").authorities("ADMIN");
}
}
I have been trying to make it work for many days but cannot make both of them work together. If i swap the order, only basic auth works and not the JWT Auth Manager.
I have gone through a lot of SOF Questions, like
[https://stackoverflow.com/questions/40743780/spring-boot-security-multiple-websecurityconfigureradapter][1]
[https://stackoverflow.com/questions/52606720/issue-with-having-multiple-websecurityconfigureradapter-in-spring-boot][1]
[https://github.com/spring-projects/spring-security/issues/5593][1]
[https://www.baeldung.com/spring-security-multiple-entry-points][1]
Nothing seems to be working, is this a known issue in Spring?
To use multiple WebsecurityConfigurerAdapter, you need restrict them to specific URL patterns using RequestMatcher.
In your case you can set a higher priority for ActuatorSecurityConfig and limit it only to actuator endpoints:
#Order(-1)
#Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/actuator/**")
.and()
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
I have spring boot app with thymeleaf. I am using spring security formLogin method for security and now I need to add JWT for only some APIs.
#EnableWebSecurity
public class SecurityConfigurations {
#Autowired
UserDetailsServiceImpl userDetails;
#Bean
DaoAuthenticationProvider provider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(encoder());
provider.setUserDetailsService(userDetails);
return provider;
}
#Bean
PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
#Configuration
#Order(1)
public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
#Autowired
private JwtRequestFilter jwtRequestFilter;
#Autowired
DaoAuthenticationProvider provider;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(provider);
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable()
.authorizeRequests().antMatchers("/api/user/authenticate").permitAll()
.antMatchers("/api/user/**").hasRole("USER")
.and().
exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint).and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// Add a filter to validate the tokens with every request
httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
#Configuration
public static class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Autowired
DaoAuthenticationProvider provider;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(provider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/admins**").hasAnyRole("SADMIN").antMatchers("/admin/**")
.hasAnyRole("ADMIN", "SADMIN", "WADMIN").antMatchers("/rest/**")
.hasAnyRole("ADMIN", "SADMIN", "WADMIN", "USER").antMatchers("/user/**").hasAnyRole("USER")
.anyRequest().permitAll().and().formLogin().loginPage("/sign-in-up")
.loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
.invalidateHttpSession(false).and().csrf().disable().cors();
}
}
}
by doing this JWT is working fine as just I need but the formlogin has stopped and calling "/signInProcess" now give 404:
NOTE: if I change the order and make formLogin #order(1) it works again but of course will not work.
Also I tried to combine them both like this now it is both works fine but the problem with exception handling if the JWT authentication error will return formlogin thymeleaf error page :
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/admins**").hasAnyRole("SADMIN").antMatchers("/admin/**")
.hasAnyRole("ADMIN", "SADMIN", "WADMIN").antMatchers("/rest/**")
.hasAnyRole("ADMIN", "SADMIN", "WADMIN", "USER").antMatchers("/user/**").hasAnyRole("USER")
.antMatchers("/api/user/authenticate").permitAll()
.antMatchers("/api/user/**").hasRole("USER")
.anyRequest().permitAll().and().formLogin().loginPage("/sign-in-up")
.loginProcessingUrl("/signInProcess").usernameParameter("phone").and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/")
.invalidateHttpSession(false).and().csrf().disable().cors();
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
any suggestions to make this work. thank you.
Your WebSecurityConfigurerAdapters will process the incoming requests in order.
Since JWTSecurityConfig is annotated with #Order(1) it will process the requests first.
You have not specified a antMatcher for this Adapter, so it will match all requests.
This means that a request will never reach FormLoginConfigurationAdapter, since JWTSecurityConfig matches them all.
If you want JWTSecurityConfig to only apply to certain requests, you can specify an antMatcher in your security configuration.
Below is an example:
#EnableWebSecurity
public class SecurityConfigurations {
#Configuration
#Order(1)
public class JWTSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers(matchers -> matchers
.antMatchers("/api/**") // apply JWTSecurityConfig to requests matching "/api/**"
)
.authorizeRequests(authz -> authz
.anyRequest().authenticated()
)
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
#Configuration
public class FormLoginConfigurationAdapter extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests(authz -> authz
.anyRequest().authenticated()
)
.formLogin();
}
}
}
For more details on multiple WebSecurityConfigurerAdapter, you can see the multiple HttpSecurity section in the Spring Security reference docs.
For more details on the difference between authorizeRequests() and requestMatchers(), you can see this Stack Overflow question.
I have a REST API with the following security config -
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
#Value("${auth0.audience}")
private String audience;
#Value("${auth0.issuer}")
private String issuer;
#Override
protected void configure(HttpSecurity http) {
try {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/purch").authenticated()
.antMatchers("/purch2").authenticated();
JwtWebSecurityConfigurer
.forRS256(audience, issuer)
.configure(http);
} catch (Exception ex) {
throw new AuthenticationException(ex.getMessage());
}
}
}
I had added Swagger docs for this REST API and I am trying to protect the swagger docs using HTTP Basic Auth using this example
Hence, I updated the above WebSecurityConfig with #Order(1) and added a new WebSecurityConfig with Order(2) as shown below -
#Configuration
#Order(2)
public class SwaggerSecurity extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_LIST = { //
"**/v2/api-docs", //
"**/configuration/ui", //
"**/swagger-resources", //
"**/configuration/security", //
"**/swagger-ui.html", //
"**/webjars/**" //
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers(AUTH_LIST).authenticated().and().httpBasic();
}
//#Override
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("admin")).roles("USER", "ADMIN");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
This does not seem to have any effect and is NOT prompting for the basic auth credentials.
I tried several combinations of answers from here, here and here... But I am unable to get this working!
I was able to get the standalone Order(2) spring web security config working as expected, just not in combination with Order(1) security config.
As you can see from my question, I am not an expert with Spring Security and tried debugging this as much as I can! its time I sought for help after losing couple of hours on this. Any help is appreciated. Thank you.
Update based on comments:
I already tried combining the Web Security Config classes similar to what is shown here or here. The outcome is that my original REST API which was protected with "Authorization Header" bearer authentication is now overriden with Basic Auth.
May be, my question is - how do I make sure that one Web security config does not override another?
#Configuration
#Order(2)
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
#Value("${auth0.audience}")
private String audience;
#Value("${auth0.issuer}")
private String issuer;
#Override
protected void configure(HttpSecurity http) {
try {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/purch").authenticated()
.antMatchers("/purch2").authenticated();
JwtWebSecurityConfigurer
.forRS256(audience, issuer)
.configure(http);
} catch (Exception ex) {
throw new AuthenticationException(ex.getMessage());
}
}
#Configuration
#Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_LIST = { //
"/v2/api-docs", //
"/configuration/ui", //
"/swagger-resources", //
"/configuration/security", //
"/swagger-ui.html", //
"/webjars/**" //
};
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/purch/**").permitAll().and()
.authorizeRequests()
.antMatchers(AUTH_LIST)
.authenticated()
.and()
.httpBasic();
}
#Autowired
protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password(passwordEncoder().encode("password")).roles("USER")
.and()
.withUser("admin").password(passwordEncoder().encode("admin")).roles("USER", "ADMIN");
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
}
You seem to have mixed up contents gleaned from different sources. Please try a configuration like below.
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// Firs this configuration will apply since the order is 1
#Configuration
#Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// configure auth modes and path matchers
}
}
// Since there is no #Order annotation, this will be checked at last
#Configuration
public static class MvcWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// configure auth modes and path matchers
}
}
}
I am trying to set up multiple WebsecurityConfigurerAdapter for my project where the spring boot actuator APIs are secured using basic auth and all other endpoints are authenticated using JWtAuthentication. I am just not able to make it work together, only the config with the lower order works. I am using Spring Boot 2.1.5.RELEASE
Security Config One with JWT Authenticator
#Order(1)
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final String[] AUTH_WHITELIST = {
"/docs/**",
"/csrf/**",
"/webjars/**",
"/**swagger**/**",
"/swagger-resources",
"/swagger-resources/**",
"/v2/api-docs"
};
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers(AUTH_WHITELIST).permitAll()
.antMatchers("/abc/**", "/abc/pdf/**").hasAuthority("ABC")
.antMatchers("/ddd/**").hasAuthority("DDD")
.and()
.csrf().disable()
.oauth2ResourceServer().jwt().jwtAuthenticationConverter(new GrantedAuthoritiesExtractor());
}
}
The basic Auth config with username/password
#Order(2)
#Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
/* #Bean
public UserDetailsService userDetailsService(final PasswordEncoder encoder) {
final InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(
User
.withUsername("user1")
.password(encoder.encode("password"))
.roles("ADMIN")
.build()
);
return manager;
}
#Bean PasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}*/
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/actuator/**").hasRole("ADMIN")
.and()
.httpBasic();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("password").authorities("ADMIN");
}
}
I have been trying to make it work for many days but cannot make both of them work together. If i swap the order, only basic auth works and not the JWT Auth Manager.
I have gone through a lot of SOF Questions, like
[https://stackoverflow.com/questions/40743780/spring-boot-security-multiple-websecurityconfigureradapter][1]
[https://stackoverflow.com/questions/52606720/issue-with-having-multiple-websecurityconfigureradapter-in-spring-boot][1]
[https://github.com/spring-projects/spring-security/issues/5593][1]
[https://www.baeldung.com/spring-security-multiple-entry-points][1]
Nothing seems to be working, is this a known issue in Spring?
To use multiple WebsecurityConfigurerAdapter, you need restrict them to specific URL patterns using RequestMatcher.
In your case you can set a higher priority for ActuatorSecurityConfig and limit it only to actuator endpoints:
#Order(-1)
#Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/actuator/**")
.and()
.authorizeRequests().anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
I am trying to configure SpringSecurity to work with Remember Me authentication.
Here is my Java configuration:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Autowired
DatabasePersistentTokeRepositoryImpl databasePersistentTokeRepositoryImpl;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authenticationProvider(rememberMeAuthenticationProvider())
.rememberMe().tokenRepository(databasePersistentTokeRepositoryImpl).tokenValiditySeconds((int) TimeUnit.SECONDS.convert(7, TimeUnit.DAYS))
.and()
.csrf().disable();
}
#Bean()
public AuthenticationProvider rememberMeAuthenticationProvider() {
return new RememberMeAuthenticationProvider("KEY");
}
#Bean()
public TokenBasedRememberMeServices rememberMeServices() {
TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("KEY", userDetailsService);
rememberMeServices.setAlwaysRemember(true);
return rememberMeServices;
}
}
I see that rememberMeServices is not injected in RememberMeConfigurer. And that results in creating RememberMeAuthenticationFilter which refers to wrong rememberMeServices.
There is a section in Spring Security documentation describing this process using XML.
http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#session-mgmt
What is wrong with my injection and is it possible do to this without XML after all?
You aren't injecting it. There is no autowiring for the RememberMeConfigurer. Also why are you configuring so many beans?
The RememberMeAuthenticationProvider is already created for you, if you want to use a different key specify it using key("KEY"). This in turn will be used to create the RememberMeServices.
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Autowired
DatabasePersistentTokeRepositoryImpl databasePersistentTokeRepositoryImpl;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe()
.key("KEY")
.tokenRepository(databasePersistentTokeRepositoryImpl)
.tokenValiditySeconds((int) TimeUnit.SECONDS.convert(7, TimeUnit.DAYS))
.and()
.csrf().disable();
}
}
If you really need to set the alwaysRemember property to true you could use an ObjectPostProcessor to post process the filter and configure the RememberMeServices from there.
You would also have injected the wrong type of RememberMeServices as the one configured doesn't use the PersistentTokeRepository.
Just to provide an example of the code that #m-deinum's suggestion of an ObjectPostProcessor that sets alwaysRemember to true would look like would look like:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe()
.key("KEY")
.tokenRepository(databasePersistentTokeRepositoryImpl)
.tokenValiditySeconds((int) TimeUnit.SECONDS.convert(7, TimeUnit.DAYS))
.withObjectPostProcessor( new ObjectPostProcessor<RememberMeAuthenticationFilter>() {
#Override
public <O extends RememberMeAuthenticationFilter> O postProcess( O object) {
RememberMeAuthenticationFilter rmaf = (RememberMeAuthenticationFilter)
PersistentTokenBasedRememberMeServices rms = (PersistentTokenBasedRememberMeServices)rmaf.getRememberMeServices();
rms.setAlwaysRemember( true );
return object;
}
})
.and()
.csrf().disable();
}