Add SecurityContextHolderFilter
Closes gh-9635
This commit is contained in:
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.security.config.annotation.web.configurers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -33,8 +37,11 @@ import org.springframework.security.config.test.SpringTestContext;
|
||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.userdetails.PasswordEncodedUser;
|
||||
import org.springframework.security.web.FilterChainProxy;
|
||||
import org.springframework.security.web.context.HttpRequestResponseHolder;
|
||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||
import org.springframework.security.web.context.NullSecurityContextRepository;
|
||||
import org.springframework.security.web.context.SecurityContextHolderFilter;
|
||||
import org.springframework.security.web.context.SecurityContextPersistenceFilter;
|
||||
import org.springframework.security.web.context.SecurityContextRepository;
|
||||
import org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter;
|
||||
@@ -110,6 +117,27 @@ public class SecurityContextConfigurerTests {
|
||||
assertThat(session).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requireExplicitSave() throws Exception {
|
||||
HttpSessionSecurityContextRepository repository = new HttpSessionSecurityContextRepository();
|
||||
SpringTestContext testContext = this.spring.register(RequireExplicitSaveConfig.class);
|
||||
testContext.autowire();
|
||||
FilterChainProxy filterChainProxy = testContext.getContext().getBean(FilterChainProxy.class);
|
||||
// @formatter:off
|
||||
List<Class<? extends Filter>> filterTypes = filterChainProxy.getFilters("/")
|
||||
.stream()
|
||||
.map(Filter::getClass)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(filterTypes)
|
||||
.contains(SecurityContextHolderFilter.class)
|
||||
.doesNotContain(SecurityContextPersistenceFilter.class);
|
||||
// @formatter:on
|
||||
MvcResult mvcResult = this.mvc.perform(formLogin()).andReturn();
|
||||
SecurityContext securityContext = repository
|
||||
.loadContext(new HttpRequestResponseHolder(mvcResult.getRequest(), mvcResult.getResponse()));
|
||||
assertThat(securityContext.getAuthentication()).isNotNull();
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@@ -241,14 +269,39 @@ public class SecurityContextConfigurerTests {
|
||||
@EnableWebSecurity
|
||||
static class NullSecurityContextRepositoryInLambdaConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.formLogin(withDefaults())
|
||||
.securityContext((securityContext) ->
|
||||
securityContext
|
||||
.securityContextRepository(new NullSecurityContextRepository())
|
||||
);
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||
// @formatter:off
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser(PasswordEncodedUser.user());
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableWebSecurity
|
||||
static class RequireExplicitSaveConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.formLogin(withDefaults())
|
||||
.securityContext((securityContext) ->
|
||||
securityContext
|
||||
.securityContextRepository(new NullSecurityContextRepository())
|
||||
.securityContext((securityContext) -> securityContext
|
||||
.requireExplicitSave(true)
|
||||
);
|
||||
// @formatter:on
|
||||
}
|
||||
@@ -258,7 +311,7 @@ public class SecurityContextConfigurerTests {
|
||||
// @formatter:off
|
||||
auth
|
||||
.inMemoryAuthentication()
|
||||
.withUser(PasswordEncodedUser.user());
|
||||
.withUser(PasswordEncodedUser.user());
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
|
||||
@@ -122,9 +122,11 @@ import static org.mockito.BDDMockito.willAnswer;
|
||||
import static org.mockito.Mockito.atLeastOnce;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
|
||||
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.x509;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
@@ -462,6 +464,37 @@ public class MiscHttpConfigTests {
|
||||
any(HttpServletResponse.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWhenExplicitSaveAndRepositoryAndAuthenticatingThenConsultsCustomSecurityContextRepository()
|
||||
throws Exception {
|
||||
this.spring.configLocations(xml("ExplicitSaveAndExplicitRepository")).autowire();
|
||||
SecurityContextRepository repository = this.spring.getContext().getBean(SecurityContextRepository.class);
|
||||
SecurityContext context = new SecurityContextImpl(new TestingAuthenticationToken("user", "password"));
|
||||
given(repository.loadContext(any(HttpRequestResponseHolder.class))).willReturn(context);
|
||||
// @formatter:off
|
||||
MvcResult result = this.mvc.perform(formLogin())
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(authenticated())
|
||||
.andReturn();
|
||||
// @formatter:on
|
||||
verify(repository, atLeastOnce()).saveContext(any(SecurityContext.class), any(HttpServletRequest.class),
|
||||
any(HttpServletResponse.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWhenExplicitSaveAndExplicitSaveAndAuthenticatingThenConsultsCustomSecurityContextRepository()
|
||||
throws Exception {
|
||||
this.spring.configLocations(xml("ExplicitSave")).autowire();
|
||||
SecurityContextRepository repository = this.spring.getContext().getBean(SecurityContextRepository.class);
|
||||
// @formatter:off
|
||||
MvcResult result = this.mvc.perform(formLogin())
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andReturn();
|
||||
// @formatter:on
|
||||
assertThat(repository.loadContext(new HttpRequestResponseHolder(result.getRequest(), result.getResponse()))
|
||||
.getAuthentication()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWhenUsingInterceptUrlExpressionsThenAuthorizesAccordingly() throws Exception {
|
||||
this.spring.configLocations(xml("InterceptUrlExpressions")).autowire();
|
||||
|
||||
Reference in New Issue
Block a user