Allow configuration of remember me through nested builder

Issue: gh-5557
This commit is contained in:
Eleftheria Stein 2019-07-02 14:56:08 -04:00
parent ae9eb6f56b
commit fcb119b94e
2 changed files with 115 additions and 0 deletions

View File

@ -934,6 +934,43 @@ public final class HttpSecurity extends
return getOrApply(new RememberMeConfigurer<>()); return getOrApply(new RememberMeConfigurer<>());
} }
/**
* Allows configuring of Remember Me authentication.
*
* <h2>Example Configuration</h2>
*
* The following configuration demonstrates how to allow token based remember me
* authentication. Upon authenticating if the HTTP parameter named "remember-me"
* exists, then the user will be remembered even after their
* {@link javax.servlet.http.HttpSession} expires.
*
* <pre>
* &#064;Configuration
* &#064;EnableWebSecurity
* public class RememberMeSecurityConfig extends WebSecurityConfigurerAdapter {
*
* &#064;Override
* protected void configure(HttpSecurity http) throws Exception {
* http
* .authorizeRequests()
* .antMatchers(&quot;/**&quot;).hasRole(&quot;USER&quot;)
* .and()
* .formLogin(withDefaults())
* .rememberMe(withDefaults());
* }
* }
* </pre>
*
* @param rememberMeCustomizer the {@link Customizer} to provide more options for
* the {@link RememberMeConfigurer}
* @return the {@link HttpSecurity} for further customizations
* @throws Exception
*/
public HttpSecurity rememberMe(Customizer<RememberMeConfigurer<HttpSecurity>> rememberMeCustomizer) throws Exception {
rememberMeCustomizer.customize(getOrApply(new RememberMeConfigurer<>()));
return HttpSecurity.this;
}
/** /**
* Allows restricting access based upon the {@link HttpServletRequest} using * Allows restricting access based upon the {@link HttpServletRequest} using
* *

View File

@ -51,6 +51,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
@ -299,6 +300,44 @@ public class RememberMeConfigurerTests {
} }
} }
@Test
public void loginWhenRememberMeConfiguredInLambdaThenRespondsWithRememberMeCookie() throws Exception {
this.spring.register(RememberMeInLambdaConfig.class).autowire();
this.mvc.perform(post("/login")
.with(csrf())
.param("username", "user")
.param("password", "password")
.param("remember-me", "true"))
.andExpect(cookie().exists("remember-me"));
}
@EnableWebSecurity
static class RememberMeInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin(withDefaults())
.rememberMe(withDefaults());
// @formatter:on
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test @Test
public void loginWhenRememberMeTrueAndCookieDomainThenRememberMeCookieHasDomain() throws Exception { public void loginWhenRememberMeTrueAndCookieDomainThenRememberMeCookieHasDomain() throws Exception {
this.spring.register(RememberMeCookieDomainConfig.class).autowire(); this.spring.register(RememberMeCookieDomainConfig.class).autowire();
@ -337,6 +376,45 @@ public class RememberMeConfigurerTests {
} }
} }
@Test
public void loginWhenRememberMeTrueAndCookieDomainInLambdaThenRememberMeCookieHasDomain() throws Exception {
this.spring.register(RememberMeCookieDomainInLambdaConfig.class).autowire();
this.mvc.perform(post("/login")
.with(csrf())
.param("username", "user")
.param("password", "password")
.param("remember-me", "true"))
.andExpect(cookie().exists("remember-me"))
.andExpect(cookie().domain("remember-me", "spring.io"));
}
@EnableWebSecurity
static class RememberMeCookieDomainInLambdaConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin(withDefaults())
.rememberMe(rememberMe ->
rememberMe
.rememberMeCookieDomain("spring.io")
);
// @formatter:on
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test @Test
public void configureWhenRememberMeCookieNameAndRememberMeServicesThenException() { public void configureWhenRememberMeCookieNameAndRememberMeServicesThenException() {
assertThatThrownBy(() -> this.spring.register(RememberMeCookieNameAndRememberMeServicesConfig.class).autowire()) assertThatThrownBy(() -> this.spring.register(RememberMeCookieNameAndRememberMeServicesConfig.class).autowire())