Reformat code using spring-javaformat

Run `./gradlew format` to reformat all java files.

Issue gh-8945
This commit is contained in:
Phillip Webb
2020-08-10 16:39:17 -05:00
committed by Rob Winch
parent 81d9c6cac5
commit b7fc18262d
2487 changed files with 41506 additions and 46548 deletions

View File

@@ -25,19 +25,19 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
* @author Luke Taylor
*/
public class BeanNameCollectingPostProcessor implements BeanPostProcessor {
Set<String> beforeInitPostProcessedBeans = new HashSet<>();
Set<String> afterInitPostProcessedBeans = new HashSet<>();
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName != null) {
beforeInitPostProcessedBeans.add(beanName);
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName != null) {
afterInitPostProcessedBeans.add(beanName);
}
@@ -51,4 +51,5 @@ public class BeanNameCollectingPostProcessor implements BeanPostProcessor {
public Set<String> getAfterInitPostProcessedBeans() {
return afterInitPostProcessedBeans;
}
}

View File

@@ -30,9 +30,13 @@ import org.springframework.security.authentication.event.AbstractAuthenticationF
* @since 3.1
*/
public class CollectingAppListener implements ApplicationListener {
Set<ApplicationEvent> events = new HashSet<>();
Set<AbstractAuthenticationEvent> authenticationEvents = new HashSet<>();
Set<AbstractAuthenticationFailureEvent> authenticationFailureEvents = new HashSet<>();
Set<AbstractAuthorizationEvent> authorizationEvents = new HashSet<>();
public void onApplicationEvent(ApplicationEvent event) {
@@ -65,4 +69,5 @@ public class CollectingAppListener implements ApplicationListener {
public Set<AbstractAuthorizationEvent> getAuthorizationEvents() {
return authorizationEvents;
}
}

View File

@@ -16,14 +16,13 @@
package org.springframework.security.config;
public abstract class ConfigTestUtils {
public static final String AUTH_PROVIDER_XML = "<authentication-manager alias='authManager'>"
+ " <authentication-provider>"
+ " <user-service id='us'>"
+ " <authentication-provider>" + " <user-service id='us'>"
+ " <user name='bob' password='{noop}bobspassword' authorities='ROLE_A,ROLE_B' />"
+ " <user name='bill' password='{noop}billspassword' authorities='ROLE_A,ROLE_B,AUTH_OTHER' />"
+ " <user name='admin' password='{noop}password' authorities='ROLE_ADMIN,ROLE_USER' />"
+ " <user name='user' password='{noop}password' authorities='ROLE_USER' />"
+ " </user-service>"
+ " </authentication-provider>"
+ "</authentication-manager>";
+ " </user-service>" + " </authentication-provider>" + "</authentication-manager>";
}

View File

@@ -27,6 +27,7 @@ import org.springframework.util.Assert;
* @author Ben Alex
*/
public class DataSourcePopulator implements InitializingBean {
// ~ Instance fields
// ================================================================================================
@@ -35,8 +36,10 @@ public class DataSourcePopulator implements InitializingBean {
public void afterPropertiesSet() {
Assert.notNull(template, "dataSource required");
template.execute("CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(500) NOT NULL,ENABLED BOOLEAN NOT NULL);");
template.execute("CREATE TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME));");
template.execute(
"CREATE TABLE USERS(USERNAME VARCHAR_IGNORECASE(50) NOT NULL PRIMARY KEY,PASSWORD VARCHAR_IGNORECASE(500) NOT NULL,ENABLED BOOLEAN NOT NULL);");
template.execute(
"CREATE TABLE AUTHORITIES(USERNAME VARCHAR_IGNORECASE(50) NOT NULL,AUTHORITY VARCHAR_IGNORECASE(50) NOT NULL,CONSTRAINT FK_AUTHORITIES_USERS FOREIGN KEY(USERNAME) REFERENCES USERS(USERNAME));");
template.execute("CREATE UNIQUE INDEX IX_AUTH_USERNAME ON AUTHORITIES(USERNAME,AUTHORITY);");
/*
@@ -66,4 +69,5 @@ public class DataSourcePopulator implements InitializingBean {
public void setDataSource(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
}
}

View File

@@ -50,6 +50,7 @@ import org.springframework.security.web.util.matcher.AnyRequestMatcher;
* @author Ben Alex
*/
public class FilterChainProxyConfigTests {
private ClassPathXmlApplicationContext appCtx;
// ~ Methods
@@ -59,8 +60,7 @@ public class FilterChainProxyConfigTests {
public void loadContext() {
System.setProperty("sec1235.pattern1", "/login");
System.setProperty("sec1235.pattern2", "/logout");
appCtx = new ClassPathXmlApplicationContext(
"org/springframework/security/util/filtertest-valid.xml");
appCtx = new ClassPathXmlApplicationContext("org/springframework/security/util/filtertest-valid.xml");
}
@After
@@ -72,15 +72,13 @@ public class FilterChainProxyConfigTests {
@Test
public void normalOperation() throws Exception {
FilterChainProxy filterChainProxy = appCtx.getBean("filterChain",
FilterChainProxy.class);
FilterChainProxy filterChainProxy = appCtx.getBean("filterChain", FilterChainProxy.class);
doNormalOperation(filterChainProxy);
}
@Test
public void normalOperationWithNewConfig() throws Exception {
FilterChainProxy filterChainProxy = appCtx.getBean("newFilterChainProxy",
FilterChainProxy.class);
FilterChainProxy filterChainProxy = appCtx.getBean("newFilterChainProxy", FilterChainProxy.class);
filterChainProxy.setFirewall(new DefaultHttpFirewall());
checkPathAndFilterOrder(filterChainProxy);
doNormalOperation(filterChainProxy);
@@ -88,8 +86,7 @@ public class FilterChainProxyConfigTests {
@Test
public void normalOperationWithNewConfigRegex() throws Exception {
FilterChainProxy filterChainProxy = appCtx.getBean("newFilterChainProxyRegex",
FilterChainProxy.class);
FilterChainProxy filterChainProxy = appCtx.getBean("newFilterChainProxyRegex", FilterChainProxy.class);
filterChainProxy.setFirewall(new DefaultHttpFirewall());
checkPathAndFilterOrder(filterChainProxy);
doNormalOperation(filterChainProxy);
@@ -97,8 +94,7 @@ public class FilterChainProxyConfigTests {
@Test
public void normalOperationWithNewConfigNonNamespace() throws Exception {
FilterChainProxy filterChainProxy = appCtx.getBean(
"newFilterChainProxyNonNamespace", FilterChainProxy.class);
FilterChainProxy filterChainProxy = appCtx.getBean("newFilterChainProxyNonNamespace", FilterChainProxy.class);
filterChainProxy.setFirewall(new DefaultHttpFirewall());
checkPathAndFilterOrder(filterChainProxy);
doNormalOperation(filterChainProxy);
@@ -106,26 +102,24 @@ public class FilterChainProxyConfigTests {
@Test
public void pathWithNoMatchHasNoFilters() {
FilterChainProxy filterChainProxy = appCtx.getBean(
"newFilterChainProxyNoDefaultPath", FilterChainProxy.class);
FilterChainProxy filterChainProxy = appCtx.getBean("newFilterChainProxyNoDefaultPath", FilterChainProxy.class);
assertThat(filterChainProxy.getFilters("/nomatch")).isNull();
}
// SEC-1235
@Test
public void mixingPatternsAndPlaceholdersDoesntCauseOrderingIssues() {
FilterChainProxy fcp = appCtx.getBean("sec1235FilterChainProxy",
FilterChainProxy.class);
FilterChainProxy fcp = appCtx.getBean("sec1235FilterChainProxy", FilterChainProxy.class);
List<SecurityFilterChain> chains = fcp.getFilterChains();
assertThat(getPattern(chains.get(0))).isEqualTo("/login*");
assertThat(getPattern(chains.get(1))).isEqualTo("/logout");
assertThat(((DefaultSecurityFilterChain) chains.get(2)).getRequestMatcher() instanceof AnyRequestMatcher).isTrue();
assertThat(((DefaultSecurityFilterChain) chains.get(2)).getRequestMatcher() instanceof AnyRequestMatcher)
.isTrue();
}
private String getPattern(SecurityFilterChain chain) {
return ((AntPathRequestMatcher) ((DefaultSecurityFilterChain) chain)
.getRequestMatcher()).getPattern();
return ((AntPathRequestMatcher) ((DefaultSecurityFilterChain) chain).getRequestMatcher()).getPattern();
}
private void checkPathAndFilterOrder(FilterChainProxy filterChainProxy) {
@@ -158,13 +152,12 @@ public class FilterChainProxyConfigTests {
FilterChain chain = mock(FilterChain.class);
filterChainProxy.doFilter(request, response, chain);
verify(chain).doFilter(any(HttpServletRequest.class),
any(HttpServletResponse.class));
verify(chain).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class));
request.setServletPath("/a/path/which/doesnt/match/any/filter.html");
chain = mock(FilterChain.class);
filterChainProxy.doFilter(request, response, chain);
verify(chain).doFilter(any(HttpServletRequest.class),
any(HttpServletResponse.class));
verify(chain).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class));
}
}

View File

@@ -34,6 +34,7 @@ import org.springframework.security.config.util.InMemoryXmlApplicationContext;
* @author Luke Taylor
*/
public class InvalidConfigurationTests {
private InMemoryXmlApplicationContext appContext;
@After
@@ -65,8 +66,7 @@ public class InvalidConfigurationTests {
assertThat(cause instanceof NoSuchBeanDefinitionException).isTrue();
NoSuchBeanDefinitionException nsbe = (NoSuchBeanDefinitionException) cause;
assertThat(nsbe.getBeanName()).isEqualTo(BeanIds.AUTHENTICATION_MANAGER);
assertThat(nsbe.getMessage()).endsWith(
AuthenticationManagerFactoryBean.MISSING_BEAN_ERROR_MESSAGE);
assertThat(nsbe.getMessage()).endsWith(AuthenticationManagerFactoryBean.MISSING_BEAN_ERROR_MESSAGE);
}
}
@@ -80,4 +80,5 @@ public class InvalidConfigurationTests {
private void setContext(String context) {
appContext = new InMemoryXmlApplicationContext(context);
}
}

View File

@@ -24,9 +24,8 @@ import org.springframework.security.core.Authentication;
public class MockAfterInvocationProvider implements AfterInvocationProvider {
public Object decide(Authentication authentication, Object object,
Collection<ConfigAttribute> config, Object returnedObject)
throws AccessDeniedException {
public Object decide(Authentication authentication, Object object, Collection<ConfigAttribute> config,
Object returnedObject) throws AccessDeniedException {
return returnedObject;
}

View File

@@ -26,8 +26,8 @@ import java.util.List;
* @author Rob Winch
* @since 5.0.2
*/
public class MockEventListener<T extends ApplicationEvent>
implements ApplicationListener<T> {
public class MockEventListener<T extends ApplicationEvent> implements ApplicationListener<T> {
private List<T> events = new ArrayList<>();
public void onApplicationEvent(T event) {
@@ -37,4 +37,5 @@ public class MockEventListener<T extends ApplicationEvent>
public List<T> getEvents() {
return this.events;
}
}

View File

@@ -26,8 +26,8 @@ import org.springframework.transaction.TransactionStatus;
* @author Luke Taylor
*/
public class MockTransactionManager implements PlatformTransactionManager {
public TransactionStatus getTransaction(TransactionDefinition definition)
throws TransactionException {
public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
return mock(TransactionStatus.class);
}
@@ -36,4 +36,5 @@ public class MockTransactionManager implements PlatformTransactionManager {
public void rollback(TransactionStatus status) throws TransactionException {
}
}

View File

@@ -26,18 +26,16 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
*/
public class MockUserServiceBeanPostProcessor implements BeanPostProcessor {
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof PostProcessedMockUserDetailsService) {
((PostProcessedMockUserDetailsService) bean)
.setPostProcessorWasHere("Hello from the post processor!");
((PostProcessedMockUserDetailsService) bean).setPostProcessorWasHere("Hello from the post processor!");
}
return bean;
}
}

View File

@@ -19,6 +19,7 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
public class PostProcessedMockUserDetailsService implements UserDetailsService {
private String postProcessorWasHere;
public PostProcessedMockUserDetailsService() {
@@ -36,4 +37,5 @@ public class PostProcessedMockUserDetailsService implements UserDetailsService {
public UserDetails loadUserByUsername(String username) {
throw new UnsupportedOperationException("Not for actual use");
}
}

View File

@@ -41,7 +41,6 @@ import static org.powermock.api.mockito.PowerMockito.verifyStatic;
import static org.powermock.api.mockito.PowerMockito.verifyZeroInteractions;
/**
*
* @author Luke Taylor
* @author Rob Winch
* @since 3.0
@@ -50,15 +49,16 @@ import static org.powermock.api.mockito.PowerMockito.verifyZeroInteractions;
@PrepareForTest({ ClassUtils.class })
@PowerMockIgnore({ "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*", "javax.xml.parsers.*" })
public class SecurityNamespaceHandlerTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
private static final String XML_AUTHENTICATION_MANAGER = "<authentication-manager>"
+ " <authentication-provider>" + " <user-service id='us'>"
+ " <user name='bob' password='bobspassword' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>"
+ "</authentication-manager>";
private static final String XML_AUTHENTICATION_MANAGER = "<authentication-manager>" + " <authentication-provider>"
+ " <user-service id='us'>" + " <user name='bob' password='bobspassword' authorities='ROLE_A' />"
+ " </user-service>" + " </authentication-provider>" + "</authentication-manager>";
private static final String XML_HTTP_BLOCK = "<http auto-config='true'/>";
private static final String FILTER_CHAIN_PROXY_CLASSNAME = "org.springframework.security.web.FilterChainProxy";
@Test
@@ -74,15 +74,13 @@ public class SecurityNamespaceHandlerTests {
@Test
public void pre32SchemaAreNotSupported() {
try {
new InMemoryXmlApplicationContext(
"<user-service id='us'>"
+ " <user name='bob' password='bobspassword' authorities='ROLE_A' />"
+ "</user-service>", "3.0.3", null);
new InMemoryXmlApplicationContext("<user-service id='us'>"
+ " <user name='bob' password='bobspassword' authorities='ROLE_A' />" + "</user-service>", "3.0.3",
null);
fail("Expected BeanDefinitionParsingException");
}
catch (BeanDefinitionParsingException expected) {
assertThat(expected.getMessage().contains(
"You cannot use a spring-security-2.0.xsd"));
assertThat(expected.getMessage().contains("You cannot use a spring-security-2.0.xsd"));
}
}
@@ -91,8 +89,8 @@ public class SecurityNamespaceHandlerTests {
public void initDoesNotLogErrorWhenFilterChainProxyFailsToLoad() throws Exception {
String className = "javax.servlet.Filter";
spy(ClassUtils.class);
doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName",
eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName", eq(FILTER_CHAIN_PROXY_CLASSNAME),
any(ClassLoader.class));
Log logger = mock(Log.class);
SecurityNamespaceHandler handler = new SecurityNamespaceHandler();
@@ -111,8 +109,8 @@ public class SecurityNamespaceHandlerTests {
thrown.expect(BeanDefinitionParsingException.class);
thrown.expectMessage("NoClassDefFoundError: " + className);
spy(ClassUtils.class);
doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName",
eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName", eq(FILTER_CHAIN_PROXY_CLASSNAME),
any(ClassLoader.class));
new InMemoryXmlApplicationContext(XML_AUTHENTICATION_MANAGER + XML_HTTP_BLOCK);
}
@@ -120,8 +118,8 @@ public class SecurityNamespaceHandlerTests {
public void filterNoClassDefFoundErrorNoHttpBlock() throws Exception {
String className = "javax.servlet.Filter";
spy(ClassUtils.class);
doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName",
eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName", eq(FILTER_CHAIN_PROXY_CLASSNAME),
any(ClassLoader.class));
new InMemoryXmlApplicationContext(XML_AUTHENTICATION_MANAGER);
// should load just fine since no http block
}
@@ -151,9 +149,10 @@ public class SecurityNamespaceHandlerTests {
public void websocketNotFoundExceptionNoMessageBlock() throws Exception {
String className = FILTER_CHAIN_PROXY_CLASSNAME;
spy(ClassUtils.class);
doThrow(new ClassNotFoundException(className)).when(ClassUtils.class, "forName",
eq(Message.class.getName()), any(ClassLoader.class));
doThrow(new ClassNotFoundException(className)).when(ClassUtils.class, "forName", eq(Message.class.getName()),
any(ClassLoader.class));
new InMemoryXmlApplicationContext(XML_AUTHENTICATION_MANAGER);
// should load just fine since no websocket block
}
}

View File

@@ -29,4 +29,5 @@ public interface TestBusinessBean {
void doSomething();
void unprotected();
}

View File

@@ -21,8 +21,8 @@ import org.springframework.security.core.session.SessionCreationEvent;
/**
* @author Luke Taylor
*/
public class TestBusinessBeanImpl implements TestBusinessBean,
ApplicationListener<SessionCreationEvent> {
public class TestBusinessBeanImpl implements TestBusinessBean, ApplicationListener<SessionCreationEvent> {
public void setInteger(int i) {
}
@@ -46,4 +46,5 @@ public class TestBusinessBeanImpl implements TestBusinessBean,
public void onApplicationEvent(SessionCreationEvent event) {
System.out.println(event);
}
}

View File

@@ -21,6 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
* @author Luke Taylor
*/
public class TransactionalTestBusinessBean implements TestBusinessBean {
public void setInteger(int i) {
}
@@ -37,4 +38,5 @@ public class TransactionalTestBusinessBean implements TestBusinessBean {
public void unprotected() {
}
}

View File

@@ -22,8 +22,8 @@ import java.util.List;
* @author Rob Winch
*
*/
class ConcereteSecurityConfigurerAdapter extends
SecurityConfigurerAdapter<Object, SecurityBuilder<Object>> {
class ConcereteSecurityConfigurerAdapter extends SecurityConfigurerAdapter<Object, SecurityBuilder<Object>> {
private List<Object> list = new ArrayList<>();
@Override
@@ -35,4 +35,5 @@ class ConcereteSecurityConfigurerAdapter extends
this.list = l;
return this;
}
}

View File

@@ -32,8 +32,7 @@ public class ObjectPostProcessorTests {
@Test
public void convertTypes() {
assertThat((Object) PerformConversion.perform(new ArrayList<>()))
.isInstanceOf(LinkedList.class);
assertThat((Object) PerformConversion.perform(new ArrayList<>())).isInstanceOf(LinkedList.class);
}
static class ListToLinkedListObjectPostProcessor implements ObjectPostProcessor<List<?>> {
@@ -41,13 +40,15 @@ public class ObjectPostProcessorTests {
public <O extends List<?>> O postProcess(O l) {
return (O) new LinkedList(l);
}
}
static class PerformConversion {
public static List<?> perform(ArrayList<?> l) {
return new ListToLinkedListObjectPostProcessor().postProcess(l);
}
}
}

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.security.config.annotation;
import java.util.ArrayList;
import java.util.List;
@@ -30,6 +29,7 @@ import static org.mockito.Mockito.mock;
*
*/
public class SecurityConfigurerAdapterClosureTests {
ConcereteSecurityConfigurerAdapter conf = new ConcereteSecurityConfigurerAdapter();
@Test
@@ -49,8 +49,8 @@ public class SecurityConfigurerAdapterClosureTests {
assertThat(this.conf.list).contains("a");
}
static class ConcereteSecurityConfigurerAdapter extends
SecurityConfigurerAdapter<Object, SecurityBuilder<Object>> {
static class ConcereteSecurityConfigurerAdapter extends SecurityConfigurerAdapter<Object, SecurityBuilder<Object>> {
private List<Object> list = new ArrayList<Object>();
@Override
@@ -62,5 +62,7 @@ public class SecurityConfigurerAdapterClosureTests {
this.list = l;
return this;
}
}
}

View File

@@ -22,6 +22,7 @@ import org.junit.Test;
import org.springframework.core.Ordered;
public class SecurityConfigurerAdapterTests {
ConcereteSecurityConfigurerAdapter adapter;
@Before
@@ -39,6 +40,7 @@ public class SecurityConfigurerAdapterTests {
}
static class OrderedObjectPostProcessor implements ObjectPostProcessor<String>, Ordered {
private final int order;
OrderedObjectPostProcessor(int order) {
@@ -53,5 +55,7 @@ public class SecurityConfigurerAdapterTests {
public String postProcess(String object) {
return object + " " + order;
}
}
}

View File

@@ -63,6 +63,7 @@ import static org.springframework.security.test.web.servlet.response.SecurityMoc
* @author Rob Winch
*/
public class AuthenticationManagerBuilderTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -84,15 +85,14 @@ public class AuthenticationManagerBuilderTests {
ObjectPostProcessor<Object> opp = mock(ObjectPostProcessor.class);
AuthenticationEventPublisher aep = mock(AuthenticationEventPublisher.class);
when(opp.postProcess(any())).thenAnswer(a -> a.getArgument(0));
AuthenticationManager am = new AuthenticationManagerBuilder(opp)
.authenticationEventPublisher(aep)
.inMemoryAuthentication()
.and()
.build();
AuthenticationManager am = new AuthenticationManagerBuilder(opp).authenticationEventPublisher(aep)
.inMemoryAuthentication().and().build();
try {
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
} catch (AuthenticationException success) {}
}
catch (AuthenticationException success) {
}
verify(aep).publishAuthenticationFailure(any(), any());
}
@@ -100,8 +100,8 @@ public class AuthenticationManagerBuilderTests {
@Test
public void getAuthenticationManagerWhenGlobalPasswordEncoderBeanThenUsed() throws Exception {
this.spring.register(PasswordEncoderGlobalConfig.class).autowire();
AuthenticationManager manager = this.spring.getContext()
.getBean(AuthenticationConfiguration.class).getAuthenticationManager();
AuthenticationManager manager = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
Authentication auth = manager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
@@ -111,6 +111,7 @@ public class AuthenticationManagerBuilderTests {
@EnableWebSecurity
static class PasswordEncoderGlobalConfig extends WebSecurityConfigurerAdapter {
@Autowired
void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -124,13 +125,14 @@ public class AuthenticationManagerBuilderTests {
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
@Test
public void getAuthenticationManagerWhenProtectedPasswordEncoderBeanThenUsed() throws Exception {
this.spring.register(PasswordEncoderGlobalConfig.class).autowire();
AuthenticationManager manager = this.spring.getContext()
.getBean(AuthenticationConfiguration.class).getAuthenticationManager();
AuthenticationManager manager = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
Authentication auth = manager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
@@ -140,6 +142,7 @@ public class AuthenticationManagerBuilderTests {
@EnableWebSecurity
static class PasswordEncoderConfig extends WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
@@ -152,6 +155,7 @@ public class AuthenticationManagerBuilderTests {
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
@Autowired(required = false)
@@ -161,22 +165,18 @@ public class AuthenticationManagerBuilderTests {
public void authenticationManagerWhenMultipleProvidersThenWorks() throws Exception {
this.spring.register(MultiAuthenticationProvidersConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withUsername("user").withRoles("USER"));
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user").withRoles("USER"));
this.mockMvc.perform(formLogin().user("admin"))
.andExpect(authenticated().withUsername("admin").withRoles("USER", "ADMIN"));
.andExpect(authenticated().withUsername("admin").withRoles("USER", "ADMIN"));
}
@EnableWebSecurity
static class MultiAuthenticationProvidersConfig
extends WebSecurityConfigurerAdapter {
static class MultiAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user())
.and()
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.admin());
auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user()).and().inMemoryAuthentication()
.withUser(PasswordEncodedUser.admin());
}
}
@@ -219,7 +219,7 @@ public class AuthenticationManagerBuilderTests {
this.spring.register(UserFromPropertiesConfig.class).autowire();
this.mockMvc.perform(formLogin().user("joe", "joespassword"))
.andExpect(authenticated().withUsername("joe").withRoles("USER"));
.andExpect(authenticated().withUsername("joe").withRoles("USER"));
}
@Configuration
@@ -248,6 +248,7 @@ public class AuthenticationManagerBuilderTests {
properties.load(this.users.getInputStream());
return new InMemoryUserDetailsManager(properties);
}
}
}

View File

@@ -19,13 +19,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
/**
*
* @author Rob Winch
*/
@Configuration
public class BaseAuthenticationConfig {
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -35,4 +34,5 @@ public class BaseAuthenticationConfig {
.withUser("admin").password("password").roles("USER", "ADMIN");
// @formatter:on
}
}

View File

@@ -33,6 +33,7 @@ import static org.springframework.security.test.web.servlet.response.SecurityMoc
* @author Rob Winch
*/
public class NamespaceAuthenticationManagerTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -44,15 +45,16 @@ public class NamespaceAuthenticationManagerTests {
this.spring.register(EraseCredentialsTrueDefaultConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a-> assertThat(a.getCredentials()).isNull()));
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNull()));
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a-> assertThat(a.getCredentials()).isNull()));
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNull()));
// no exception due to username being cleared out
}
@EnableWebSecurity
static class EraseCredentialsTrueDefaultConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -61,6 +63,7 @@ public class NamespaceAuthenticationManagerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
@@ -68,15 +71,16 @@ public class NamespaceAuthenticationManagerTests {
this.spring.register(EraseCredentialsFalseConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a-> assertThat(a.getCredentials()).isNotNull()));
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a-> assertThat(a.getCredentials()).isNotNull()));
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
// no exception due to username being cleared out
}
@EnableWebSecurity
static class EraseCredentialsFalseConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -86,6 +90,7 @@ public class NamespaceAuthenticationManagerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
@@ -94,11 +99,12 @@ public class NamespaceAuthenticationManagerTests {
this.spring.register(GlobalEraseCredentialsFalseConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a-> assertThat(a.getCredentials()).isNotNull()));
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
}
@EnableWebSecurity
static class GlobalEraseCredentialsFalseConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -108,5 +114,7 @@ public class NamespaceAuthenticationManagerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
}

View File

@@ -49,12 +49,12 @@ public class NamespaceAuthenticationProviderTests {
public void authenticationProviderRef() throws Exception {
this.spring.register(AuthenticationProviderRefConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withUsername("user"));
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user"));
}
@EnableWebSecurity
static class AuthenticationProviderRefConfig extends WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) {
// @formatter:off
auth
@@ -68,6 +68,7 @@ public class NamespaceAuthenticationProviderTests {
result.setUserDetailsService(new InMemoryUserDetailsManager(PasswordEncodedUser.user()));
return result;
}
}
@Test
@@ -75,12 +76,12 @@ public class NamespaceAuthenticationProviderTests {
public void authenticationProviderUserServiceRef() throws Exception {
this.spring.register(AuthenticationProviderRefConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withUsername("user"));
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user"));
}
@EnableWebSecurity
static class UserServiceRefConfig extends WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
@@ -92,5 +93,7 @@ public class NamespaceAuthenticationProviderTests {
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(PasswordEncodedUser.user());
}
}
}

View File

@@ -53,12 +53,12 @@ public class NamespaceJdbcUserServiceTests {
public void jdbcUserService() throws Exception {
this.spring.register(DataSourceConfig.class, JdbcUserServiceConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withUsername("user"));
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user"));
}
@EnableWebSecurity
static class JdbcUserServiceConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@@ -71,27 +71,30 @@ public class NamespaceJdbcUserServiceTests {
.dataSource(this.dataSource); // jdbc-user-service@data-source-ref
// @formatter:on
}
}
@Configuration
static class DataSourceConfig {
@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.HSQL).build();
}
}
@Test
public void jdbcUserServiceCustom() throws Exception {
this.spring.register(CustomDataSourceConfig.class, CustomJdbcUserServiceSampleConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withUsername("user").withRoles("DBA", "USER"));
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user").withRoles("DBA", "USER"));
}
@EnableWebSecurity
static class CustomJdbcUserServiceSampleConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@@ -129,16 +132,22 @@ public class NamespaceJdbcUserServiceTests {
@Override
public void removeUserFromCache(String username) {
}
}
}
@Configuration
static class CustomDataSourceConfig {
@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
// simulate that the DB already has the schema loaded and users in it
.addScript("CustomJdbcUserServiceSampleConfig.sql");
// simulate that the DB already has the schema loaded and users in it
.addScript("CustomJdbcUserServiceSampleConfig.sql");
return builder.setType(EmbeddedDatabaseType.HSQL).build();
}
}
}

View File

@@ -52,12 +52,12 @@ public class NamespacePasswordEncoderTests {
public void passwordEncoderRefWithInMemory() throws Exception {
this.spring.register(PasswordEncoderWithInMemoryConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated());
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderWithInMemoryConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
@@ -68,18 +68,19 @@ public class NamespacePasswordEncoderTests {
.passwordEncoder(encoder);
// @formatter:on
}
}
@Test
public void passwordEncoderRefWithJdbc() throws Exception {
this.spring.register(PasswordEncoderWithJdbcConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated());
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderWithJdbcConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
@@ -99,18 +100,19 @@ public class NamespacePasswordEncoderTests {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.HSQL).build();
}
}
@Test
public void passwordEncoderRefWithUserDetailsService() throws Exception {
this.spring.register(PasswordEncoderWithUserDetailsServiceConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated());
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderWithUserDetailsServiceConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
@@ -134,5 +136,7 @@ public class NamespacePasswordEncoderTests {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
return builder.setType(EmbeddedDatabaseType.HSQL).build();
}
}
}

View File

@@ -49,6 +49,7 @@ public class PasswordEncoderConfigurerTests {
@EnableWebSecurity
static class PasswordEncoderConfig extends WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder encoder = passwordEncoder();
// @formatter:off
@@ -67,19 +68,19 @@ public class PasswordEncoderConfigurerTests {
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@Test
public void passwordEncoderRefWhenAuthenticationManagerBuilderThenAuthenticationSuccess() throws Exception {
this.spring.register(PasswordEncoderNoAuthManagerLoadsConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated());
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderNoAuthManagerLoadsConfig extends
WebSecurityConfigurerAdapter {
static class PasswordEncoderNoAuthManagerLoadsConfig extends WebSecurityConfigurerAdapter {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder encoder = passwordEncoder();
// @formatter:off
@@ -94,5 +95,7 @@ public class PasswordEncoderConfigurerTests {
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
}

View File

@@ -37,6 +37,7 @@ import static org.assertj.core.api.Assertions.*;
*/
@RunWith(SpringJUnit4ClassRunner.class)
public class AuthenticationConfigurationPublishTests {
@Autowired
MockEventListener<AuthenticationSuccessEvent> listener;
@@ -58,6 +59,7 @@ public class AuthenticationConfigurationPublishTests {
@EnableGlobalAuthentication
@Import(AuthenticationTestConfiguration.class)
static class Config {
@Bean
AuthenticationEventPublisher publisher() {
return new DefaultAuthenticationEventPublisher();
@@ -65,8 +67,10 @@ public class AuthenticationConfigurationPublishTests {
@Bean
MockEventListener<AuthenticationSuccessEvent> eventListener() {
return new MockEventListener<AuthenticationSuccessEvent>(){};
return new MockEventListener<AuthenticationSuccessEvent>() {
};
}
}
}

View File

@@ -79,81 +79,100 @@ public class AuthenticationConfigurationTests {
@Test
public void orderingAutowiredOnEnableGlobalMethodSecurity() {
this.spring.register(AuthenticationTestConfiguration.class, GlobalMethodSecurityAutowiredConfig.class, ServicesConfig.class).autowire();
this.spring.register(AuthenticationTestConfiguration.class, GlobalMethodSecurityAutowiredConfig.class,
ServicesConfig.class).autowire();
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
this.service.run();
}
@EnableGlobalMethodSecurity(securedEnabled = true)
static class GlobalMethodSecurityAutowiredConfig {
}
@Test
public void orderingAutowiredOnEnableWebSecurity() {
this.spring.register(AuthenticationTestConfiguration.class, WebSecurityConfig.class, GlobalMethodSecurityAutowiredConfig.class, ServicesConfig.class).autowire();
this.spring.register(AuthenticationTestConfiguration.class, WebSecurityConfig.class,
GlobalMethodSecurityAutowiredConfig.class, ServicesConfig.class).autowire();
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
this.service.run();
}
@EnableWebSecurity
static class WebSecurityConfig {}
static class WebSecurityConfig {
}
@Test
public void orderingAutowiredOnEnableWebMvcSecurity() {
this.spring.register(AuthenticationTestConfiguration.class, WebMvcSecurityConfig.class, GlobalMethodSecurityAutowiredConfig.class, ServicesConfig.class).autowire();
this.spring.register(AuthenticationTestConfiguration.class, WebMvcSecurityConfig.class,
GlobalMethodSecurityAutowiredConfig.class, ServicesConfig.class).autowire();
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
this.service.run();
}
@EnableWebMvcSecurity
static class WebMvcSecurityConfig {}
static class WebMvcSecurityConfig {
}
@Test
public void getAuthenticationManagerWhenNoAuthenticationThenNull() throws Exception {
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class).autowire();
assertThat(this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager()).isNull();
assertThat(this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager())
.isNull();
}
@Test
public void getAuthenticationManagerWhenNoOpGlobalAuthenticationConfigurerAdapterThenNull() throws Exception {
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class, NoOpGlobalAuthenticationConfigurerAdapter.class).autowire();
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class,
NoOpGlobalAuthenticationConfigurerAdapter.class).autowire();
assertThat(this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager()).isNull();
assertThat(this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager())
.isNull();
}
@Configuration
static class NoOpGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {}
static class NoOpGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
}
@Test
public void getAuthenticationWhenGlobalAuthenticationConfigurerAdapterThenAuthenticates() throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class, UserGlobalAuthenticationConfigurerAdapter.class).autowire();
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class,
UserGlobalAuthenticationConfigurerAdapter.class).autowire();
AuthenticationManager authentication = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
AuthenticationManager authentication = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
assertThat(authentication.authenticate(token).getName()).isEqualTo(token.getName());
}
@Configuration
static class UserGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user());
}
}
@Test
public void getAuthenticationWhenAuthenticationManagerBeanThenAuthenticates() throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class, AuthenticationManagerBeanConfig.class).autowire();
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class,
AuthenticationManagerBeanConfig.class).autowire();
AuthenticationManager authentication = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
AuthenticationManager authentication = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
when(authentication.authenticate(token)).thenReturn(TestAuthentication.authenticatedUser());
assertThat(authentication.authenticate(token).getName()).isEqualTo(token.getName());
@@ -161,70 +180,93 @@ public class AuthenticationConfigurationTests {
@Configuration
static class AuthenticationManagerBeanConfig {
AuthenticationManager authenticationManager = mock(AuthenticationManager.class);
@Bean
public AuthenticationManager authenticationManager() {
return this.authenticationManager;
}
}
//
// //
//
@Configuration
static class ServicesConfig {
@Bean
public Service service() {
return new ServiceImpl();
}
//
// //
//
@Configuration
static class ServicesConfig {
@Bean
public Service service() {
return new ServiceImpl();
}
interface Service {
void run();
}
interface Service {
void run();
}
static class ServiceImpl implements Service {
@Secured("ROLE_USER")
public void run() {
}
static class ServiceImpl implements Service {
@Secured("ROLE_USER")
public void run() {}
}
@Test
public void getAuthenticationWhenMultipleThenOrdered() throws Exception {
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class,
AuthenticationManagerBeanConfig.class).autowire();
AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
config.setGlobalAuthenticationConfigurers(Arrays.asList(new LowestOrderGlobalAuthenticationConfigurerAdapter(),
new HighestOrderGlobalAuthenticationConfigurerAdapter(),
new DefaultOrderGlobalAuthenticationConfigurerAdapter()));
}
static class DefaultOrderGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
static List<Class<?>> inits = new ArrayList<>();
static List<Class<?>> configs = new ArrayList<>();
public void init(AuthenticationManagerBuilder auth) throws Exception {
inits.add(getClass());
}
@Test
public void getAuthenticationWhenMultipleThenOrdered() throws Exception {
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class, AuthenticationManagerBeanConfig.class).autowire();
AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
config.setGlobalAuthenticationConfigurers(Arrays.asList(new LowestOrderGlobalAuthenticationConfigurerAdapter(), new HighestOrderGlobalAuthenticationConfigurerAdapter(), new DefaultOrderGlobalAuthenticationConfigurerAdapter()));
public void configure(AuthenticationManagerBuilder auth) {
configs.add(getClass());
}
static class DefaultOrderGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
static List<Class<?>> inits = new ArrayList<>();
static List<Class<?>> configs = new ArrayList<>();
}
public void init(AuthenticationManagerBuilder auth) throws Exception {
inits.add(getClass());
}
@Order(Ordered.LOWEST_PRECEDENCE)
static class LowestOrderGlobalAuthenticationConfigurerAdapter
extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
public void configure(AuthenticationManagerBuilder auth) {
configs.add(getClass());
}
}
}
@Order(Ordered.LOWEST_PRECEDENCE)
static class LowestOrderGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {}
@Order(Ordered.HIGHEST_PRECEDENCE)
static class HighestOrderGlobalAuthenticationConfigurerAdapter
extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
@Order(Ordered.HIGHEST_PRECEDENCE)
static class HighestOrderGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {}
}
@Test
public void getAuthenticationWhenConfiguredThenBootNotTrigger() throws Exception {
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class).autowire();
AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
config.setGlobalAuthenticationConfigurers(Arrays.asList(new ConfiguresInMemoryConfigurerAdapter(), new BootGlobalAuthenticationConfigurerAdapter()));
config.setGlobalAuthenticationConfigurers(Arrays.asList(new ConfiguresInMemoryConfigurerAdapter(),
new BootGlobalAuthenticationConfigurerAdapter()));
AuthenticationManager authenticationManager = config.getAuthenticationManager();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
assertThatThrownBy(() -> authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot", "password")))
.isInstanceOf(AuthenticationException.class);
assertThatThrownBy(
() -> authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot", "password")))
.isInstanceOf(AuthenticationException.class);
}
@@ -247,16 +289,21 @@ public class AuthenticationConfigurationTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Order(Ordered.LOWEST_PRECEDENCE)
static class BootGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.apply(new DefaultBootGlobalAuthenticationConfigurerAdapter());
}
}
static class DefaultBootGlobalAuthenticationConfigurerAdapter extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
static class DefaultBootGlobalAuthenticationConfigurerAdapter
extends DefaultOrderGlobalAuthenticationConfigurerAdapter {
@Override
public void configure(AuthenticationManagerBuilder auth) {
if (auth.isConfigured()) {
@@ -273,6 +320,7 @@ public class AuthenticationConfigurationTests {
auth.authenticationProvider(provider);
}
}
// gh-2531
@@ -301,6 +349,7 @@ public class AuthenticationConfigurationTests {
public AuthenticationManager manager() {
return null;
}
}
@Test
@@ -313,19 +362,24 @@ public class AuthenticationConfigurationTests {
@Configuration
@Import(AuthenticationConfiguration.class)
static class Sec2822Config {}
static class Sec2822Config {
}
@Configuration
@EnableWebSecurity
static class Sec2822WebSecurity extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication();
}
}
@Configuration
static class Sec2822UseAuth {
@Autowired
public void useAuthenticationManager(AuthenticationConfiguration auth) throws Exception {
auth.getAuthenticationManager();
@@ -338,52 +392,62 @@ public class AuthenticationConfigurationTests {
return new BootGlobalAuthenticationConfigurerAdapter();
}
static class BootGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter { }
static class BootGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
}
}
// sec-2868
@Test
public void getAuthenticationWhenUserDetailsServiceBeanThenAuthenticationManagerUsesUserDetailsServiceBean() throws Exception {
public void getAuthenticationWhenUserDetailsServiceBeanThenAuthenticationManagerUsesUserDetailsServiceBean()
throws Exception {
this.spring.register(UserDetailsServiceBeanConfig.class).autowire();
UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
when(uds.loadUserByUsername("user")).thenReturn(PasswordEncodedUser.user(), PasswordEncodedUser.user());
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
assertThatThrownBy(() -> am.authenticate(new UsernamePasswordAuthenticationToken("user", "invalid")))
.isInstanceOf(AuthenticationException.class);
.isInstanceOf(AuthenticationException.class);
}
@Configuration
@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class UserDetailsServiceBeanConfig {
UserDetailsService uds = mock(UserDetailsService.class);
@Bean
UserDetailsService userDetailsService() {
return this.uds;
}
}
@Test
public void getAuthenticationWhenUserDetailsServiceAndPasswordEncoderBeanThenEncoderUsed() throws Exception {
UserDetails user = new User("user", "$2a$10$FBAKClV1zBIOOC9XMXf3AO8RoGXYVYsfvUdoLxGkd/BnXEn4tqT3u",
AuthorityUtils.createAuthorityList("ROLE_USER"));
AuthorityUtils.createAuthorityList("ROLE_USER"));
this.spring.register(UserDetailsServiceBeanWithPasswordEncoderConfig.class).autowire();
UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
when(uds.loadUserByUsername("user")).thenReturn(User.withUserDetails(user).build(), User.withUserDetails(user).build());
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
when(uds.loadUserByUsername("user")).thenReturn(User.withUserDetails(user).build(),
User.withUserDetails(user).build());
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
assertThatThrownBy(() -> am.authenticate(new UsernamePasswordAuthenticationToken("user", "invalid")))
.isInstanceOf(AuthenticationException.class);
.isInstanceOf(AuthenticationException.class);
}
@Configuration
@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class UserDetailsServiceBeanWithPasswordEncoderConfig {
UserDetailsService uds = mock(UserDetailsService.class);
@Bean
@@ -395,16 +459,19 @@ public class AuthenticationConfigurationTests {
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@Test
public void getAuthenticationWhenUserDetailsServiceAndPasswordManagerThenManagerUsed() throws Exception {
UserDetails user = new User("user", "{noop}password",
AuthorityUtils.createAuthorityList("ROLE_USER"));
UserDetails user = new User("user", "{noop}password", AuthorityUtils.createAuthorityList("ROLE_USER"));
this.spring.register(UserDetailsPasswordManagerBeanConfig.class).autowire();
UserDetailsPasswordManagerBeanConfig.Manager manager = this.spring.getContext().getBean(UserDetailsPasswordManagerBeanConfig.Manager.class);
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
when(manager.loadUserByUsername("user")).thenReturn(User.withUserDetails(user).build(), User.withUserDetails(user).build());
UserDetailsPasswordManagerBeanConfig.Manager manager = this.spring.getContext()
.getBean(UserDetailsPasswordManagerBeanConfig.Manager.class);
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
when(manager.loadUserByUsername("user")).thenReturn(User.withUserDetails(user).build(),
User.withUserDetails(user).build());
when(manager.updatePassword(any(), any())).thenReturn(user);
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
@@ -413,8 +480,9 @@ public class AuthenticationConfigurationTests {
}
@Configuration
@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class UserDetailsPasswordManagerBeanConfig {
Manager manager = mock(Manager.class);
@Bean
@@ -423,15 +491,18 @@ public class AuthenticationConfigurationTests {
}
interface Manager extends UserDetailsService, UserDetailsPasswordService {
}
}
//gh-3091
// gh-3091
@Test
public void getAuthenticationWhenAuthenticationProviderBeanThenUsed() throws Exception {
this.spring.register(AuthenticationProviderBeanConfig.class).autowire();
AuthenticationProvider ap = this.spring.getContext().getBean(AuthenticationProvider.class);
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
when(ap.supports(any())).thenReturn(true);
when(ap.authenticate(any())).thenReturn(TestAuthentication.authenticatedUser());
@@ -439,21 +510,25 @@ public class AuthenticationConfigurationTests {
}
@Configuration
@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class AuthenticationProviderBeanConfig {
AuthenticationProvider provider = mock(AuthenticationProvider.class);
@Bean
AuthenticationProvider authenticationProvider() {
return this.provider;
}
}
@Test
public void getAuthenticationWhenAuthenticationProviderAndUserDetailsBeanThenAuthenticationProviderUsed() throws Exception {
public void getAuthenticationWhenAuthenticationProviderAndUserDetailsBeanThenAuthenticationProviderUsed()
throws Exception {
this.spring.register(AuthenticationProviderBeanAndUserDetailsServiceConfig.class).autowire();
AuthenticationProvider ap = this.spring.getContext().getBean(AuthenticationProvider.class);
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
AuthenticationManager am = this.spring.getContext().getBean(AuthenticationConfiguration.class)
.getAuthenticationManager();
when(ap.supports(any())).thenReturn(true);
when(ap.authenticate(any())).thenReturn(TestAuthentication.authenticatedUser());
@@ -461,8 +536,9 @@ public class AuthenticationConfigurationTests {
}
@Configuration
@Import({AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class})
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class AuthenticationProviderBeanAndUserDetailsServiceConfig {
AuthenticationProvider provider = mock(AuthenticationProvider.class);
UserDetailsService uds = mock(UserDetailsService.class);
@@ -476,11 +552,13 @@ public class AuthenticationConfigurationTests {
AuthenticationProvider authenticationProvider() {
return this.provider;
}
}
@Test
public void enableGlobalMethodSecurityWhenPreAuthorizeThenNoException() {
this.spring.register(UsesPreAuthorizeMethodSecurityConfig.class, AuthenticationManagerBeanConfig.class).autowire();
this.spring.register(UsesPreAuthorizeMethodSecurityConfig.class, AuthenticationManagerBeanConfig.class)
.autowire();
// no exception
}
@@ -488,13 +566,17 @@ public class AuthenticationConfigurationTests {
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class UsesPreAuthorizeMethodSecurityConfig {
@PreAuthorize("denyAll")
void run() {}
void run() {
}
}
@Test
public void enableGlobalMethodSecurityWhenPreAuthorizeThenUsesMethodSecurityService() {
this.spring.register(ServicesConfig.class, UsesPreAuthorizeMethodSecurityConfig.class, AuthenticationManagerBeanConfig.class).autowire();
this.spring.register(ServicesConfig.class, UsesPreAuthorizeMethodSecurityConfig.class,
AuthenticationManagerBeanConfig.class).autowire();
// no exception
}
@@ -502,8 +584,10 @@ public class AuthenticationConfigurationTests {
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
static class UsesServiceMethodSecurityConfig {
@Autowired
Service service;
}
@Test
@@ -537,11 +621,12 @@ public class AuthenticationConfigurationTests {
this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
assertThatThrownBy(ap::build)
.isInstanceOf(AlreadyBuiltException.class);
assertThatThrownBy(ap::build).isInstanceOf(AlreadyBuiltException.class);
}
@Configuration
static class AuthenticationConfigurationSubclass extends AuthenticationConfiguration {
}
}

View File

@@ -26,11 +26,11 @@ import org.springframework.security.config.annotation.authentication.builders.Au
import org.springframework.security.config.test.SpringTestRule;
/**
*
* @author Rob Winch
*
*/
public class EnableGlobalAuthenticationTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -52,6 +52,7 @@ public class EnableGlobalAuthenticationTests {
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
}
}
@Test
@@ -66,6 +67,7 @@ public class EnableGlobalAuthenticationTests {
@EnableGlobalAuthentication
static class BeanProxyEnabledByDefaultConfig {
@Bean
public Child child() {
return new Child();
@@ -75,6 +77,7 @@ public class EnableGlobalAuthenticationTests {
public Parent parent() {
return new Parent(child());
}
}
@Test
@@ -90,6 +93,7 @@ public class EnableGlobalAuthenticationTests {
@Configuration(proxyBeanMethods = false)
@EnableGlobalAuthentication
static class BeanProxyDisabledConfig {
@Bean
public Child child() {
return new Child();
@@ -99,9 +103,11 @@ public class EnableGlobalAuthenticationTests {
public Parent parent() {
return new Parent(child());
}
}
static class Parent {
private Child child;
Parent(Child child) {
@@ -111,10 +117,14 @@ public class EnableGlobalAuthenticationTests {
public Child getChild() {
return child;
}
}
static class Child {
Child() {
}
}
}

View File

@@ -41,4 +41,5 @@ public class LdapAuthenticationProviderConfigurerTests {
assertThat(configurer.getAuthoritiesMapper()).isInstanceOf(NullAuthoritiesMapper.class);
}
}

View File

@@ -28,10 +28,9 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
/**
*
* @author Rob Winch
* @author Adolfo Eloy
*/
* @author Rob Winch
* @author Adolfo Eloy
*/
public class UserDetailsManagerConfigurerTests {
private InMemoryUserDetailsManager userDetailsManager;
@@ -43,16 +42,9 @@ public class UserDetailsManagerConfigurerTests {
@Test
public void allAttributesSupported() {
UserDetails userDetails = new UserDetailsManagerConfigurer<AuthenticationManagerBuilder,
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>(userDetailsManager)
.withUser("user")
.password("password")
.roles("USER")
.disabled(true)
.accountExpired(true)
.accountLocked(true)
.credentialsExpired(true)
.build();
UserDetails userDetails = new UserDetailsManagerConfigurer<AuthenticationManagerBuilder, InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>(
userDetailsManager).withUser("user").password("password").roles("USER").disabled(true)
.accountExpired(true).accountLocked(true).credentialsExpired(true).build();
assertThat(userDetails.getUsername()).isEqualTo("user");
assertThat(userDetails.getPassword()).isEqualTo("password");
@@ -67,12 +59,8 @@ public class UserDetailsManagerConfigurerTests {
public void authoritiesWithGrantedAuthorityWorks() {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
UserDetails userDetails = new UserDetailsManagerConfigurer<AuthenticationManagerBuilder,
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>(userDetailsManager)
.withUser("user")
.password("password")
.authorities(authority)
.build();
UserDetails userDetails = new UserDetailsManagerConfigurer<AuthenticationManagerBuilder, InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>(
userDetailsManager).withUser("user").password("password").authorities(authority).build();
assertThat(userDetails.getAuthorities().stream().findFirst().get()).isEqualTo(authority);
}
@@ -81,12 +69,8 @@ public class UserDetailsManagerConfigurerTests {
public void authoritiesWithStringAuthorityWorks() {
String authority = "ROLE_USER";
UserDetails userDetails = new UserDetailsManagerConfigurer<AuthenticationManagerBuilder,
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>(userDetailsManager)
.withUser("user")
.password("password")
.authorities(authority)
.build();
UserDetails userDetails = new UserDetailsManagerConfigurer<AuthenticationManagerBuilder, InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>(
userDetailsManager).withUser("user").password("password").authorities(authority).build();
assertThat(userDetails.getAuthorities().stream().findFirst().get().getAuthority()).isEqualTo(authority);
}
@@ -95,13 +79,10 @@ public class UserDetailsManagerConfigurerTests {
public void authoritiesWithAListOfGrantedAuthorityWorks() {
SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_USER");
UserDetails userDetails = new UserDetailsManagerConfigurer<AuthenticationManagerBuilder,
InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>(userDetailsManager)
.withUser("user")
.password("password")
.authorities(Arrays.asList(authority))
.build();
UserDetails userDetails = new UserDetailsManagerConfigurer<AuthenticationManagerBuilder, InMemoryUserDetailsManagerConfigurer<AuthenticationManagerBuilder>>(
userDetailsManager).withUser("user").password("password").authorities(Arrays.asList(authority)).build();
assertThat(userDetails.getAuthorities().stream().findFirst().get()).isEqualTo(authority);
}
}

View File

@@ -19,7 +19,9 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundMethodInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
return String.valueOf(methodInvocation.proceed());
}
}

View File

@@ -39,10 +39,10 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
*
* @author Rob Winch
*/
public class AutowireBeanFactoryObjectPostProcessorTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -127,10 +127,12 @@ public class AutowireBeanFactoryObjectPostProcessorTests {
@Configuration
static class Config {
@Bean
public ObjectPostProcessor objectPostProcessor(AutowireCapableBeanFactory beanFactory) {
return new AutowireBeanFactoryObjectPostProcessor(beanFactory);
}
}
@Test
@@ -144,12 +146,14 @@ public class AutowireBeanFactoryObjectPostProcessorTests {
@Configuration
static class SmartConfig {
SmartInitializingSingleton toTest = mock(SmartInitializingSingleton.class);
@Autowired
public void configure(ObjectPostProcessor<Object> p) {
p.postProcess(this.toTest);
}
}
@Test
@@ -164,6 +168,7 @@ public class AutowireBeanFactoryObjectPostProcessorTests {
@Configuration
static class WithBeanNameAutoProxyCreatorConfig {
@Bean
public ObjectPostProcessor objectPostProcessor(AutowireCapableBeanFactory beanFactory) {
return new AutowireBeanFactoryObjectPostProcessor(beanFactory);
@@ -173,5 +178,7 @@ public class AutowireBeanFactoryObjectPostProcessorTests {
public void configure(ObjectPostProcessor<Object> p) {
p.postProcess(new Object());
}
}
}

View File

@@ -20,4 +20,5 @@ public class MyAdvisedBean {
public Object doStuff() {
return null;
}
}

View File

@@ -38,6 +38,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableJpaRepositories("org.springframework.security.config.annotation.issue50.repo")
@EnableTransactionManagement
public class ApplicationConfig {
@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
@@ -65,4 +66,5 @@ public class ApplicationConfig {
txManager.setEntityManagerFactory(entityManagerFactory().getObject());
return txManager;
}
}

View File

@@ -43,8 +43,9 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@Transactional
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {ApplicationConfig.class, SecurityConfig.class})
@ContextConfiguration(classes = { ApplicationConfig.class, SecurityConfig.class })
public class Issue50Tests {
@Autowired
private AuthenticationManager authenticationManager;
@@ -53,7 +54,8 @@ public class Issue50Tests {
@Before
public void setup() {
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("test", null, "ROLE_ADMIN"));
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("test", null, "ROLE_ADMIN"));
}
@After
@@ -82,7 +84,7 @@ public class Issue50Tests {
public void authenticateWhenValidUserThenAuthenticates() {
this.userRepo.save(User.withUsernameAndPassword("test", "password"));
Authentication result = this.authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken("test", "password"));
.authenticate(new UsernamePasswordAuthenticationToken("test", "password"));
assertThat(result.getName()).isEqualTo("test");
}
@@ -91,6 +93,7 @@ public class Issue50Tests {
SecurityContextHolder.getContext().setAuthentication(new TestingAuthenticationToken("test", null, "ROLE_USER"));
this.userRepo.save(User.withUsernameAndPassword("denied", "password"));
Authentication result = this.authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken("test", "password"));
.authenticate(new UsernamePasswordAuthenticationToken("test", "password"));
}
}

View File

@@ -42,6 +42,7 @@ import org.springframework.util.Assert;
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserRepository myUserRepository;
@@ -76,14 +77,12 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
return true;
}
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Object principal = authentication.getPrincipal();
String username = String.valueOf(principal);
User user = myUserRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("No user for principal "
+ principal);
throw new UsernameNotFoundException("No user for principal " + principal);
}
if (!authentication.getCredentials().equals(user.getPassword())) {
throw new BadCredentialsException("Invalid password");
@@ -92,4 +91,5 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
}
};
}
}

View File

@@ -63,6 +63,7 @@ public class User {
User user = new User();
user.setUsername(username);
user.setPassword(password);
return user;
return user;
}
}

View File

@@ -27,4 +27,5 @@ public interface UserRepository extends CrudRepository<User, String> {
@PreAuthorize("hasRole('ROLE_ADMIN')")
User findByUsername(String username);
}

View File

@@ -35,7 +35,7 @@ public class Authz {
}
public boolean check(Authentication authentication, String message) {
return message != null &&
message.contains(authentication.getName());
return message != null && message.contains(authentication.getName());
}
}

View File

@@ -22,6 +22,7 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class DelegatingReactiveMessageService implements ReactiveMessageService {
private final ReactiveMessageService delegate;
public DelegatingReactiveMessageService(ReactiveMessageService delegate) {
@@ -41,29 +42,25 @@ public class DelegatingReactiveMessageService implements ReactiveMessageService
@Override
@PreAuthorize("hasRole('ADMIN')")
public Mono<String> monoPreAuthorizeHasRoleFindById(
long id) {
public Mono<String> monoPreAuthorizeHasRoleFindById(long id) {
return delegate.monoPreAuthorizeHasRoleFindById(id);
}
@Override
@PostAuthorize("returnObject?.contains(authentication?.name)")
public Mono<String> monoPostAuthorizeFindById(
long id) {
public Mono<String> monoPostAuthorizeFindById(long id) {
return delegate.monoPostAuthorizeFindById(id);
}
@Override
@PreAuthorize("@authz.check(#id)")
public Mono<String> monoPreAuthorizeBeanFindById(
long id) {
public Mono<String> monoPreAuthorizeBeanFindById(long id) {
return delegate.monoPreAuthorizeBeanFindById(id);
}
@Override
@PostAuthorize("@authz.check(authentication, returnObject)")
public Mono<String> monoPostAuthorizeBeanFindById(
long id) {
public Mono<String> monoPostAuthorizeBeanFindById(long id) {
return delegate.monoPostAuthorizeBeanFindById(id);
}
@@ -74,29 +71,25 @@ public class DelegatingReactiveMessageService implements ReactiveMessageService
@Override
@PreAuthorize("hasRole('ADMIN')")
public Flux<String> fluxPreAuthorizeHasRoleFindById(
long id) {
public Flux<String> fluxPreAuthorizeHasRoleFindById(long id) {
return delegate.fluxPreAuthorizeHasRoleFindById(id);
}
@Override
@PostAuthorize("returnObject?.contains(authentication?.name)")
public Flux<String> fluxPostAuthorizeFindById(
long id) {
public Flux<String> fluxPostAuthorizeFindById(long id) {
return delegate.fluxPostAuthorizeFindById(id);
}
@Override
@PreAuthorize("@authz.check(#id)")
public Flux<String> fluxPreAuthorizeBeanFindById(
long id) {
public Flux<String> fluxPreAuthorizeBeanFindById(long id) {
return delegate.fluxPreAuthorizeBeanFindById(id);
}
@Override
@PostAuthorize("@authz.check(authentication, returnObject)")
public Flux<String> fluxPostAuthorizeBeanFindById(
long id) {
public Flux<String> fluxPostAuthorizeBeanFindById(long id) {
return delegate.fluxPostAuthorizeBeanFindById(id);
}
@@ -107,29 +100,26 @@ public class DelegatingReactiveMessageService implements ReactiveMessageService
@Override
@PreAuthorize("hasRole('ADMIN')")
public Publisher<String> publisherPreAuthorizeHasRoleFindById(
long id) {
public Publisher<String> publisherPreAuthorizeHasRoleFindById(long id) {
return delegate.publisherPreAuthorizeHasRoleFindById(id);
}
@Override
@PostAuthorize("returnObject?.contains(authentication?.name)")
public Publisher<String> publisherPostAuthorizeFindById(
long id) {
public Publisher<String> publisherPostAuthorizeFindById(long id) {
return delegate.publisherPostAuthorizeFindById(id);
}
@Override
@PreAuthorize("@authz.check(#id)")
public Publisher<String> publisherPreAuthorizeBeanFindById(
long id) {
public Publisher<String> publisherPreAuthorizeBeanFindById(long id) {
return delegate.publisherPreAuthorizeBeanFindById(id);
}
@Override
@PostAuthorize("@authz.check(authentication, returnObject)")
public Publisher<String> publisherPostAuthorizeBeanFindById(
long id) {
public Publisher<String> publisherPostAuthorizeBeanFindById(long id) {
return delegate.publisherPostAuthorizeBeanFindById(id);
}
}

View File

@@ -44,12 +44,19 @@ import static org.mockito.Mockito.*;
@RunWith(SpringRunner.class)
@ContextConfiguration
public class EnableReactiveMethodSecurityTests {
@Autowired ReactiveMessageService messageService;
@Autowired
ReactiveMessageService messageService;
ReactiveMessageService delegate;
TestPublisher<String> result = TestPublisher.create();
Context withAdmin = ReactiveSecurityContextHolder.withAuthentication(new TestingAuthenticationToken("admin", "password", "ROLE_USER", "ROLE_ADMIN"));
Context withUser = ReactiveSecurityContextHolder.withAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
Context withAdmin = ReactiveSecurityContextHolder
.withAuthentication(new TestingAuthenticationToken("admin", "password", "ROLE_USER", "ROLE_ADMIN"));
Context withUser = ReactiveSecurityContextHolder
.withAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
@After
public void cleanup() {
@@ -64,9 +71,8 @@ public class EnableReactiveMethodSecurityTests {
@Test
public void notPublisherPreAuthorizeFindByIdThenThrowsIllegalStateException() {
assertThatThrownBy(() -> this.messageService.notPublisherPreAuthorizeFindById(1L))
.isInstanceOf(IllegalStateException.class)
.extracting(Throwable::getMessage)
.isEqualTo("The returnType class java.lang.String on public abstract java.lang.String org.springframework.security.config.annotation.method.configuration.ReactiveMessageService.notPublisherPreAuthorizeFindById(long) must return an instance of org.reactivestreams.Publisher (i.e. Mono / Flux) in order to support Reactor Context");
.isInstanceOf(IllegalStateException.class).extracting(Throwable::getMessage).isEqualTo(
"The returnType class java.lang.String on public abstract java.lang.String org.springframework.security.config.annotation.method.configuration.ReactiveMessageService.notPublisherPreAuthorizeFindById(long) must return an instance of org.reactivestreams.Publisher (i.e. Mono / Flux) in order to support Reactor Context");
}
@Test
@@ -82,21 +88,15 @@ public class EnableReactiveMethodSecurityTests {
public void monoWhenPermitAllThenSuccess() {
when(this.delegate.monoFindById(1L)).thenReturn(Mono.just("success"));
StepVerifier.create(this.delegate.monoFindById(1L))
.expectNext("success")
.verifyComplete();
StepVerifier.create(this.delegate.monoFindById(1L)).expectNext("success").verifyComplete();
}
@Test
public void monoPreAuthorizeHasRoleWhenGrantedThenSuccess() {
when(this.delegate.monoPreAuthorizeHasRoleFindById(1L)).thenReturn(Mono.just("result"));
Mono<String> findById = this.messageService.monoPreAuthorizeHasRoleFindById(1L)
.subscriberContext(withAdmin);
StepVerifier
.create(findById)
.expectNext("result")
.verifyComplete();
Mono<String> findById = this.messageService.monoPreAuthorizeHasRoleFindById(1L).subscriberContext(withAdmin);
StepVerifier.create(findById).expectNext("result").verifyComplete();
}
@Test
@@ -104,10 +104,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.monoPreAuthorizeHasRoleFindById(1L)).thenReturn(Mono.from(result));
Mono<String> findById = this.messageService.monoPreAuthorizeHasRoleFindById(1L);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -116,12 +113,8 @@ public class EnableReactiveMethodSecurityTests {
public void monoPreAuthorizeHasRoleWhenNotAuthorizedThenDenied() {
when(this.delegate.monoPreAuthorizeHasRoleFindById(1L)).thenReturn(Mono.from(result));
Mono<String> findById = this.messageService.monoPreAuthorizeHasRoleFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
Mono<String> findById = this.messageService.monoPreAuthorizeHasRoleFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -130,12 +123,8 @@ public class EnableReactiveMethodSecurityTests {
public void monoPreAuthorizeBeanWhenGrantedThenSuccess() {
when(this.delegate.monoPreAuthorizeBeanFindById(2L)).thenReturn(Mono.just("result"));
Mono<String> findById = this.messageService.monoPreAuthorizeBeanFindById(2L)
.subscriberContext(withAdmin);
StepVerifier
.create(findById)
.expectNext("result")
.verifyComplete();
Mono<String> findById = this.messageService.monoPreAuthorizeBeanFindById(2L).subscriberContext(withAdmin);
StepVerifier.create(findById).expectNext("result").verifyComplete();
}
@Test
@@ -143,10 +132,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.monoPreAuthorizeBeanFindById(2L)).thenReturn(Mono.just("result"));
Mono<String> findById = this.messageService.monoPreAuthorizeBeanFindById(2L);
StepVerifier
.create(findById)
.expectNext("result")
.verifyComplete();
StepVerifier.create(findById).expectNext("result").verifyComplete();
}
@Test
@@ -154,10 +140,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.monoPreAuthorizeBeanFindById(1L)).thenReturn(Mono.from(result));
Mono<String> findById = this.messageService.monoPreAuthorizeBeanFindById(1L);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -166,12 +149,8 @@ public class EnableReactiveMethodSecurityTests {
public void monoPreAuthorizeBeanWhenNotAuthorizedThenDenied() {
when(this.delegate.monoPreAuthorizeBeanFindById(1L)).thenReturn(Mono.from(result));
Mono<String> findById = this.messageService.monoPreAuthorizeBeanFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
Mono<String> findById = this.messageService.monoPreAuthorizeBeanFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -180,36 +159,24 @@ public class EnableReactiveMethodSecurityTests {
public void monoPostAuthorizeWhenAuthorizedThenSuccess() {
when(this.delegate.monoPostAuthorizeFindById(1L)).thenReturn(Mono.just("user"));
Mono<String> findById = this.messageService.monoPostAuthorizeFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectNext("user")
.verifyComplete();
Mono<String> findById = this.messageService.monoPostAuthorizeFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectNext("user").verifyComplete();
}
@Test
public void monoPostAuthorizeWhenNotAuthorizedThenDenied() {
when(this.delegate.monoPostAuthorizeBeanFindById(1L)).thenReturn(Mono.just("not-authorized"));
Mono<String> findById = this.messageService.monoPostAuthorizeBeanFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
Mono<String> findById = this.messageService.monoPostAuthorizeBeanFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
}
@Test
public void monoPostAuthorizeWhenBeanAndAuthorizedThenSuccess() {
when(this.delegate.monoPostAuthorizeBeanFindById(2L)).thenReturn(Mono.just("user"));
Mono<String> findById = this.messageService.monoPostAuthorizeBeanFindById(2L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectNext("user")
.verifyComplete();
Mono<String> findById = this.messageService.monoPostAuthorizeBeanFindById(2L).subscriberContext(withUser);
StepVerifier.create(findById).expectNext("user").verifyComplete();
}
@Test
@@ -217,22 +184,15 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.monoPostAuthorizeBeanFindById(2L)).thenReturn(Mono.just("anonymous"));
Mono<String> findById = this.messageService.monoPostAuthorizeBeanFindById(2L);
StepVerifier
.create(findById)
.expectNext("anonymous")
.verifyComplete();
StepVerifier.create(findById).expectNext("anonymous").verifyComplete();
}
@Test
public void monoPostAuthorizeWhenBeanAndNotAuthorizedThenDenied() {
when(this.delegate.monoPostAuthorizeBeanFindById(1L)).thenReturn(Mono.just("not-authorized"));
Mono<String> findById = this.messageService.monoPostAuthorizeBeanFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
Mono<String> findById = this.messageService.monoPostAuthorizeBeanFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
}
// Flux tests
@@ -250,20 +210,15 @@ public class EnableReactiveMethodSecurityTests {
public void fluxWhenPermitAllThenSuccess() {
when(this.delegate.fluxFindById(1L)).thenReturn(Flux.just("success"));
StepVerifier.create(this.delegate.fluxFindById(1L))
.expectNext("success")
.verifyComplete();
StepVerifier.create(this.delegate.fluxFindById(1L)).expectNext("success").verifyComplete();
}
@Test
public void fluxPreAuthorizeHasRoleWhenGrantedThenSuccess() {
when(this.delegate.fluxPreAuthorizeHasRoleFindById(1L)).thenReturn(Flux.just("result"));
Flux<String> findById = this.messageService.fluxPreAuthorizeHasRoleFindById(1L)
.subscriberContext(withAdmin);
StepVerifier
.create(findById)
.consumeNextWith( s -> AssertionsForClassTypes.assertThat(s).isEqualTo("result"))
Flux<String> findById = this.messageService.fluxPreAuthorizeHasRoleFindById(1L).subscriberContext(withAdmin);
StepVerifier.create(findById).consumeNextWith(s -> AssertionsForClassTypes.assertThat(s).isEqualTo("result"))
.verifyComplete();
}
@@ -272,10 +227,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.fluxPreAuthorizeHasRoleFindById(1L)).thenReturn(Flux.from(result));
Flux<String> findById = this.messageService.fluxPreAuthorizeHasRoleFindById(1L);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -284,12 +236,8 @@ public class EnableReactiveMethodSecurityTests {
public void fluxPreAuthorizeHasRoleWhenNotAuthorizedThenDenied() {
when(this.delegate.fluxPreAuthorizeHasRoleFindById(1L)).thenReturn(Flux.from(result));
Flux<String> findById = this.messageService.fluxPreAuthorizeHasRoleFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
Flux<String> findById = this.messageService.fluxPreAuthorizeHasRoleFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -298,12 +246,8 @@ public class EnableReactiveMethodSecurityTests {
public void fluxPreAuthorizeBeanWhenGrantedThenSuccess() {
when(this.delegate.fluxPreAuthorizeBeanFindById(2L)).thenReturn(Flux.just("result"));
Flux<String> findById = this.messageService.fluxPreAuthorizeBeanFindById(2L)
.subscriberContext(withAdmin);
StepVerifier
.create(findById)
.expectNext("result")
.verifyComplete();
Flux<String> findById = this.messageService.fluxPreAuthorizeBeanFindById(2L).subscriberContext(withAdmin);
StepVerifier.create(findById).expectNext("result").verifyComplete();
}
@Test
@@ -311,10 +255,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.fluxPreAuthorizeBeanFindById(2L)).thenReturn(Flux.just("result"));
Flux<String> findById = this.messageService.fluxPreAuthorizeBeanFindById(2L);
StepVerifier
.create(findById)
.expectNext("result")
.verifyComplete();
StepVerifier.create(findById).expectNext("result").verifyComplete();
}
@Test
@@ -322,10 +263,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.fluxPreAuthorizeBeanFindById(1L)).thenReturn(Flux.from(result));
Flux<String> findById = this.messageService.fluxPreAuthorizeBeanFindById(1L);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -334,12 +272,8 @@ public class EnableReactiveMethodSecurityTests {
public void fluxPreAuthorizeBeanWhenNotAuthorizedThenDenied() {
when(this.delegate.fluxPreAuthorizeBeanFindById(1L)).thenReturn(Flux.from(result));
Flux<String> findById = this.messageService.fluxPreAuthorizeBeanFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
Flux<String> findById = this.messageService.fluxPreAuthorizeBeanFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -348,36 +282,24 @@ public class EnableReactiveMethodSecurityTests {
public void fluxPostAuthorizeWhenAuthorizedThenSuccess() {
when(this.delegate.fluxPostAuthorizeFindById(1L)).thenReturn(Flux.just("user"));
Flux<String> findById = this.messageService.fluxPostAuthorizeFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectNext("user")
.verifyComplete();
Flux<String> findById = this.messageService.fluxPostAuthorizeFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectNext("user").verifyComplete();
}
@Test
public void fluxPostAuthorizeWhenNotAuthorizedThenDenied() {
when(this.delegate.fluxPostAuthorizeBeanFindById(1L)).thenReturn(Flux.just("not-authorized"));
Flux<String> findById = this.messageService.fluxPostAuthorizeBeanFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
Flux<String> findById = this.messageService.fluxPostAuthorizeBeanFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
}
@Test
public void fluxPostAuthorizeWhenBeanAndAuthorizedThenSuccess() {
when(this.delegate.fluxPostAuthorizeBeanFindById(2L)).thenReturn(Flux.just("user"));
Flux<String> findById = this.messageService.fluxPostAuthorizeBeanFindById(2L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectNext("user")
.verifyComplete();
Flux<String> findById = this.messageService.fluxPostAuthorizeBeanFindById(2L).subscriberContext(withUser);
StepVerifier.create(findById).expectNext("user").verifyComplete();
}
@Test
@@ -385,22 +307,15 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.fluxPostAuthorizeBeanFindById(2L)).thenReturn(Flux.just("anonymous"));
Flux<String> findById = this.messageService.fluxPostAuthorizeBeanFindById(2L);
StepVerifier
.create(findById)
.expectNext("anonymous")
.verifyComplete();
StepVerifier.create(findById).expectNext("anonymous").verifyComplete();
}
@Test
public void fluxPostAuthorizeWhenBeanAndNotAuthorizedThenDenied() {
when(this.delegate.fluxPostAuthorizeBeanFindById(1L)).thenReturn(Flux.just("not-authorized"));
Flux<String> findById = this.messageService.fluxPostAuthorizeBeanFindById(1L)
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
Flux<String> findById = this.messageService.fluxPostAuthorizeBeanFindById(1L).subscriberContext(withUser);
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
}
// Publisher tests
@@ -418,9 +333,7 @@ public class EnableReactiveMethodSecurityTests {
public void publisherWhenPermitAllThenSuccess() {
when(this.delegate.publisherFindById(1L)).thenReturn(publisherJust("success"));
StepVerifier.create(this.delegate.publisherFindById(1L))
.expectNext("success")
.verifyComplete();
StepVerifier.create(this.delegate.publisherFindById(1L)).expectNext("success").verifyComplete();
}
@Test
@@ -429,9 +342,7 @@ public class EnableReactiveMethodSecurityTests {
Publisher<String> findById = Flux.from(this.messageService.publisherPreAuthorizeHasRoleFindById(1L))
.subscriberContext(withAdmin);
StepVerifier
.create(findById)
.consumeNextWith( s -> AssertionsForClassTypes.assertThat(s).isEqualTo("result"))
StepVerifier.create(findById).consumeNextWith(s -> AssertionsForClassTypes.assertThat(s).isEqualTo("result"))
.verifyComplete();
}
@@ -440,10 +351,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.publisherPreAuthorizeHasRoleFindById(1L)).thenReturn(result);
Publisher<String> findById = this.messageService.publisherPreAuthorizeHasRoleFindById(1L);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -454,10 +362,7 @@ public class EnableReactiveMethodSecurityTests {
Publisher<String> findById = Flux.from(this.messageService.publisherPreAuthorizeHasRoleFindById(1L))
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -468,10 +373,7 @@ public class EnableReactiveMethodSecurityTests {
Publisher<String> findById = Flux.from(this.messageService.publisherPreAuthorizeBeanFindById(2L))
.subscriberContext(withAdmin);
StepVerifier
.create(findById)
.expectNext("result")
.verifyComplete();
StepVerifier.create(findById).expectNext("result").verifyComplete();
}
@Test
@@ -479,10 +381,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.publisherPreAuthorizeBeanFindById(2L)).thenReturn(publisherJust("result"));
Publisher<String> findById = this.messageService.publisherPreAuthorizeBeanFindById(2L);
StepVerifier
.create(findById)
.expectNext("result")
.verifyComplete();
StepVerifier.create(findById).expectNext("result").verifyComplete();
}
@Test
@@ -490,10 +389,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.publisherPreAuthorizeBeanFindById(1L)).thenReturn(result);
Publisher<String> findById = this.messageService.publisherPreAuthorizeBeanFindById(1L);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -504,10 +400,7 @@ public class EnableReactiveMethodSecurityTests {
Publisher<String> findById = Flux.from(this.messageService.publisherPreAuthorizeBeanFindById(1L))
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
result.assertNoSubscribers();
}
@@ -518,10 +411,7 @@ public class EnableReactiveMethodSecurityTests {
Publisher<String> findById = Flux.from(this.messageService.publisherPostAuthorizeFindById(1L))
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectNext("user")
.verifyComplete();
StepVerifier.create(findById).expectNext("user").verifyComplete();
}
@Test
@@ -530,10 +420,7 @@ public class EnableReactiveMethodSecurityTests {
Publisher<String> findById = Flux.from(this.messageService.publisherPostAuthorizeBeanFindById(1L))
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
}
@Test
@@ -542,10 +429,7 @@ public class EnableReactiveMethodSecurityTests {
Publisher<String> findById = Flux.from(this.messageService.publisherPostAuthorizeBeanFindById(2L))
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectNext("user")
.verifyComplete();
StepVerifier.create(findById).expectNext("user").verifyComplete();
}
@Test
@@ -553,10 +437,7 @@ public class EnableReactiveMethodSecurityTests {
when(this.delegate.publisherPostAuthorizeBeanFindById(2L)).thenReturn(publisherJust("anonymous"));
Publisher<String> findById = this.messageService.publisherPostAuthorizeBeanFindById(2L);
StepVerifier
.create(findById)
.expectNext("anonymous")
.verifyComplete();
StepVerifier.create(findById).expectNext("anonymous").verifyComplete();
}
@Test
@@ -565,10 +446,7 @@ public class EnableReactiveMethodSecurityTests {
Publisher<String> findById = Flux.from(this.messageService.publisherPostAuthorizeBeanFindById(1L))
.subscriberContext(withUser);
StepVerifier
.create(findById)
.expectError(AccessDeniedException.class)
.verify();
StepVerifier.create(findById).expectError(AccessDeniedException.class).verify();
}
static <T> Publisher<T> publisher(Flux<T> flux) {
@@ -581,6 +459,7 @@ public class EnableReactiveMethodSecurityTests {
@EnableReactiveMethodSecurity
static class Config {
ReactiveMessageService delegate = mock(ReactiveMessageService.class);
@Bean
@@ -592,5 +471,7 @@ public class EnableReactiveMethodSecurityTests {
public Authz authz() {
return new Authz();
}
}
}

View File

@@ -68,13 +68,13 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
*
* @author Rob Winch
* @author Artsiom Yudovin
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SecurityTestExecutionListeners
public class GlobalMethodSecurityConfigurationTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -112,11 +112,13 @@ public class GlobalMethodSecurityConfigurationTests {
@EnableGlobalMethodSecurity
public static class CustomMetadataSourceConfig extends GlobalMethodSecurityConfiguration {
@Bean
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return mock(MethodSecurityMetadataSource.class);
}
}
@Test
@@ -125,13 +127,17 @@ public class GlobalMethodSecurityConfigurationTests {
try {
this.authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("foo", "bar"));
} catch(AuthenticationException e) {}
}
catch (AuthenticationException e) {
}
assertThat(this.events.getEvents()).extracting(Object::getClass).containsOnly((Class) AuthenticationFailureBadCredentialsEvent.class);
assertThat(this.events.getEvents()).extracting(Object::getClass)
.containsOnly((Class) AuthenticationFailureBadCredentialsEvent.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class InMemoryAuthWithGlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -142,8 +148,10 @@ public class GlobalMethodSecurityConfigurationTests {
@Bean
public MockEventListener<AbstractAuthenticationEvent> listener() {
return new MockEventListener<AbstractAuthenticationEvent>() {};
return new MockEventListener<AbstractAuthenticationEvent>() {
};
}
}
@Test
@@ -154,8 +162,7 @@ public class GlobalMethodSecurityConfigurationTests {
AuthenticationTrustResolver trustResolver = this.spring.getContext().getBean(AuthenticationTrustResolver.class);
when(trustResolver.isAnonymous(any())).thenReturn(true, false);
assertThatThrownBy(() -> this.service.preAuthorizeNotAnonymous())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorizeNotAnonymous()).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeNotAnonymous();
@@ -174,6 +181,7 @@ public class GlobalMethodSecurityConfigurationTests {
public MethodSecurityServiceImpl service() {
return new MethodSecurityServiceImpl();
}
}
// SEC-2301
@@ -183,8 +191,7 @@ public class GlobalMethodSecurityConfigurationTests {
this.spring.register(ExpressionHandlerHasBeanResolverSetConfig.class).autowire();
Authz authz = this.spring.getContext().getBean(Authz.class);
assertThatThrownBy(() -> this.service.preAuthorizeBean(false))
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorizeBean(false)).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeBean(true);
}
@@ -201,6 +208,7 @@ public class GlobalMethodSecurityConfigurationTests {
public Authz authz() {
return new Authz();
}
}
@Test
@@ -208,8 +216,7 @@ public class GlobalMethodSecurityConfigurationTests {
public void methodSecuritySupportsAnnotaitonsOnInterfaceParamerNames() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.postAnnotation("deny"))
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.postAnnotation("deny")).isInstanceOf(AccessDeniedException.class);
this.service.postAnnotation("grant");
// no exception
@@ -222,6 +229,7 @@ public class GlobalMethodSecurityConfigurationTests {
public MethodSecurityService service() {
return new MethodSecurityServiceImpl();
}
}
@Test
@@ -234,8 +242,7 @@ public class GlobalMethodSecurityConfigurationTests {
this.service.hasPermission("something");
// no exception
assertThatThrownBy(() -> this.service.hasPermission("something"))
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.hasPermission("something")).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
@@ -250,6 +257,7 @@ public class GlobalMethodSecurityConfigurationTests {
public MethodSecurityService service() {
return new MethodSecurityServiceImpl();
}
}
@Test
@@ -271,6 +279,7 @@ public class GlobalMethodSecurityConfigurationTests {
public PermissionEvaluator permissionEvaluator2() {
return mock(PermissionEvaluator.class);
}
}
// SEC-2425
@@ -279,12 +288,13 @@ public class GlobalMethodSecurityConfigurationTests {
public void enableGlobalMethodSecurityWorksOnSuperclass() {
this.spring.register(ChildConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Configuration
static class ChildConfig extends ParentConfig {}
static class ChildConfig extends ParentConfig {
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class ParentConfig {
@@ -293,6 +303,7 @@ public class GlobalMethodSecurityConfigurationTests {
public MethodSecurityService service() {
return new MethodSecurityServiceImpl();
}
}
// SEC-2479
@@ -308,26 +319,29 @@ public class GlobalMethodSecurityConfigurationTests {
child.refresh();
this.spring.context(child).autowire();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
}
}
@Configuration
static class Sec2479ParentConfig {
@Bean
public AuthenticationManager am() {
return mock(AuthenticationManager.class);
}
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class Sec2479ChildConfig {
@Bean
public MethodSecurityService service() {
return new MethodSecurityServiceImpl();
}
}
@Test
@@ -342,6 +356,7 @@ public class GlobalMethodSecurityConfigurationTests {
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class Sec2815Config {
@Bean
public MethodSecurityService service() {
return new MethodSecurityServiceImpl();
@@ -359,6 +374,7 @@ public class GlobalMethodSecurityConfigurationTests {
@Configuration
static class AuthConfig extends GlobalAuthenticationConfigurerAdapter {
@Autowired
DataSource dataSource;
@@ -366,16 +382,19 @@ public class GlobalMethodSecurityConfigurationTests {
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication();
}
}
}
static class MockBeanPostProcessor implements BeanPostProcessor {
Map<String, Object> beforeInit = new HashMap<>();
Map<String, Object> afterInit = new HashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws
BeansException {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
this.beforeInit.put(beanName, bean);
return bean;
}
@@ -385,6 +404,7 @@ public class GlobalMethodSecurityConfigurationTests {
this.afterInit.put(beanName, bean);
return bean;
}
}
// SEC-3045
@@ -392,12 +412,13 @@ public class GlobalMethodSecurityConfigurationTests {
public void globalSecurityProxiesSecurity() {
this.spring.register(Sec3005Config.class).autowire();
assertThat(this.service.getClass()).matches(c-> !Proxy.isProxyClass(c), "is not proxy class");
assertThat(this.service.getClass()).matches(c -> !Proxy.isProxyClass(c), "is not proxy class");
}
@EnableGlobalMethodSecurity(prePostEnabled = true, mode= AdviceMode.ASPECTJ)
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ)
@EnableTransactionManagement
static class Sec3005Config {
@Bean
public MethodSecurityService service() {
return new MethodSecurityServiceImpl();
@@ -407,25 +428,26 @@ public class GlobalMethodSecurityConfigurationTests {
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication();
}
}
//
// // gh-3797
// def preAuthorizeBeanSpel() {
// setup:
// SecurityContextHolder.getContext().setAuthentication(
// new TestingAuthenticationToken("user", "password","ROLE_USER"))
// context = new AnnotationConfigApplicationContext(PreAuthorizeBeanSpelConfig)
// BeanSpelService service = context.getBean(BeanSpelService)
// when:
// service.run(true)
// then:
// noExceptionThrown()
// when:
// service.run(false)
// then:
// thrown(AccessDeniedException)
// }
// // gh-3797
// def preAuthorizeBeanSpel() {
// setup:
// SecurityContextHolder.getContext().setAuthentication(
// new TestingAuthenticationToken("user", "password","ROLE_USER"))
// context = new AnnotationConfigApplicationContext(PreAuthorizeBeanSpelConfig)
// BeanSpelService service = context.getBean(BeanSpelService)
// when:
// service.run(true)
// then:
// noExceptionThrown()
// when:
// service.run(false)
// then:
// thrown(AccessDeniedException)
// }
//
@Test
@@ -433,8 +455,7 @@ public class GlobalMethodSecurityConfigurationTests {
public void preAuthorizeBeanSpel() {
this.spring.register(PreAuthorizeBeanSpelConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorizeBean(false))
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorizeBean(false)).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeBean(true);
}
@@ -442,6 +463,7 @@ public class GlobalMethodSecurityConfigurationTests {
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class PreAuthorizeBeanSpelConfig {
@Bean
MethodSecurityService service() {
return new MethodSecurityServiceImpl();
@@ -451,6 +473,7 @@ public class GlobalMethodSecurityConfigurationTests {
Authz authz() {
return new Authz();
}
}
// gh-3394
@@ -459,14 +482,14 @@ public class GlobalMethodSecurityConfigurationTests {
public void roleHierarchy() {
this.spring.register(RoleHierarchyConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeAdmin();
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public static class RoleHierarchyConfig {
@Bean
MethodSecurityService service() {
return new MethodSecurityServiceImpl();
@@ -478,6 +501,7 @@ public class GlobalMethodSecurityConfigurationTests {
result.setHierarchy("ROLE_USER > ROLE_ADMIN");
return result;
}
}
@Test
@@ -485,11 +509,10 @@ public class GlobalMethodSecurityConfigurationTests {
public void grantedAuthorityDefaultsAutowires() {
this.spring.register(CustomGrantedAuthorityConfig.class).autowire();
CustomGrantedAuthorityConfig.CustomAuthorityService customService = this.spring.getContext().getBean(
CustomGrantedAuthorityConfig.CustomAuthorityService.class);
CustomGrantedAuthorityConfig.CustomAuthorityService customService = this.spring.getContext()
.getBean(CustomGrantedAuthorityConfig.CustomAuthorityService.class);
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
customService.customPrefixRoleUser();
// no exception
@@ -514,9 +537,13 @@ public class GlobalMethodSecurityConfigurationTests {
}
static class CustomAuthorityService {
@PreAuthorize("hasRole('ROLE:USER')")
public void customPrefixRoleUser() {}
public void customPrefixRoleUser() {
}
}
}
@Test
@@ -527,8 +554,7 @@ public class GlobalMethodSecurityConfigurationTests {
EmptyRolePrefixGrantedAuthorityConfig.CustomAuthorityService customService = this.spring.getContext()
.getBean(EmptyRolePrefixGrantedAuthorityConfig.CustomAuthorityService.class);
assertThatThrownBy(() -> this.service.securedUser())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.securedUser()).isInstanceOf(AccessDeniedException.class);
customService.emptyPrefixRoleUser();
// no exception
@@ -536,6 +562,7 @@ public class GlobalMethodSecurityConfigurationTests {
@EnableGlobalMethodSecurity(securedEnabled = true)
static class EmptyRolePrefixGrantedAuthorityConfig {
@Bean
public GrantedAuthorityDefaults ga() {
return new GrantedAuthorityDefaults("");
@@ -552,18 +579,22 @@ public class GlobalMethodSecurityConfigurationTests {
}
static class CustomAuthorityService {
@Secured("USER")
public void emptyPrefixRoleUser() {}
public void emptyPrefixRoleUser() {
}
}
}
@Test
public void methodSecurityInterceptorUsesMetadataSourceBeanWhenProxyingDisabled() {
this.spring.register(CustomMetadataSourceBeanProxyEnabledConfig.class).autowire();
MethodSecurityInterceptor methodInterceptor =
(MethodSecurityInterceptor) this.spring.getContext().getBean(MethodInterceptor.class);
MethodSecurityMetadataSource methodSecurityMetadataSource =
this.spring.getContext().getBean(MethodSecurityMetadataSource.class);
MethodSecurityInterceptor methodInterceptor = (MethodSecurityInterceptor) this.spring.getContext()
.getBean(MethodInterceptor.class);
MethodSecurityMetadataSource methodSecurityMetadataSource = this.spring.getContext()
.getBean(MethodSecurityMetadataSource.class);
assertThat(methodInterceptor.getSecurityMetadataSource()).isSameAs(methodSecurityMetadataSource);
}
@@ -571,5 +602,7 @@ public class GlobalMethodSecurityConfigurationTests {
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public static class CustomMetadataSourceBeanProxyEnabledConfig extends GlobalMethodSecurityConfiguration {
}
}

View File

@@ -29,6 +29,7 @@ import javax.annotation.security.PermitAll;
* @author Rob Winch
*/
public interface MethodSecurityService {
@PreAuthorize("denyAll")
String preAuthorize();
@@ -67,4 +68,5 @@ public interface MethodSecurityService {
@PostAuthorize("#o?.contains('grant')")
String postAnnotation(@P("o") String object);
}

View File

@@ -21,8 +21,10 @@ import org.springframework.context.annotation.Bean;
* @author Josh Cummings
*/
public class MethodSecurityServiceConfig {
@Bean
MethodSecurityService service() {
return new MethodSecurityServiceImpl();
}
}

View File

@@ -23,6 +23,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
* @author Rob Winch
*/
public class MethodSecurityServiceImpl implements MethodSecurityService {
@Override
public String preAuthorize() {
return null;

View File

@@ -35,7 +35,6 @@ import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
*
* @author Rob Winch
* @author Josh Cummings
*/
@@ -54,11 +53,9 @@ public class NamespaceGlobalMethodSecurityExpressionHandlerTests {
public void methodSecurityWhenUsingCustomPermissionEvaluatorThenPreAuthorizesAccordingly() {
this.spring.register(CustomAccessDecisionManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.hasPermission("granted"))
.doesNotThrowAnyException();
assertThatCode(() -> this.service.hasPermission("granted")).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.hasPermission("denied"))
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.hasPermission("denied")).isInstanceOf(AccessDeniedException.class);
}
@Test
@@ -66,30 +63,33 @@ public class NamespaceGlobalMethodSecurityExpressionHandlerTests {
public void methodSecurityWhenUsingCustomPermissionEvaluatorThenPostAuthorizesAccordingly() {
this.spring.register(CustomAccessDecisionManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.postHasPermission("granted"))
.doesNotThrowAnyException();
assertThatCode(() -> this.service.postHasPermission("granted")).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.postHasPermission("denied"))
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.postHasPermission("denied")).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class CustomAccessDecisionManagerConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new PermissionEvaluator() {
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
public boolean hasPermission(Authentication authentication, Object targetDomainObject,
Object permission) {
return "granted".equals(targetDomainObject);
}
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
throw new UnsupportedOperationException();
}
});
return expressionHandler;
}
}
}

View File

@@ -60,7 +60,6 @@ import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
*
* @author Rob Winch
* @author Josh Cummings
*/
@@ -81,11 +80,9 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenCustomAccessDecisionManagerThenAuthorizes() {
this.spring.register(CustomAccessDecisionManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.secured())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.secured()).isInstanceOf(AccessDeniedException.class);
}
@@ -98,16 +95,22 @@ public class NamespaceGlobalMethodSecurityTests {
}
public static class DenyAllAccessDecisionManager implements AccessDecisionManager {
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) {
public void decide(Authentication authentication, Object object,
Collection<ConfigAttribute> configAttributes) {
throw new AccessDeniedException("Always Denied");
}
public boolean supports(ConfigAttribute attribute) {
return true;
}
public boolean supports(Class<?> clazz) {
return true;
}
}
}
// --- after-invocation-provider
@@ -117,13 +120,11 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenCustomAfterInvocationManagerThenAuthorizes() {
this.spring.register(CustomAfterInvocationManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorizePermitAll())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorizePermitAll()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class CustomAfterInvocationManagerConfig
extends GlobalMethodSecurityConfiguration {
public static class CustomAfterInvocationManagerConfig extends GlobalMethodSecurityConfiguration {
@Override
protected AfterInvocationManager afterInvocationManager() {
@@ -131,10 +132,9 @@ public class NamespaceGlobalMethodSecurityTests {
}
public static class AfterInvocationManagerStub implements AfterInvocationManager {
public Object decide(Authentication authentication,
Object object,
Collection<ConfigAttribute> attributes,
Object returnedObject) throws AccessDeniedException {
public Object decide(Authentication authentication, Object object, Collection<ConfigAttribute> attributes,
Object returnedObject) throws AccessDeniedException {
throw new AccessDeniedException("custom AfterInvocationManager");
}
@@ -142,10 +142,13 @@ public class NamespaceGlobalMethodSecurityTests {
public boolean supports(ConfigAttribute attribute) {
return true;
}
public boolean supports(Class<?> clazz) {
return true;
}
}
}
// --- authentication-manager-ref ---
@@ -155,8 +158,7 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenCustomAuthenticationManagerThenAuthorizes() {
this.spring.register(CustomAuthenticationConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(UnsupportedOperationException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(UnsupportedOperationException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
@@ -175,6 +177,7 @@ public class NamespaceGlobalMethodSecurityTests {
throw new UnsupportedOperationException();
};
}
}
// --- jsr250-annotations ---
@@ -184,17 +187,13 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenJsr250EnabledThenAuthorizes() {
this.spring.register(Jsr250Config.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.preAuthorize())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.preAuthorize()).doesNotThrowAnyException();
assertThatCode(() -> this.service.secured())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.jsr250())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
assertThatCode(() -> this.service.jsr250PermitAll())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250PermitAll()).doesNotThrowAnyException();
}
@@ -209,16 +208,14 @@ public class NamespaceGlobalMethodSecurityTests {
@Test
@WithMockUser
public void methodSecurityWhenCustomMethodSecurityMetadataSourceThenAuthorizes() {
this.spring.register(CustomMethodSecurityMetadataSourceConfig.class, MethodSecurityServiceConfig.class).autowire();
this.spring.register(CustomMethodSecurityMetadataSourceConfig.class, MethodSecurityServiceConfig.class)
.autowire();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.secured())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.secured()).isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.jsr250())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity
@@ -228,16 +225,18 @@ public class NamespaceGlobalMethodSecurityTests {
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return new AbstractMethodSecurityMetadataSource() {
public Collection<ConfigAttribute> getAttributes(Method method, Class<?> targetClass) {
// require ROLE_NOBODY for any method on MethodSecurityService interface
return MethodSecurityService.class.isAssignableFrom(targetClass) ?
Arrays.asList(new SecurityConfig("ROLE_NOBODY")) :
Collections.emptyList();
// require ROLE_NOBODY for any method on MethodSecurityService
// interface
return MethodSecurityService.class.isAssignableFrom(targetClass)
? Arrays.asList(new SecurityConfig("ROLE_NOBODY")) : Collections.emptyList();
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return null;
}
};
}
}
// --- mode ---
@@ -247,10 +246,13 @@ public class NamespaceGlobalMethodSecurityTests {
public void contextRefreshWhenUsingAspectJThenAutowire() throws Exception {
this.spring.register(AspectJModeConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.spring.getContext().getBean(Class.forName("org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect"))).isNotNull();
assertThat(this.spring.getContext().getBean(
Class.forName("org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect")))
.isNotNull();
assertThat(this.spring.getContext().getBean(AspectJMethodSecurityInterceptor.class)).isNotNull();
//TODO diagnose why aspectj isn't weaving method security advice around MethodSecurityServiceImpl
// TODO diagnose why aspectj isn't weaving method security advice around
// MethodSecurityServiceImpl
}
@EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ, securedEnabled = true)
@@ -260,48 +262,51 @@ public class NamespaceGlobalMethodSecurityTests {
@Test
public void contextRefreshWhenUsingAspectJAndCustomGlobalMethodSecurityConfigurationThenAutowire()
throws Exception {
throws Exception {
this.spring.register(AspectJModeExtendsGMSCConfig.class).autowire();
assertThat(this.spring.getContext().getBean(Class.forName("org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect"))).isNotNull();
assertThat(this.spring.getContext().getBean(
Class.forName("org.springframework.security.access.intercept.aspectj.aspect.AnnotationSecurityAspect")))
.isNotNull();
assertThat(this.spring.getContext().getBean(AspectJMethodSecurityInterceptor.class)).isNotNull();
}
@EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ, securedEnabled = true)
public static class AspectJModeExtendsGMSCConfig extends GlobalMethodSecurityConfiguration {
}
// --- order ---
private static class AdvisorOrderConfig
implements ImportBeanDefinitionRegistrar {
private static class AdvisorOrderConfig implements ImportBeanDefinitionRegistrar {
private static class ExceptingInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) {
throw new UnsupportedOperationException("Deny All");
}
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinitionBuilder advice = BeanDefinitionBuilder
.rootBeanDefinition(ExceptingInterceptor.class);
registry.registerBeanDefinition("exceptingInterceptor",
advice.getBeanDefinition());
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
BeanDefinitionBuilder advice = BeanDefinitionBuilder.rootBeanDefinition(ExceptingInterceptor.class);
registry.registerBeanDefinition("exceptingInterceptor", advice.getBeanDefinition());
BeanDefinitionBuilder advisor = BeanDefinitionBuilder
.rootBeanDefinition(MethodSecurityMetadataSourceAdvisor.class);
.rootBeanDefinition(MethodSecurityMetadataSourceAdvisor.class);
advisor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
advisor.addConstructorArgValue("exceptingInterceptor");
advisor.addConstructorArgReference("methodSecurityMetadataSource");
advisor.addConstructorArgValue("methodSecurityMetadataSource");
advisor.addPropertyValue("order", 0);
registry.registerBeanDefinition("exceptingAdvisor",
advisor.getBeanDefinition());
registry.registerBeanDefinition("exceptingAdvisor", advisor.getBeanDefinition());
}
}
@Test
@@ -309,13 +314,10 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenOrderSpecifiedThenConfigured() {
this.spring.register(CustomOrderConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.spring.getContext()
.getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder())
.isEqualTo(-135);
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(-135);
assertThatThrownBy(() -> this.service.jsr250())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(order = -135, jsr250Enabled = true)
@@ -329,37 +331,34 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenOrderUnspecifiedThenConfiguredToLowestPrecedence() {
this.spring.register(DefaultOrderConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.spring.getContext()
.getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder())
.isEqualTo(Ordered.LOWEST_PRECEDENCE);
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE);
assertThatThrownBy(() -> this.service.jsr250())
.isInstanceOf(UnsupportedOperationException.class);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(UnsupportedOperationException.class);
}
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@Import(AdvisorOrderConfig.class)
public static class DefaultOrderConfig {
}
@Test
@WithMockUser
public void methodSecurityWhenOrderUnspecifiedAndCustomGlobalMethodSecurityConfigurationThenConfiguredToLowestPrecedence() {
this.spring.register(DefaultOrderExtendsMethodSecurityConfig.class, MethodSecurityServiceConfig.class).autowire();
this.spring.register(DefaultOrderExtendsMethodSecurityConfig.class, MethodSecurityServiceConfig.class)
.autowire();
assertThat(this.spring.getContext()
.getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder())
.isEqualTo(Ordered.LOWEST_PRECEDENCE);
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE);
assertThatThrownBy(() -> this.service.jsr250())
.isInstanceOf(UnsupportedOperationException.class);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(UnsupportedOperationException.class);
}
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@Import(AdvisorOrderConfig.class)
public static class DefaultOrderExtendsMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}
// --- pre-post-annotations ---
@@ -369,18 +368,16 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenPrePostEnabledThenPreAuthorizes() {
this.spring.register(PreAuthorizeConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class PreAuthorizeConfig {
}
@Test
@@ -388,18 +385,16 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenPrePostEnabledAndCustomGlobalMethodSecurityConfigurationThenPreAuthorizes() {
this.spring.register(PreAuthorizeExtendsGMSCConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class PreAuthorizeExtendsGMSCConfig extends GlobalMethodSecurityConfiguration {
}
// --- proxy-target-class ---
@@ -410,15 +405,14 @@ public class NamespaceGlobalMethodSecurityTests {
this.spring.register(ProxyTargetClassConfig.class, MethodSecurityServiceConfig.class).autowire();
// make sure service was actually proxied
assertThat(this.service.getClass().getInterfaces())
.doesNotContain(MethodSecurityService.class);
assertThat(this.service.getClass().getInterfaces()).doesNotContain(MethodSecurityService.class);
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(proxyTargetClass = true, prePostEnabled = true)
public static class ProxyTargetClassConfig {
}
@Test
@@ -426,15 +420,14 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenDefaultProxyThenWiresToInterface() {
this.spring.register(DefaultProxyConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.service.getClass().getInterfaces())
.contains(MethodSecurityService.class);
assertThat(this.service.getClass().getInterfaces()).contains(MethodSecurityService.class);
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class DefaultProxyConfig {
}
// --- run-as-manager-ref ---
@@ -445,7 +438,7 @@ public class NamespaceGlobalMethodSecurityTests {
this.spring.register(CustomRunAsManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(service.runAs().getAuthorities())
.anyMatch(authority -> "ROLE_RUN_AS_SUPER".equals(authority.getAuthority()));
.anyMatch(authority -> "ROLE_RUN_AS_SUPER".equals(authority.getAuthority()));
}
@EnableGlobalMethodSecurity(securedEnabled = true)
@@ -457,6 +450,7 @@ public class NamespaceGlobalMethodSecurityTests {
runAsManager.setKey("some key");
return runAsManager;
}
}
// --- secured-annotation ---
@@ -466,21 +460,18 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenSecuredEnabledThenSecures() {
this.spring.register(SecuredConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.secured())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.secured()).isInstanceOf(AccessDeniedException.class);
assertThatCode(() -> this.service.securedUser())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.securedUser()).doesNotThrowAnyException();
assertThatCode(() -> this.service.preAuthorize())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.preAuthorize()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
}
@EnableGlobalMethodSecurity(securedEnabled = true)
public static class SecuredConfig {
}
// --- unsorted ---
@@ -488,14 +479,13 @@ public class NamespaceGlobalMethodSecurityTests {
@Test
@WithMockUser
public void methodSecurityWhenMissingEnableAnnotationThenShowsHelpfulError() {
assertThatThrownBy(() ->
this.spring.register(ExtendsNoEnableAnntotationConfig.class).autowire())
.hasStackTraceContaining(EnableGlobalMethodSecurity.class.getName() + " is required");
assertThatThrownBy(() -> this.spring.register(ExtendsNoEnableAnntotationConfig.class).autowire())
.hasStackTraceContaining(EnableGlobalMethodSecurity.class.getName() + " is required");
}
@Configuration
public static class ExtendsNoEnableAnntotationConfig
extends GlobalMethodSecurityConfiguration {
public static class ExtendsNoEnableAnntotationConfig extends GlobalMethodSecurityConfiguration {
}
@Test
@@ -503,18 +493,17 @@ public class NamespaceGlobalMethodSecurityTests {
public void methodSecurityWhenImportingGlobalMethodSecurityConfigurationSubclassThenAuthorizes() {
this.spring.register(ImportSubclassGMSCConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250())
.doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Configuration
@Import(PreAuthorizeExtendsGMSCConfig.class)
public static class ImportSubclassGMSCConfig {
}
}

View File

@@ -20,23 +20,37 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface ReactiveMessageService {
String notPublisherPreAuthorizeFindById(long id);
Mono<String> monoFindById(long id);
Mono<String> monoPreAuthorizeHasRoleFindById(long id);
Mono<String> monoPostAuthorizeFindById(long id);
Mono<String> monoPreAuthorizeBeanFindById(long id);
Mono<String> monoPostAuthorizeBeanFindById(long id);
Flux<String> fluxFindById(long id);
Flux<String> fluxPreAuthorizeHasRoleFindById(long id);
Flux<String> fluxPostAuthorizeFindById(long id);
Flux<String> fluxPreAuthorizeBeanFindById(long id);
Flux<String> fluxPostAuthorizeBeanFindById(long id);
Publisher<String> publisherFindById(long id);
Publisher<String> publisherPreAuthorizeHasRoleFindById(long id);
Publisher<String> publisherPostAuthorizeFindById(long id);
Publisher<String> publisherPreAuthorizeBeanFindById(long id);
Publisher<String> publisherPostAuthorizeBeanFindById(long id);
}

View File

@@ -46,14 +46,13 @@ public class ReactiveMethodSecurityConfigurationTests {
public void rolePrefixWithGrantedAuthorityDefaults() throws NoSuchMethodException {
this.spring.register(WithRolePrefixConfiguration.class).autowire();
TestingAuthenticationToken authentication = new TestingAuthenticationToken(
"principal", "credential", "CUSTOM_ABC");
TestingAuthenticationToken authentication = new TestingAuthenticationToken("principal", "credential",
"CUSTOM_ABC");
MockMethodInvocation methodInvocation = new MockMethodInvocation(new Foo(), Foo.class, "bar", String.class);
EvaluationContext context = this.methodSecurityExpressionHandler
.createEvaluationContext(authentication, methodInvocation);
SecurityExpressionRoot root = (SecurityExpressionRoot) context.getRootObject()
.getValue();
EvaluationContext context = this.methodSecurityExpressionHandler.createEvaluationContext(authentication,
methodInvocation);
SecurityExpressionRoot root = (SecurityExpressionRoot) context.getRootObject().getValue();
assertThat(root.hasRole("ROLE_ABC")).isFalse();
assertThat(root.hasRole("ROLE_CUSTOM_ABC")).isFalse();
@@ -65,14 +64,13 @@ public class ReactiveMethodSecurityConfigurationTests {
public void rolePrefixWithDefaultConfig() throws NoSuchMethodException {
this.spring.register(ReactiveMethodSecurityConfiguration.class).autowire();
TestingAuthenticationToken authentication = new TestingAuthenticationToken(
"principal", "credential", "ROLE_ABC");
TestingAuthenticationToken authentication = new TestingAuthenticationToken("principal", "credential",
"ROLE_ABC");
MockMethodInvocation methodInvocation = new MockMethodInvocation(new Foo(), Foo.class, "bar", String.class);
EvaluationContext context = this.methodSecurityExpressionHandler
.createEvaluationContext(authentication, methodInvocation);
SecurityExpressionRoot root = (SecurityExpressionRoot) context.getRootObject()
.getValue();
EvaluationContext context = this.methodSecurityExpressionHandler.createEvaluationContext(authentication,
methodInvocation);
SecurityExpressionRoot root = (SecurityExpressionRoot) context.getRootObject().getValue();
assertThat(root.hasRole("ROLE_ABC")).isTrue();
assertThat(root.hasRole("ABC")).isTrue();
@@ -81,24 +79,25 @@ public class ReactiveMethodSecurityConfigurationTests {
@Configuration
@EnableReactiveMethodSecurity // this imports ReactiveMethodSecurityConfiguration
static class WithRolePrefixConfiguration {
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("CUSTOM_");
}
}
@Test
public void rolePrefixWithGrantedAuthorityDefaultsAndSubclassWithProxyingEnabled() throws NoSuchMethodException {
this.spring.register(SubclassConfig.class).autowire();
TestingAuthenticationToken authentication = new TestingAuthenticationToken(
"principal", "credential", "ROLE_ABC");
TestingAuthenticationToken authentication = new TestingAuthenticationToken("principal", "credential",
"ROLE_ABC");
MockMethodInvocation methodInvocation = new MockMethodInvocation(new Foo(), Foo.class, "bar", String.class);
EvaluationContext context = this.methodSecurityExpressionHandler
.createEvaluationContext(authentication, methodInvocation);
SecurityExpressionRoot root = (SecurityExpressionRoot) context.getRootObject()
.getValue();
EvaluationContext context = this.methodSecurityExpressionHandler.createEvaluationContext(authentication,
methodInvocation);
SecurityExpressionRoot root = (SecurityExpressionRoot) context.getRootObject().getValue();
assertThat(root.hasRole("ROLE_ABC")).isTrue();
assertThat(root.hasRole("ABC")).isTrue();
@@ -106,10 +105,14 @@ public class ReactiveMethodSecurityConfigurationTests {
@Configuration
static class SubclassConfig extends ReactiveMethodSecurityConfiguration {
}
private static class Foo {
public void bar(String param){
public void bar(String param) {
}
}
}

View File

@@ -42,6 +42,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
*
*/
public class SampleEnableGlobalMethodSecurityTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -50,8 +51,8 @@ public class SampleEnableGlobalMethodSecurityTests {
@Before
public void setup() {
SecurityContextHolder.getContext().setAuthentication(
new TestingAuthenticationToken("user", "password", "ROLE_USER"));
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
}
@Test
@@ -61,12 +62,12 @@ public class SampleEnableGlobalMethodSecurityTests {
assertThat(this.methodSecurityService.secured()).isNull();
assertThat(this.methodSecurityService.jsr250()).isNull();
assertThatThrownBy(() -> this.methodSecurityService.preAuthorize())
.isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.methodSecurityService.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled=true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class SampleWebSecurityConfig {
@Bean
public MethodSecurityService methodSecurityService() {
return new MethodSecurityServiceImpl();
@@ -81,8 +82,8 @@ public class SampleEnableGlobalMethodSecurityTests {
.withUser("admin").password("password").roles("USER", "ADMIN");
// @formatter:on
}
}
}
@Test
public void customPermissionHandler() {
@@ -91,12 +92,12 @@ public class SampleEnableGlobalMethodSecurityTests {
assertThat(this.methodSecurityService.hasPermission("allowed")).isNull();
assertThatThrownBy(() -> this.methodSecurityService.hasPermission("denied"))
.isInstanceOf(AccessDeniedException.class);
.isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled=true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class CustomPermissionEvaluatorWebSecurityConfig extends GlobalMethodSecurityConfiguration {
@Bean
public MethodSecurityService methodSecurityService() {
return new MethodSecurityServiceImpl();
@@ -118,18 +119,20 @@ public class SampleEnableGlobalMethodSecurityTests {
.withUser("admin").password("password").roles("USER", "ADMIN");
// @formatter:on
}
}
static class CustomPermissionEvaluator implements PermissionEvaluator {
public boolean hasPermission(Authentication authentication,
Object targetDomainObject, Object permission) {
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
return !"denied".equals(targetDomainObject);
}
public boolean hasPermission(Authentication authentication,
Serializable targetId, String targetType, Object permission) {
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
return !"denied".equals(targetId);
}
}
}

View File

@@ -77,21 +77,23 @@ public class Sec2758Tests {
this.spring.register(SecurityConfig.class).autowire();
assertThatCode(() -> service.doJsr250())
.doesNotThrowAnyException();
assertThatCode(() -> service.doJsr250()).doesNotThrowAnyException();
assertThatCode(() -> service.doPreAuthorize())
.doesNotThrowAnyException();
assertThatCode(() -> service.doPreAuthorize()).doesNotThrowAnyException();
}
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true, jsr250Enabled = true)
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
static class SecurityConfig extends WebSecurityConfigurerAdapter {
@RestController
static class RootController {
@GetMapping("/")
public String ok() { return "ok"; }
public String ok() {
return "ok";
}
}
@Override
@@ -116,11 +118,15 @@ public class Sec2758Tests {
}
static class Service {
@PreAuthorize("hasRole('CUSTOM')")
public void doPreAuthorize() {}
public void doPreAuthorize() {
}
@RolesAllowed("CUSTOM")
public void doJsr250() {}
public void doJsr250() {
}
}
static class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {
@@ -148,5 +154,7 @@ public class Sec2758Tests {
public int getOrder() {
return PriorityOrdered.HIGHEST_PRECEDENCE;
}
}
}

View File

@@ -34,6 +34,7 @@ import static org.mockito.Mockito.verify;
* @author Joe Grandja
*/
public class AbstractConfiguredSecurityBuilderTests {
private TestConfiguredSecurityBuilder builder;
@Before
@@ -80,7 +81,8 @@ public class AbstractConfiguredSecurityBuilderTests {
@Test(expected = IllegalStateException.class)
public void getConfigurerWhenMultipleConfigurersThenThrowIllegalStateException() throws Exception {
TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class), true);
TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class),
true);
builder.apply(new DelegateSecurityConfigurer());
builder.apply(new DelegateSecurityConfigurer());
builder.getConfigurer(DelegateSecurityConfigurer.class);
@@ -88,7 +90,8 @@ public class AbstractConfiguredSecurityBuilderTests {
@Test(expected = IllegalStateException.class)
public void removeConfigurerWhenMultipleConfigurersThenThrowIllegalStateException() throws Exception {
TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class), true);
TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class),
true);
builder.apply(new DelegateSecurityConfigurer());
builder.apply(new DelegateSecurityConfigurer());
builder.removeConfigurer(DelegateSecurityConfigurer.class);
@@ -98,10 +101,12 @@ public class AbstractConfiguredSecurityBuilderTests {
public void removeConfigurersWhenMultipleConfigurersThenConfigurersRemoved() throws Exception {
DelegateSecurityConfigurer configurer1 = new DelegateSecurityConfigurer();
DelegateSecurityConfigurer configurer2 = new DelegateSecurityConfigurer();
TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class), true);
TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class),
true);
builder.apply(configurer1);
builder.apply(configurer2);
List<DelegateSecurityConfigurer> removedConfigurers = builder.removeConfigurers(DelegateSecurityConfigurer.class);
List<DelegateSecurityConfigurer> removedConfigurers = builder
.removeConfigurers(DelegateSecurityConfigurer.class);
assertThat(removedConfigurers).hasSize(2);
assertThat(removedConfigurers).containsExactly(configurer1, configurer2);
assertThat(builder.getConfigurers(DelegateSecurityConfigurer.class)).isEmpty();
@@ -111,7 +116,8 @@ public class AbstractConfiguredSecurityBuilderTests {
public void getConfigurersWhenMultipleConfigurersThenConfigurersReturned() throws Exception {
DelegateSecurityConfigurer configurer1 = new DelegateSecurityConfigurer();
DelegateSecurityConfigurer configurer2 = new DelegateSecurityConfigurer();
TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class), true);
TestConfiguredSecurityBuilder builder = new TestConfiguredSecurityBuilder(mock(ObjectPostProcessor.class),
true);
builder.apply(configurer1);
builder.apply(configurer2);
List<DelegateSecurityConfigurer> configurers = builder.getConfigurers(DelegateSecurityConfigurer.class);
@@ -120,29 +126,39 @@ public class AbstractConfiguredSecurityBuilderTests {
assertThat(builder.getConfigurers(DelegateSecurityConfigurer.class)).hasSize(2);
}
private static class DelegateSecurityConfigurer extends SecurityConfigurerAdapter<Object, TestConfiguredSecurityBuilder> {
private static class DelegateSecurityConfigurer
extends SecurityConfigurerAdapter<Object, TestConfiguredSecurityBuilder> {
private static SecurityConfigurer<Object, TestConfiguredSecurityBuilder> CONFIGURER;
@Override
public void init(TestConfiguredSecurityBuilder builder) throws Exception {
builder.apply(CONFIGURER);
}
}
private static class TestSecurityConfigurer extends SecurityConfigurerAdapter<Object, TestConfiguredSecurityBuilder> { }
private static class TestSecurityConfigurer
extends SecurityConfigurerAdapter<Object, TestConfiguredSecurityBuilder> {
private static class TestConfiguredSecurityBuilder extends AbstractConfiguredSecurityBuilder<Object, TestConfiguredSecurityBuilder> {
}
private static class TestConfiguredSecurityBuilder
extends AbstractConfiguredSecurityBuilder<Object, TestConfiguredSecurityBuilder> {
private TestConfiguredSecurityBuilder(ObjectPostProcessor<Object> objectPostProcessor) {
super(objectPostProcessor);
}
private TestConfiguredSecurityBuilder(ObjectPostProcessor<Object> objectPostProcessor, boolean allowConfigurersOfSameType) {
private TestConfiguredSecurityBuilder(ObjectPostProcessor<Object> objectPostProcessor,
boolean allowConfigurersOfSameType) {
super(objectPostProcessor, allowConfigurersOfSameType);
}
public Object performBuild() {
return "success";
}
}
}

View File

@@ -30,10 +30,11 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
*
* @author Ankur Pathak
*/
public class AbstractRequestMatcherRegistryAnyMatcherTests{
public class AbstractRequestMatcherRegistryAnyMatcherTests {
@EnableWebSecurity
static class AntMatchersAfterAnyRequestConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -43,15 +44,17 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
// @formatter:on
}
}
@Test(expected = BeanCreationException.class)
public void antMatchersCanNotWorkAfterAnyRequest(){
public void antMatchersCanNotWorkAfterAnyRequest() {
loadConfig(AntMatchersAfterAnyRequestConfig.class);
}
@EnableWebSecurity
static class MvcMatchersAfterAnyRequestConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -61,6 +64,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
// @formatter:on
}
}
@Test(expected = BeanCreationException.class)
@@ -70,6 +74,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
@EnableWebSecurity
static class RegexMatchersAfterAnyRequestConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -79,6 +84,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
// @formatter:on
}
}
@Test(expected = BeanCreationException.class)
@@ -88,6 +94,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
@EnableWebSecurity
static class AnyRequestAfterItselfConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -97,6 +104,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
// @formatter:on
}
}
@Test(expected = BeanCreationException.class)
@@ -106,6 +114,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
@EnableWebSecurity
static class RequestMatchersAfterAnyRequestConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -115,6 +124,7 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
// @formatter:on
}
}
@Test(expected = BeanCreationException.class)
@@ -129,4 +139,5 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests{
context.setServletContext(new MockServletContext());
context.refresh();
}
}

View File

@@ -32,6 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Joe Grandja
*/
public class AbstractRequestMatcherRegistryTests {
private TestRequestMatcherRegistry matcherRegistry;
@Before
@@ -87,5 +88,7 @@ public class AbstractRequestMatcherRegistryTests {
protected List<RequestMatcher> chainRequestMatchers(List<RequestMatcher> requestMatchers) {
return requestMatchers;
}
}
}

View File

@@ -41,7 +41,6 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
*
* @author Rob Winch
*
*/
@@ -49,8 +48,10 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ContextConfiguration
@WebAppConfiguration
public class HttpSecurityHeadersTests {
@Autowired
WebApplicationContext wac;
@Autowired
Filter springSecurityFilterChain;
@@ -58,44 +59,46 @@ public class HttpSecurityHeadersTests {
@Before
public void setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.addFilters(springSecurityFilterChain)
.build();
mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(springSecurityFilterChain).build();
}
// gh-2953
// gh-3975
@Test
public void headerWhenSpringMvcResourceThenCacheRelatedHeadersReset() throws Exception {
mockMvc.perform(get("/resources/file.js"))
.andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "max-age=12345"))
.andExpect(header().doesNotExist(HttpHeaders.PRAGMA))
.andExpect(header().doesNotExist(HttpHeaders.EXPIRES));
mockMvc.perform(get("/resources/file.js")).andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "max-age=12345"))
.andExpect(header().doesNotExist(HttpHeaders.PRAGMA))
.andExpect(header().doesNotExist(HttpHeaders.EXPIRES));
}
@Test
public void headerWhenNotSpringResourceThenCacheRelatedHeadersSet() throws Exception {
mockMvc.perform(get("/notresource"))
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache"))
.andExpect(header().string(HttpHeaders.EXPIRES, "0"));
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache"))
.andExpect(header().string(HttpHeaders.EXPIRES, "0"));
}
@EnableWebSecurity
static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
}
}
@EnableWebMvc
@Configuration
static class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/").setCachePeriod(12345);
registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/")
.setCachePeriod(12345);
}
}
}

View File

@@ -48,6 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Joe Grandja
*/
public class SampleWebSecurityConfigurerAdapterTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -55,7 +56,9 @@ public class SampleWebSecurityConfigurerAdapterTests {
private FilterChainProxy springSecurityFilterChain;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private MockFilterChain chain;
@Before
@@ -129,10 +132,12 @@ public class SampleWebSecurityConfigurerAdapterTests {
* </authentication-provider>
* </authentication-manager>
* </code>
*
* @author Rob Winch
*/
@EnableWebSecurity
public static class HelloWorldWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -141,8 +146,8 @@ public class SampleWebSecurityConfigurerAdapterTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
}
@Test
public void readmeSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception {
@@ -201,11 +206,13 @@ public class SampleWebSecurityConfigurerAdapterTests {
* <authentication-provider>
* <user-service>
* <user username="user" password="password" authorities="ROLE_USER"/>
* <user username="admin" password="password" authorities="ROLE_USER,ROLE_ADMIN"/>
* <user username="admin" password="password" authorities=
"ROLE_USER,ROLE_ADMIN"/>
* </user-service>
* </authentication-provider>
* </authentication-manager>
* </code>
*
* @author Rob Winch
*/
@EnableWebSecurity
@@ -213,9 +220,7 @@ public class SampleWebSecurityConfigurerAdapterTests {
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers("/resources/**");
web.ignoring().antMatchers("/resources/**");
}
@Override
@@ -242,8 +247,8 @@ public class SampleWebSecurityConfigurerAdapterTests {
.withUser(PasswordEncodedUser.admin());
// @formatter:on
}
}
}
@Test
public void multiHttpSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception {
@@ -293,7 +298,8 @@ public class SampleWebSecurityConfigurerAdapterTests {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/api/admin/test");
this.request.addHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes()));
this.request.addHeader("Authorization",
"Basic " + Base64.getEncoder().encodeToString("user:password".getBytes()));
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
@@ -304,7 +310,8 @@ public class SampleWebSecurityConfigurerAdapterTests {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/api/admin/test");
this.request.addHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString("admin:password".getBytes()));
this.request.addHeader("Authorization",
"Basic " + Base64.getEncoder().encodeToString("admin:password".getBytes()));
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
@@ -339,15 +346,18 @@ public class SampleWebSecurityConfigurerAdapterTests {
* <authentication-provider>
* <user-service>
* <user username="user" password="password" authorities="ROLE_USER"/>
* <user username="admin" password="password" authorities="ROLE_USER,ROLE_ADMIN"/>
* <user username="admin" password="password" authorities=
"ROLE_USER,ROLE_ADMIN"/>
* </user-service>
* </authentication-provider>
* </authentication-manager>
* </code>
*
* @author Rob Winch
*/
@EnableWebSecurity
public static class SampleMultiHttpSecurityConfig {
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -361,6 +371,7 @@ public class SampleWebSecurityConfigurerAdapterTests {
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -372,15 +383,15 @@ public class SampleWebSecurityConfigurerAdapterTests {
.httpBasic();
// @formatter:on
}
}
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers("/resources/**");
web.ignoring().antMatchers("/resources/**");
}
@Override
@@ -396,6 +407,9 @@ public class SampleWebSecurityConfigurerAdapterTests {
.permitAll();
// @formatter:on
}
}
}
}

View File

@@ -53,14 +53,15 @@ import static org.powermock.api.mockito.PowerMockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
/**
*
* @author Rob Winch
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({ SpringFactoriesLoader.class, WebAsyncManager.class })
@PowerMockIgnore({ "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*", "javax.xml.parsers.*", "javax.xml.transform.*" })
@PowerMockIgnore({ "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*", "javax.xml.parsers.*",
"javax.xml.transform.*" })
public class WebSecurityConfigurerAdapterPowermockTests {
ConfigurableWebApplicationContext context;
@Rule
@@ -80,9 +81,8 @@ public class WebSecurityConfigurerAdapterPowermockTests {
public void loadConfigWhenDefaultConfigurerAsSpringFactoryhenDefaultConfigurerApplied() {
spy(SpringFactoriesLoader.class);
DefaultConfigurer configurer = new DefaultConfigurer();
when(SpringFactoriesLoader
.loadFactories(AbstractHttpConfigurer.class, getClass().getClassLoader()))
.thenReturn(Arrays.<AbstractHttpConfigurer>asList(configurer));
when(SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, getClass().getClassLoader()))
.thenReturn(Arrays.<AbstractHttpConfigurer>asList(configurer));
loadConfig(Config.class);
@@ -100,13 +100,17 @@ public class WebSecurityConfigurerAdapterPowermockTests {
@EnableWebSecurity
static class Config extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
}
}
static class DefaultConfigurer extends AbstractHttpConfigurer<DefaultConfigurer, HttpSecurity> {
boolean init;
boolean configure;
@Override
@@ -118,6 +122,7 @@ public class WebSecurityConfigurerAdapterPowermockTests {
public void configure(HttpSecurity builder) {
this.configure = true;
}
}
@Test
@@ -128,15 +133,15 @@ public class WebSecurityConfigurerAdapterPowermockTests {
this.mockMvc.perform(get("/").requestAttr(WebAsyncUtils.WEB_ASYNC_MANAGER_ATTRIBUTE, webAsyncManager));
ArgumentCaptor<CallableProcessingInterceptor> callableProcessingInterceptorArgCaptor =
ArgumentCaptor.forClass(CallableProcessingInterceptor.class);
verify(webAsyncManager, atLeastOnce()).registerCallableInterceptor(any(), callableProcessingInterceptorArgCaptor.capture());
ArgumentCaptor<CallableProcessingInterceptor> callableProcessingInterceptorArgCaptor = ArgumentCaptor
.forClass(CallableProcessingInterceptor.class);
verify(webAsyncManager, atLeastOnce()).registerCallableInterceptor(any(),
callableProcessingInterceptorArgCaptor.capture());
CallableProcessingInterceptor callableProcessingInterceptor =
callableProcessingInterceptorArgCaptor.getAllValues().stream()
.filter(e -> SecurityContextCallableProcessingInterceptor.class.isAssignableFrom(e.getClass()))
.findFirst()
.orElse(null);
CallableProcessingInterceptor callableProcessingInterceptor = callableProcessingInterceptorArgCaptor
.getAllValues().stream()
.filter(e -> SecurityContextCallableProcessingInterceptor.class.isAssignableFrom(e.getClass()))
.findFirst().orElse(null);
assertThat(callableProcessingInterceptor).isNotNull();
}
@@ -156,5 +161,7 @@ public class WebSecurityConfigurerAdapterPowermockTests {
@Override
protected void configure(HttpSecurity http) {
}
}
}

View File

@@ -71,6 +71,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Joe Grandja
*/
public class WebSecurityConfigurerAdapterTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -81,14 +82,12 @@ public class WebSecurityConfigurerAdapterTests {
public void loadConfigWhenRequestSecureThenDefaultSecurityHeadersReturned() throws Exception {
this.spring.register(HeadersArePopulatedByDefaultConfig.class).autowire();
this.mockMvc.perform(get("/").secure(true))
.andExpect(header().string("X-Content-Type-Options", "nosniff"))
.andExpect(header().string("X-Frame-Options", "DENY"))
.andExpect(header().string("Strict-Transport-Security", "max-age=31536000 ; includeSubDomains"))
.andExpect(header().string("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string("Pragma", "no-cache"))
.andExpect(header().string("Expires", "0"))
.andExpect(header().string("X-XSS-Protection", "1; mode=block"));
this.mockMvc.perform(get("/").secure(true)).andExpect(header().string("X-Content-Type-Options", "nosniff"))
.andExpect(header().string("X-Frame-Options", "DENY"))
.andExpect(header().string("Strict-Transport-Security", "max-age=31536000 ; includeSubDomains"))
.andExpect(header().string("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string("Pragma", "no-cache")).andExpect(header().string("Expires", "0"))
.andExpect(header().string("X-XSS-Protection", "1; mode=block"));
}
@EnableWebSecurity
@@ -106,14 +105,14 @@ public class WebSecurityConfigurerAdapterTests {
@Override
protected void configure(HttpSecurity http) {
}
}
@Test
public void loadConfigWhenRequestAuthenticateThenAuthenticationEventPublished() throws Exception {
this.spring.register(InMemoryAuthWithWebSecurityConfigurerAdapter.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(status().is3xxRedirection());
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
assertThat(InMemoryAuthWithWebSecurityConfigurerAdapter.EVENTS).isNotEmpty();
assertThat(InMemoryAuthWithWebSecurityConfigurerAdapter.EVENTS).hasSize(1);
@@ -121,7 +120,7 @@ public class WebSecurityConfigurerAdapterTests {
@EnableWebSecurity
static class InMemoryAuthWithWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter
implements ApplicationListener<AuthenticationSuccessEvent> {
implements ApplicationListener<AuthenticationSuccessEvent> {
static List<AuthenticationSuccessEvent> EVENTS = new ArrayList<>();
@@ -138,22 +137,22 @@ public class WebSecurityConfigurerAdapterTests {
public void onApplicationEvent(AuthenticationSuccessEvent event) {
EVENTS.add(event);
}
}
@Test
public void loadConfigWhenInMemoryConfigureProtectedThenPasswordUpgraded() throws Exception {
this.spring.register(InMemoryConfigureProtectedConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(status().is3xxRedirection());
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
UserDetailsService uds = this.spring.getContext()
.getBean(UserDetailsService.class);
UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
assertThat(uds.loadUserByUsername("user").getPassword()).startsWith("{bcrypt}");
}
@EnableWebSecurity
static class InMemoryConfigureProtectedConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -168,22 +167,22 @@ public class WebSecurityConfigurerAdapterTests {
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
}
@Test
public void loadConfigWhenInMemoryConfigureGlobalThenPasswordUpgraded() throws Exception {
this.spring.register(InMemoryConfigureGlobalConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(status().is3xxRedirection());
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
UserDetailsService uds = this.spring.getContext()
.getBean(UserDetailsService.class);
UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
assertThat(uds.loadUserByUsername("user").getPassword()).startsWith("{bcrypt}");
}
@EnableWebSecurity
static class InMemoryConfigureGlobalConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -198,24 +197,28 @@ public class WebSecurityConfigurerAdapterTests {
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
}
@Test
public void loadConfigWhenCustomContentNegotiationStrategyBeanThenOverridesDefault() {
OverrideContentNegotiationStrategySharedObjectConfig.CONTENT_NEGOTIATION_STRATEGY_BEAN = mock(ContentNegotiationStrategy.class);
OverrideContentNegotiationStrategySharedObjectConfig.CONTENT_NEGOTIATION_STRATEGY_BEAN = mock(
ContentNegotiationStrategy.class);
this.spring.register(OverrideContentNegotiationStrategySharedObjectConfig.class).autowire();
OverrideContentNegotiationStrategySharedObjectConfig securityConfig =
this.spring.getContext().getBean(OverrideContentNegotiationStrategySharedObjectConfig.class);
OverrideContentNegotiationStrategySharedObjectConfig securityConfig = this.spring.getContext()
.getBean(OverrideContentNegotiationStrategySharedObjectConfig.class);
assertThat(securityConfig.contentNegotiationStrategySharedObject).isNotNull();
assertThat(securityConfig.contentNegotiationStrategySharedObject)
.isSameAs(OverrideContentNegotiationStrategySharedObjectConfig.CONTENT_NEGOTIATION_STRATEGY_BEAN);
.isSameAs(OverrideContentNegotiationStrategySharedObjectConfig.CONTENT_NEGOTIATION_STRATEGY_BEAN);
}
@EnableWebSecurity
static class OverrideContentNegotiationStrategySharedObjectConfig extends WebSecurityConfigurerAdapter {
static ContentNegotiationStrategy CONTENT_NEGOTIATION_STRATEGY_BEAN;
private ContentNegotiationStrategy contentNegotiationStrategySharedObject;
@Bean
@@ -228,21 +231,24 @@ public class WebSecurityConfigurerAdapterTests {
this.contentNegotiationStrategySharedObject = http.getSharedObject(ContentNegotiationStrategy.class);
super.configure(http);
}
}
@Test
public void loadConfigWhenDefaultContentNegotiationStrategyThenHeaderContentNegotiationStrategy() {
this.spring.register(ContentNegotiationStrategyDefaultSharedObjectConfig.class).autowire();
ContentNegotiationStrategyDefaultSharedObjectConfig securityConfig =
this.spring.getContext().getBean(ContentNegotiationStrategyDefaultSharedObjectConfig.class);
ContentNegotiationStrategyDefaultSharedObjectConfig securityConfig = this.spring.getContext()
.getBean(ContentNegotiationStrategyDefaultSharedObjectConfig.class);
assertThat(securityConfig.contentNegotiationStrategySharedObject).isNotNull();
assertThat(securityConfig.contentNegotiationStrategySharedObject).isInstanceOf(HeaderContentNegotiationStrategy.class);
assertThat(securityConfig.contentNegotiationStrategySharedObject)
.isInstanceOf(HeaderContentNegotiationStrategy.class);
}
@EnableWebSecurity
static class ContentNegotiationStrategyDefaultSharedObjectConfig extends WebSecurityConfigurerAdapter {
private ContentNegotiationStrategy contentNegotiationStrategySharedObject;
@Override
@@ -250,6 +256,7 @@ public class WebSecurityConfigurerAdapterTests {
this.contentNegotiationStrategySharedObject = http.getSharedObject(ContentNegotiationStrategy.class);
super.configure(http);
}
}
@Test
@@ -258,23 +265,26 @@ public class WebSecurityConfigurerAdapterTests {
MyFilter myFilter = this.spring.getContext().getBean(MyFilter.class);
Throwable thrown = catchThrowable(() -> myFilter.userDetailsService.loadUserByUsername("user") );
Throwable thrown = catchThrowable(() -> myFilter.userDetailsService.loadUserByUsername("user"));
assertThat(thrown).isNull();
thrown = catchThrowable(() -> myFilter.userDetailsService.loadUserByUsername("admin") );
thrown = catchThrowable(() -> myFilter.userDetailsService.loadUserByUsername("admin"));
assertThat(thrown).isInstanceOf(UsernameNotFoundException.class);
}
@Configuration
static class RequiresUserDetailsServiceConfig {
@Bean
public MyFilter myFilter(UserDetailsService userDetailsService) {
return new MyFilter(userDetailsService);
}
}
@EnableWebSecurity
static class UserDetailsServiceConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyFilter myFilter;
@@ -297,9 +307,11 @@ public class WebSecurityConfigurerAdapterTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
static class MyFilter extends OncePerRequestFilter {
private UserDetailsService userDetailsService;
MyFilter(UserDetailsService userDetailsService) {
@@ -307,11 +319,11 @@ public class WebSecurityConfigurerAdapterTests {
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filterChain.doFilter(request, response);
}
}
// SEC-2274: WebSecurityConfigurer adds ApplicationContext as a shared object
@@ -319,8 +331,8 @@ public class WebSecurityConfigurerAdapterTests {
public void loadConfigWhenSharedObjectsCreatedThenApplicationContextAdded() {
this.spring.register(ApplicationContextSharedObjectConfig.class).autowire();
ApplicationContextSharedObjectConfig securityConfig =
this.spring.getContext().getBean(ApplicationContextSharedObjectConfig.class);
ApplicationContextSharedObjectConfig securityConfig = this.spring.getContext()
.getBean(ApplicationContextSharedObjectConfig.class);
assertThat(securityConfig.applicationContextSharedObject).isNotNull();
assertThat(securityConfig.applicationContextSharedObject).isSameAs(this.spring.getContext());
@@ -328,6 +340,7 @@ public class WebSecurityConfigurerAdapterTests {
@EnableWebSecurity
static class ApplicationContextSharedObjectConfig extends WebSecurityConfigurerAdapter {
private ApplicationContext applicationContextSharedObject;
@Override
@@ -335,6 +348,7 @@ public class WebSecurityConfigurerAdapterTests {
this.applicationContextSharedObject = http.getSharedObject(ApplicationContext.class);
super.configure(http);
}
}
@Test
@@ -342,17 +356,18 @@ public class WebSecurityConfigurerAdapterTests {
CustomTrustResolverConfig.AUTHENTICATION_TRUST_RESOLVER_BEAN = mock(AuthenticationTrustResolver.class);
this.spring.register(CustomTrustResolverConfig.class).autowire();
CustomTrustResolverConfig securityConfig =
this.spring.getContext().getBean(CustomTrustResolverConfig.class);
CustomTrustResolverConfig securityConfig = this.spring.getContext().getBean(CustomTrustResolverConfig.class);
assertThat(securityConfig.authenticationTrustResolverSharedObject).isNotNull();
assertThat(securityConfig.authenticationTrustResolverSharedObject)
.isSameAs(CustomTrustResolverConfig.AUTHENTICATION_TRUST_RESOLVER_BEAN);
.isSameAs(CustomTrustResolverConfig.AUTHENTICATION_TRUST_RESOLVER_BEAN);
}
@EnableWebSecurity
static class CustomTrustResolverConfig extends WebSecurityConfigurerAdapter {
static AuthenticationTrustResolver AUTHENTICATION_TRUST_RESOLVER_BEAN;
private AuthenticationTrustResolver authenticationTrustResolverSharedObject;
@Bean
@@ -365,21 +380,23 @@ public class WebSecurityConfigurerAdapterTests {
this.authenticationTrustResolverSharedObject = http.getSharedObject(AuthenticationTrustResolver.class);
super.configure(http);
}
}
@Test
public void compareOrderWebSecurityConfigurerAdapterWhenLowestOrderToDefaultOrderThenGreaterThanZero() {
AnnotationAwareOrderComparator comparator = new AnnotationAwareOrderComparator();
assertThat(comparator.compare(
new LowestPriorityWebSecurityConfig(),
new DefaultOrderWebSecurityConfig())).isGreaterThan(0);
assertThat(comparator.compare(new LowestPriorityWebSecurityConfig(), new DefaultOrderWebSecurityConfig()))
.isGreaterThan(0);
}
static class DefaultOrderWebSecurityConfig extends WebSecurityConfigurerAdapter {
}
@Order
static class LowestPriorityWebSecurityConfig extends WebSecurityConfigurerAdapter {
}
// gh-7515
@@ -387,17 +404,17 @@ public class WebSecurityConfigurerAdapterTests {
public void performWhenUsingAuthenticationEventPublisherBeanThenUses() throws Exception {
this.spring.register(CustomAuthenticationEventPublisherBean.class).autowire();
AuthenticationEventPublisher authenticationEventPublisher =
this.spring.getContext().getBean(AuthenticationEventPublisher.class);
AuthenticationEventPublisher authenticationEventPublisher = this.spring.getContext()
.getBean(AuthenticationEventPublisher.class);
this.mockMvc.perform(get("/")
.with(httpBasic("user", "password")));
this.mockMvc.perform(get("/").with(httpBasic("user", "password")));
verify(authenticationEventPublisher).publishAuthenticationSuccess(any(Authentication.class));
}
@EnableWebSecurity
static class CustomAuthenticationEventPublisherBean extends WebSecurityConfigurerAdapter {
@Bean
@Override
public UserDetailsService userDetailsService() {
@@ -408,6 +425,7 @@ public class WebSecurityConfigurerAdapterTests {
public AuthenticationEventPublisher authenticationEventPublisher() {
return mock(AuthenticationEventPublisher.class);
}
}
// gh-4400
@@ -415,24 +433,27 @@ public class WebSecurityConfigurerAdapterTests {
public void performWhenUsingAuthenticationEventPublisherInDslThenUses() throws Exception {
this.spring.register(CustomAuthenticationEventPublisherDsl.class).autowire();
AuthenticationEventPublisher authenticationEventPublisher =
CustomAuthenticationEventPublisherDsl.EVENT_PUBLISHER;
AuthenticationEventPublisher authenticationEventPublisher = CustomAuthenticationEventPublisherDsl.EVENT_PUBLISHER;
this.mockMvc.perform(get("/")
.with(httpBasic("user", "password"))); // fails since no providers configured
this.mockMvc.perform(get("/").with(httpBasic("user", "password"))); // fails since
// no
// providers
// configured
verify(authenticationEventPublisher).publishAuthenticationFailure(
any(AuthenticationException.class),
verify(authenticationEventPublisher).publishAuthenticationFailure(any(AuthenticationException.class),
any(Authentication.class));
}
@EnableWebSecurity
static class CustomAuthenticationEventPublisherDsl extends WebSecurityConfigurerAdapter {
static AuthenticationEventPublisher EVENT_PUBLISHER = mock(AuthenticationEventPublisher.class);
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationEventPublisher(EVENT_PUBLISHER);
}
}
}

View File

@@ -49,6 +49,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Joe Grandja
*/
public class HttpConfigurationTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -57,11 +58,11 @@ public class HttpConfigurationTests {
@Test
public void configureWhenAddFilterUnregisteredThenThrowsBeanCreationException() {
Throwable thrown = catchThrowable(() -> this.spring.register(UnregisteredFilterConfig.class).autowire() );
Throwable thrown = catchThrowable(() -> this.spring.register(UnregisteredFilterConfig.class).autowire());
assertThat(thrown).isInstanceOf(BeanCreationException.class);
assertThat(thrown.getMessage()).contains("The Filter class " + UnregisteredFilter.class.getName() +
" does not have a registered order and cannot be added without a specified order." +
" Consider using addFilterBefore or addFilterAfter instead.");
assertThat(thrown.getMessage()).contains("The Filter class " + UnregisteredFilter.class.getName()
+ " does not have a registered order and cannot be added without a specified order."
+ " Consider using addFilterBefore or addFilterAfter instead.");
}
@EnableWebSecurity
@@ -81,15 +82,17 @@ public class HttpConfigurationTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
static class UnregisteredFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filterChain.doFilter(request, response);
}
}
// https://github.com/spring-projects/spring-security-javaconfig/issues/104
@@ -100,12 +103,13 @@ public class HttpConfigurationTests {
this.mockMvc.perform(get("/"));
verify(CasAuthenticationFilterConfig.CAS_AUTHENTICATION_FILTER).doFilter(
any(ServletRequest.class), any(ServletResponse.class), any(FilterChain.class));
verify(CasAuthenticationFilterConfig.CAS_AUTHENTICATION_FILTER).doFilter(any(ServletRequest.class),
any(ServletResponse.class), any(FilterChain.class));
}
@EnableWebSecurity
static class CasAuthenticationFilterConfig extends WebSecurityConfigurerAdapter {
static CasAuthenticationFilter CAS_AUTHENTICATION_FILTER;
protected void configure(HttpSecurity http) {
@@ -114,6 +118,7 @@ public class HttpConfigurationTests {
.addFilter(CAS_AUTHENTICATION_FILTER);
// @formatter:on
}
}
@Test
@@ -128,6 +133,7 @@ public class HttpConfigurationTests {
@EnableWebSecurity
static class RequestMatcherRegistryConfigs extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -142,5 +148,7 @@ public class HttpConfigurationTests {
.httpBasic();
// @formatter:on
}
}
}

View File

@@ -63,33 +63,38 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* Tests to verify that all the functionality of <http> attributes are present in Java Config.
* Tests to verify that all the functionality of <http> attributes are present in Java
* Config.
*
* @author Rob Winch
* @author Joe Grandja
*/
public class NamespaceHttpTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Autowired
private MockMvc mockMvc;
@Test // http@access-decision-manager-ref
@Test // http@access-decision-manager-ref
public void configureWhenAccessDecisionManagerSetThenVerifyUse() throws Exception {
AccessDecisionManagerRefConfig.ACCESS_DECISION_MANAGER = mock(AccessDecisionManager.class);
when(AccessDecisionManagerRefConfig.ACCESS_DECISION_MANAGER.supports(FilterInvocation.class)).thenReturn(true);
when(AccessDecisionManagerRefConfig.ACCESS_DECISION_MANAGER.supports(any(ConfigAttribute.class))).thenReturn(true);
when(AccessDecisionManagerRefConfig.ACCESS_DECISION_MANAGER.supports(any(ConfigAttribute.class)))
.thenReturn(true);
this.spring.register(AccessDecisionManagerRefConfig.class).autowire();
this.mockMvc.perform(get("/"));
verify(AccessDecisionManagerRefConfig.ACCESS_DECISION_MANAGER, times(1)).decide(any(Authentication.class), any(), anyCollection());
verify(AccessDecisionManagerRefConfig.ACCESS_DECISION_MANAGER, times(1)).decide(any(Authentication.class),
any(), anyCollection());
}
@EnableWebSecurity
static class AccessDecisionManagerRefConfig extends WebSecurityConfigurerAdapter {
static AccessDecisionManager ACCESS_DECISION_MANAGER;
@Override
@@ -101,19 +106,20 @@ public class NamespaceHttpTests {
.accessDecisionManager(ACCESS_DECISION_MANAGER);
// @formatter:on
}
}
@Test // http@access-denied-page
@Test // http@access-denied-page
public void configureWhenAccessDeniedPageSetAndRequestForbiddenThenForwardedToAccessDeniedPage() throws Exception {
this.spring.register(AccessDeniedPageConfig.class).autowire();
this.mockMvc.perform(get("/admin").with(user(PasswordEncodedUser.user())))
.andExpect(status().isForbidden())
.andExpect(forwardedUrl("/AccessDeniedPage"));
this.mockMvc.perform(get("/admin").with(user(PasswordEncodedUser.user()))).andExpect(status().isForbidden())
.andExpect(forwardedUrl("/AccessDeniedPage"));
}
@EnableWebSecurity
static class AccessDeniedPageConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -126,9 +132,10 @@ public class NamespaceHttpTests {
.accessDeniedPage("/AccessDeniedPage");
// @formatter:on
}
}
@Test // http@authentication-manager-ref
@Test // http@authentication-manager-ref
public void configureWhenAuthenticationManagerProvidedThenVerifyUse() throws Exception {
AuthenticationManagerRefConfig.AUTHENTICATION_MANAGER = mock(AuthenticationManager.class);
this.spring.register(AuthenticationManagerRefConfig.class).autowire();
@@ -140,6 +147,7 @@ public class NamespaceHttpTests {
@EnableWebSecurity
static class AuthenticationManagerRefConfig extends WebSecurityConfigurerAdapter {
static AuthenticationManager AUTHENTICATION_MANAGER;
@Override
@@ -157,9 +165,10 @@ public class NamespaceHttpTests {
.formLogin();
// @formatter:on
}
}
@Test // http@create-session=always
@Test // http@create-session=always
public void configureWhenSessionCreationPolicyAlwaysThenSessionCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionAlwaysConfig.class).autowire();
@@ -172,6 +181,7 @@ public class NamespaceHttpTests {
@EnableWebSecurity
static class CreateSessionAlwaysConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -183,9 +193,10 @@ public class NamespaceHttpTests {
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
// @formatter:on
}
}
@Test // http@create-session=stateless
@Test // http@create-session=stateless
public void configureWhenSessionCreationPolicyStatelessThenSessionNotCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionStatelessConfig.class).autowire();
@@ -197,6 +208,7 @@ public class NamespaceHttpTests {
@EnableWebSecurity
static class CreateSessionStatelessConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -208,9 +220,10 @@ public class NamespaceHttpTests {
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// @formatter:on
}
}
@Test // http@create-session=ifRequired
@Test // http@create-session=ifRequired
public void configureWhenSessionCreationPolicyIfRequiredThenSessionCreatedWhenRequiredOnRequest() throws Exception {
this.spring.register(IfRequiredConfig.class).autowire();
@@ -228,6 +241,7 @@ public class NamespaceHttpTests {
@EnableWebSecurity
static class IfRequiredConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -242,9 +256,10 @@ public class NamespaceHttpTests {
.formLogin();
// @formatter:on
}
}
@Test // http@create-session=never
@Test // http@create-session=never
public void configureWhenSessionCreationPolicyNeverThenSessionNotCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionNeverConfig.class).autowire();
@@ -256,6 +271,7 @@ public class NamespaceHttpTests {
@EnableWebSecurity
static class CreateSessionNeverConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -267,19 +283,21 @@ public class NamespaceHttpTests {
.sessionCreationPolicy(SessionCreationPolicy.NEVER);
// @formatter:on
}
}
@Test // http@entry-point-ref
public void configureWhenAuthenticationEntryPointSetAndRequestUnauthorizedThenRedirectedToAuthenticationEntryPoint() throws Exception {
@Test // http@entry-point-ref
public void configureWhenAuthenticationEntryPointSetAndRequestUnauthorizedThenRedirectedToAuthenticationEntryPoint()
throws Exception {
this.spring.register(EntryPointRefConfig.class).autowire();
this.mockMvc.perform(get("/"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrlPattern("**/entry-point"));
this.mockMvc.perform(get("/")).andExpect(status().is3xxRedirection())
.andExpect(redirectedUrlPattern("**/entry-point"));
}
@EnableWebSecurity
static class EntryPointRefConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -293,9 +311,10 @@ public class NamespaceHttpTests {
.formLogin();
// @formatter:on
}
}
@Test // http@jaas-api-provision
@Test // http@jaas-api-provision
public void configureWhenJaasApiIntegrationFilterAddedThenJaasSubjectObtained() throws Exception {
LoginContext loginContext = mock(LoginContext.class);
when(loginContext.getSubject()).thenReturn(new Subject());
@@ -313,6 +332,7 @@ public class NamespaceHttpTests {
@EnableWebSecurity
static class JaasApiProvisionConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
// @formatter:off
@@ -320,19 +340,20 @@ public class NamespaceHttpTests {
.addFilter(new JaasApiIntegrationFilter());
// @formatter:on
}
}
@Test // http@realm
@Test // http@realm
public void configureWhenHttpBasicAndRequestUnauthorizedThenReturnWWWAuthenticateWithRealm() throws Exception {
this.spring.register(RealmConfig.class).autowire();
this.mockMvc.perform(get("/"))
.andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"RealmConfig\""));
this.mockMvc.perform(get("/")).andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"RealmConfig\""));
}
@EnableWebSecurity
static class RealmConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -344,21 +365,24 @@ public class NamespaceHttpTests {
.realmName("RealmConfig");
// @formatter:on
}
}
@Test // http@request-matcher-ref ant
@Test // http@request-matcher-ref ant
public void configureWhenAntPatternMatchingThenAntPathRequestMatcherUsed() {
this.spring.register(RequestMatcherAntConfig.class).autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
assertThat(filterChainProxy.getFilterChains().get(0)).isInstanceOf(DefaultSecurityFilterChain.class);
DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains().get(0);
DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains()
.get(0);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
}
@EnableWebSecurity
static class RequestMatcherAntConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
// @formatter:off
@@ -366,21 +390,24 @@ public class NamespaceHttpTests {
.antMatcher("/api/**");
// @formatter:on
}
}
@Test // http@request-matcher-ref regex
@Test // http@request-matcher-ref regex
public void configureWhenRegexPatternMatchingThenRegexRequestMatcherUsed() {
this.spring.register(RequestMatcherRegexConfig.class).autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
assertThat(filterChainProxy.getFilterChains().get(0)).isInstanceOf(DefaultSecurityFilterChain.class);
DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains().get(0);
DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains()
.get(0);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(RegexRequestMatcher.class);
}
@EnableWebSecurity
static class RequestMatcherRegexConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
// @formatter:off
@@ -388,21 +415,25 @@ public class NamespaceHttpTests {
.regexMatcher("/regex/.*");
// @formatter:on
}
}
@Test // http@request-matcher-ref
@Test // http@request-matcher-ref
public void configureWhenRequestMatcherProvidedThenRequestMatcherUsed() {
this.spring.register(RequestMatcherRefConfig.class).autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
assertThat(filterChainProxy.getFilterChains().get(0)).isInstanceOf(DefaultSecurityFilterChain.class);
DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains().get(0);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(RequestMatcherRefConfig.MyRequestMatcher.class);
DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains()
.get(0);
assertThat(securityFilterChain.getRequestMatcher())
.isInstanceOf(RequestMatcherRefConfig.MyRequestMatcher.class);
}
@EnableWebSecurity
static class RequestMatcherRefConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
// @formatter:off
@@ -412,28 +443,34 @@ public class NamespaceHttpTests {
}
static class MyRequestMatcher implements RequestMatcher {
public boolean matches(HttpServletRequest request) {
return true;
}
}
}
@Test // http@security=none
@Test // http@security=none
public void configureWhenIgnoredAntPatternsThenAntPathRequestMatcherUsedWithNoFilters() {
this.spring.register(SecurityNoneConfig.class).autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
assertThat(filterChainProxy.getFilterChains().get(0)).isInstanceOf(DefaultSecurityFilterChain.class);
DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains().get(0);
DefaultSecurityFilterChain securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains()
.get(0);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
assertThat(((AntPathRequestMatcher) securityFilterChain.getRequestMatcher()).getPattern()).isEqualTo("/resources/**");
assertThat(((AntPathRequestMatcher) securityFilterChain.getRequestMatcher()).getPattern())
.isEqualTo("/resources/**");
assertThat(securityFilterChain.getFilters()).isEmpty();
assertThat(filterChainProxy.getFilterChains().get(1)).isInstanceOf(DefaultSecurityFilterChain.class);
securityFilterChain = (DefaultSecurityFilterChain) filterChainProxy.getFilterChains().get(1);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
assertThat(((AntPathRequestMatcher) securityFilterChain.getRequestMatcher()).getPattern()).isEqualTo("/public/**");
assertThat(((AntPathRequestMatcher) securityFilterChain.getRequestMatcher()).getPattern())
.isEqualTo("/public/**");
assertThat(securityFilterChain.getFilters()).isEmpty();
}
@@ -442,17 +479,16 @@ public class NamespaceHttpTests {
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers("/resources/**", "/public/**");
web.ignoring().antMatchers("/resources/**", "/public/**");
}
@Override
protected void configure(HttpSecurity http) {
}
}
@Test // http@security-context-repository-ref
@Test // http@security-context-repository-ref
public void configureWhenNullSecurityContextRepositoryThenSecurityContextNotSavedInSession() throws Exception {
this.spring.register(SecurityContextRepoConfig.class).autowire();
@@ -463,6 +499,7 @@ public class NamespaceHttpTests {
@EnableWebSecurity
static class SecurityContextRepoConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -485,19 +522,22 @@ public class NamespaceHttpTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test // http@servlet-api-provision=false
@Test // http@servlet-api-provision=false
public void configureWhenServletApiDisabledThenRequestNotServletApiWrapper() throws Exception {
this.spring.register(ServletApiProvisionConfig.class, MainController.class).autowire();
this.mockMvc.perform(get("/"));
assertThat(MainController.HTTP_SERVLET_REQUEST_TYPE).isNotInstanceOf(SecurityContextHolderAwareRequestWrapper.class);
assertThat(MainController.HTTP_SERVLET_REQUEST_TYPE)
.isNotInstanceOf(SecurityContextHolderAwareRequestWrapper.class);
}
@EnableWebSecurity
static class ServletApiProvisionConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -509,19 +549,22 @@ public class NamespaceHttpTests {
.disable();
// @formatter:on
}
}
@Test // http@servlet-api-provision defaults to true
@Test // http@servlet-api-provision defaults to true
public void configureWhenServletApiDefaultThenRequestIsServletApiWrapper() throws Exception {
this.spring.register(ServletApiProvisionDefaultsConfig.class, MainController.class).autowire();
this.mockMvc.perform(get("/"));
assertThat(SecurityContextHolderAwareRequestWrapper.class).isAssignableFrom(MainController.HTTP_SERVLET_REQUEST_TYPE);
assertThat(SecurityContextHolderAwareRequestWrapper.class)
.isAssignableFrom(MainController.HTTP_SERVLET_REQUEST_TYPE);
}
@EnableWebSecurity
static class ServletApiProvisionDefaultsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -530,10 +573,12 @@ public class NamespaceHttpTests {
.anyRequest().permitAll();
// @formatter:on
}
}
@Controller
static class MainController {
static Class<? extends HttpServletRequest> HTTP_SERVLET_REQUEST_TYPE;
@GetMapping("/")
@@ -541,20 +586,22 @@ public class NamespaceHttpTests {
HTTP_SERVLET_REQUEST_TYPE = request.getClass();
return "index";
}
}
@Test // http@use-expressions=true
@Test // http@use-expressions=true
public void configureWhenUseExpressionsEnabledThenExpressionBasedSecurityMetadataSource() {
this.spring.register(UseExpressionsConfig.class).autowire();
UseExpressionsConfig config = this.spring.getContext().getBean(UseExpressionsConfig.class);
assertThat(ExpressionBasedFilterInvocationSecurityMetadataSource.class)
.isAssignableFrom(config.filterInvocationSecurityMetadataSourceType);
.isAssignableFrom(config.filterInvocationSecurityMetadataSourceType);
}
@EnableWebSecurity
static class UseExpressionsConfig extends WebSecurityConfigurerAdapter {
private Class<? extends FilterInvocationSecurityMetadataSource> filterInvocationSecurityMetadataSourceType;
@Override
@@ -574,24 +621,26 @@ public class NamespaceHttpTests {
final HttpSecurity http = this.getHttp();
web.postBuildAction(() -> {
FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);
UseExpressionsConfig.this.filterInvocationSecurityMetadataSourceType =
securityInterceptor.getSecurityMetadataSource().getClass();
UseExpressionsConfig.this.filterInvocationSecurityMetadataSourceType = securityInterceptor
.getSecurityMetadataSource().getClass();
});
}
}
@Test // http@use-expressions=false
@Test // http@use-expressions=false
public void configureWhenUseExpressionsDisabledThenDefaultSecurityMetadataSource() {
this.spring.register(DisableUseExpressionsConfig.class).autowire();
DisableUseExpressionsConfig config = this.spring.getContext().getBean(DisableUseExpressionsConfig.class);
assertThat(DefaultFilterInvocationSecurityMetadataSource.class)
.isAssignableFrom(config.filterInvocationSecurityMetadataSourceType);
.isAssignableFrom(config.filterInvocationSecurityMetadataSourceType);
}
@EnableWebSecurity
static class DisableUseExpressionsConfig extends WebSecurityConfigurerAdapter {
private Class<? extends FilterInvocationSecurityMetadataSource> filterInvocationSecurityMetadataSourceType;
@Override
@@ -611,9 +660,11 @@ public class NamespaceHttpTests {
final HttpSecurity http = this.getHttp();
web.postBuildAction(() -> {
FilterSecurityInterceptor securityInterceptor = http.getSharedObject(FilterSecurityInterceptor.class);
DisableUseExpressionsConfig.this.filterInvocationSecurityMetadataSourceType =
securityInterceptor.getSecurityMetadataSource().getClass();
DisableUseExpressionsConfig.this.filterInvocationSecurityMetadataSourceType = securityInterceptor
.getSecurityMetadataSource().getClass();
});
}
}
}

View File

@@ -45,10 +45,13 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Rob Winch
*/
public class WebSecurityTests {
AnnotationConfigWebApplicationContext context;
MockHttpServletRequest request;
MockHttpServletResponse response;
MockFilterChain chain;
@Autowired
@@ -97,14 +100,14 @@ public class WebSecurityTests {
this.request.setRequestURI("/other");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
// @formatter:off
@@ -134,11 +137,14 @@ public class WebSecurityTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -173,14 +179,14 @@ public class WebSecurityTests {
this.request.setRequestURI("/other/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherServletPathConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
// @formatter:off
@@ -211,19 +217,24 @@ public class WebSecurityTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Configuration
static class LegacyMvcMatchingConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(true);
}
}
public void loadConfig(Class<?>... configs) {

View File

@@ -42,7 +42,6 @@ import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
*
* @author Rob Winch
*
*/
@@ -50,6 +49,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@ContextConfiguration
@WebAppConfiguration
public class AuthenticationPrincipalArgumentResolverTests {
@Autowired
WebApplicationContext wac;
@@ -62,21 +62,19 @@ public class AuthenticationPrincipalArgumentResolverTests {
public void authenticationPrincipalExpressionWhenBeanExpressionSuppliedThenBeanUsed() throws Exception {
User user = new User("user", "password", AuthorityUtils.createAuthorityList("ROLE_USER"));
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities()));
context.setAuthentication(
new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities()));
SecurityContextHolder.setContext(context);
MockMvc mockMvc = MockMvcBuilders
.webAppContextSetup(wac)
.build();
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
mockMvc.perform(get("/users/self"))
.andExpect(status().isOk())
.andExpect(content().string("extracted-user"));
mockMvc.perform(get("/users/self")).andExpect(status().isOk()).andExpect(content().string("extracted-user"));
}
@EnableWebSecurity
@EnableWebMvc
static class Config {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off

View File

@@ -45,6 +45,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Joe Grandja
*/
public class EnableWebSecurityTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -56,12 +57,14 @@ public class EnableWebSecurityTests {
this.spring.register(SecurityConfig.class).autowire();
AuthenticationManager authenticationManager = this.spring.getContext().getBean(AuthenticationManager.class);
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
Authentication authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
assertThat(authentication.isAuthenticated()).isTrue();
}
@EnableWebSecurity
static class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -87,6 +90,7 @@ public class EnableWebSecurityTests {
.formLogin();
// @formatter:on
}
}
@Test
@@ -97,10 +101,12 @@ public class EnableWebSecurityTests {
@Configuration
static class ChildSecurityConfig extends DebugSecurityConfig {
}
@EnableWebSecurity(debug=true)
@EnableWebSecurity(debug = true)
static class DebugSecurityConfig extends WebSecurityConfigurerAdapter {
}
@Test
@@ -108,12 +114,13 @@ public class EnableWebSecurityTests {
this.spring.register(AuthenticationPrincipalConfig.class).autowire();
this.mockMvc.perform(get("/").with(authentication(new TestingAuthenticationToken("user1", "password"))))
.andExpect(content().string("user1"));
.andExpect(content().string("user1"));
}
@EnableWebSecurity
@EnableWebMvc
static class AuthenticationPrincipalConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
}
@@ -125,7 +132,9 @@ public class EnableWebSecurityTests {
String principal(@AuthenticationPrincipal String principal) {
return principal;
}
}
}
@Test
@@ -133,12 +142,13 @@ public class EnableWebSecurityTests {
this.spring.register(SecurityFilterChainAuthenticationPrincipalConfig.class).autowire();
this.mockMvc.perform(get("/").with(authentication(new TestingAuthenticationToken("user1", "password"))))
.andExpect(content().string("user1"));
.andExpect(content().string("user1"));
}
@EnableWebSecurity
@EnableWebMvc
static class SecurityFilterChainAuthenticationPrincipalConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.build();
@@ -151,7 +161,9 @@ public class EnableWebSecurityTests {
String principal(@AuthenticationPrincipal String principal) {
return principal;
}
}
}
@Test
@@ -166,6 +178,7 @@ public class EnableWebSecurityTests {
@EnableWebSecurity
static class BeanProxyEnabledByDefaultConfig extends WebSecurityConfigurerAdapter {
@Bean
public Child child() {
return new Child();
@@ -175,6 +188,7 @@ public class EnableWebSecurityTests {
public Parent parent() {
return new Parent(child());
}
}
@Test
@@ -190,6 +204,7 @@ public class EnableWebSecurityTests {
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
static class BeanProxyDisabledConfig extends WebSecurityConfigurerAdapter {
@Bean
public Child child() {
return new Child();
@@ -199,9 +214,11 @@ public class EnableWebSecurityTests {
public Parent parent() {
return new Parent(child());
}
}
static class Parent {
private Child child;
Parent(Child child) {
@@ -211,10 +228,14 @@ public class EnableWebSecurityTests {
public Child getChild() {
return child;
}
}
static class Child {
Child() {
}
}
}

View File

@@ -62,6 +62,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Eleftheria Stein
*/
public class HttpSecurityConfigurationTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -70,11 +71,9 @@ public class HttpSecurityConfigurationTests {
@Test
public void postWhenDefaultFilterChainBeanThenRespondsWithForbidden() throws Exception {
this.spring.register(DefaultWithFilterChainConfig.class)
.autowire();
this.spring.register(DefaultWithFilterChainConfig.class).autowire();
this.mockMvc.perform(post("/"))
.andExpect(status().isForbidden());
this.mockMvc.perform(post("/")).andExpect(status().isForbidden());
}
@Test
@@ -83,13 +82,14 @@ public class HttpSecurityConfigurationTests {
MvcResult mvcResult = this.mockMvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.X_CONTENT_TYPE_OPTIONS, "nosniff"))
.andExpect(header().string(HttpHeaders.X_FRAME_OPTIONS, XFrameOptionsHeaderWriter.XFrameOptionsMode.DENY.name()))
.andExpect(header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains"))
.andExpect(header().string(HttpHeaders.X_FRAME_OPTIONS,
XFrameOptionsHeaderWriter.XFrameOptionsMode.DENY.name()))
.andExpect(
header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains"))
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string(HttpHeaders.EXPIRES, "0"))
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache"))
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block"))
.andReturn();
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactlyInAnyOrder(
HttpHeaders.X_CONTENT_TYPE_OPTIONS, HttpHeaders.X_FRAME_OPTIONS, HttpHeaders.STRICT_TRANSPORT_SECURITY,
HttpHeaders.CACHE_CONTROL, HttpHeaders.EXPIRES, HttpHeaders.PRAGMA, HttpHeaders.X_XSS_PROTECTION);
@@ -99,57 +99,54 @@ public class HttpSecurityConfigurationTests {
public void logoutWhenDefaultFilterChainBeanThenCreatesDefaultLogoutEndpoint() throws Exception {
this.spring.register(DefaultWithFilterChainConfig.class).autowire();
this.mockMvc.perform(post("/logout").with(csrf()))
.andExpect(redirectedUrl("/login?logout"));
this.mockMvc.perform(post("/logout").with(csrf())).andExpect(redirectedUrl("/login?logout"));
}
@Test
public void loadConfigWhenDefaultConfigThenWebAsyncManagerIntegrationFilterAdded() throws Exception {
this.spring.register(DefaultWithFilterChainConfig.class, NameController.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/name").with(user("Bob")))
.andExpect(request().asyncStarted())
MvcResult mvcResult = this.mockMvc.perform(get("/name").with(user("Bob"))).andExpect(request().asyncStarted())
.andReturn();
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().string("Bob"));
this.mockMvc.perform(asyncDispatch(mvcResult)).andExpect(status().isOk()).andExpect(content().string("Bob"));
}
@RestController
static class NameController {
@GetMapping("/name")
public Callable<String> name() {
return () -> SecurityContextHolder.getContext().getAuthentication().getName();
}
}
@EnableWebSecurity
static class DefaultWithFilterChainConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.build();
}
}
@Test
public void getWhenDefaultFilterChainBeanThenAnonymousPermitted() throws Exception {
this.spring.register(AuthorizeRequestsConfig.class, UserDetailsConfig.class, BaseController.class).autowire();
this.mockMvc.perform(get("/"))
.andExpect(status().isOk());
this.mockMvc.perform(get("/")).andExpect(status().isOk());
}
@EnableWebSecurity
static class AuthorizeRequestsConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeRequests(authorize -> authorize
.anyRequest().permitAll()
)
.build();
return http.authorizeRequests(authorize -> authorize.anyRequest().permitAll()).build();
}
}
@Test
@@ -159,13 +156,9 @@ public class HttpSecurityConfigurationTests {
MockHttpSession session = new MockHttpSession();
String sessionId = session.getId();
MvcResult result =
this.mockMvc.perform(post("/login")
.param("username", "user")
.param("password", "password")
.session(session)
.with(csrf()))
.andReturn();
MvcResult result = this.mockMvc.perform(
post("/login").param("username", "user").param("password", "password").session(session).with(csrf()))
.andReturn();
assertThat(result.getRequest().getSession(false).getId()).isNotEqualTo(sessionId);
}
@@ -174,15 +167,11 @@ public class HttpSecurityConfigurationTests {
public void authenticateWhenDefaultFilterChainBeanThenRedirectsToSavedRequest() throws Exception {
this.spring.register(SecurityEnabledConfig.class, UserDetailsConfig.class).autowire();
MockHttpSession session = (MockHttpSession)
this.mockMvc.perform(get("/messages"))
.andReturn().getRequest().getSession();
MockHttpSession session = (MockHttpSession) this.mockMvc.perform(get("/messages")).andReturn().getRequest()
.getSession();
this.mockMvc.perform(post("/login")
.param("username", "user")
.param("password", "password")
.session(session)
.with(csrf()))
this.mockMvc.perform(
post("/login").param("username", "user").param("password", "password").session(session).with(csrf()))
.andExpect(redirectedUrl("http://localhost/messages"));
}
@@ -190,8 +179,9 @@ public class HttpSecurityConfigurationTests {
public void authenticateWhenDefaultFilterChainBeanThenRolePrefixIsSet() throws Exception {
this.spring.register(SecurityEnabledConfig.class, UserDetailsConfig.class, UserController.class).autowire();
this.mockMvc.perform(get("/user")
.with(authentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"))))
this.mockMvc
.perform(get("/user")
.with(authentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"))))
.andExpect(status().isOk());
}
@@ -199,50 +189,51 @@ public class HttpSecurityConfigurationTests {
public void loginWhenUsingDefaultsThenDefaultLoginPageGenerated() throws Exception {
this.spring.register(SecurityEnabledConfig.class).autowire();
this.mockMvc.perform(get("/login"))
.andExpect(status().isOk());
this.mockMvc.perform(get("/login")).andExpect(status().isOk());
}
@EnableWebSecurity
static class SecurityEnabledConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(withDefaults())
return http.authorizeRequests(authorize -> authorize.anyRequest().authenticated()).formLogin(withDefaults())
.build();
}
}
@Configuration
static class UserDetailsConfig {
@Bean
public UserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
UserDetails user = User.withDefaultPasswordEncoder().username("user").password("password").roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
@RestController
static class BaseController {
@GetMapping("/")
public void index() {
}
}
@RestController
static class UserController {
@GetMapping("/user")
public void user(HttpServletRequest request) {
if (!request.isUserInRole("USER")) {
throw new AccessDeniedException("This resource is only available to users");
}
}
}
}

View File

@@ -64,6 +64,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Joe Grandja
*/
public class OAuth2ClientConfigurationTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -78,14 +79,14 @@ public class OAuth2ClientConfigurationTests {
ClientRegistrationRepository clientRegistrationRepository = mock(ClientRegistrationRepository.class);
ClientRegistration clientRegistration = clientRegistration().registrationId(clientRegistrationId).build();
when(clientRegistrationRepository.findByRegistrationId(eq(clientRegistrationId))).thenReturn(clientRegistration);
when(clientRegistrationRepository.findByRegistrationId(eq(clientRegistrationId)))
.thenReturn(clientRegistration);
OAuth2AuthorizedClientRepository authorizedClientRepository = mock(OAuth2AuthorizedClientRepository.class);
OAuth2AuthorizedClient authorizedClient = mock(OAuth2AuthorizedClient.class);
when(authorizedClient.getClientRegistration()).thenReturn(clientRegistration);
when(authorizedClientRepository.loadAuthorizedClient(
eq(clientRegistrationId), eq(authentication), any(HttpServletRequest.class)))
.thenReturn(authorizedClient);
when(authorizedClientRepository.loadAuthorizedClient(eq(clientRegistrationId), eq(authentication),
any(HttpServletRequest.class))).thenReturn(authorizedClient);
OAuth2AccessToken accessToken = mock(OAuth2AccessToken.class);
when(authorizedClient.getAccessToken()).thenReturn(accessToken);
@@ -97,14 +98,14 @@ public class OAuth2ClientConfigurationTests {
OAuth2AuthorizedClientArgumentResolverConfig.ACCESS_TOKEN_RESPONSE_CLIENT = accessTokenResponseClient;
this.spring.register(OAuth2AuthorizedClientArgumentResolverConfig.class).autowire();
this.mockMvc.perform(get("/authorized-client").with(authentication(authentication)))
.andExpect(status().isOk())
this.mockMvc.perform(get("/authorized-client").with(authentication(authentication))).andExpect(status().isOk())
.andExpect(content().string("resolved"));
verifyZeroInteractions(accessTokenResponseClient);
}
@Test
public void requestWhenAuthorizedClientNotFoundAndClientCredentialsThenTokenResponseClientIsUsed() throws Exception {
public void requestWhenAuthorizedClientNotFoundAndClientCredentialsThenTokenResponseClientIsUsed()
throws Exception {
String clientRegistrationId = "client1";
String principalName = "user1";
TestingAuthenticationToken authentication = new TestingAuthenticationToken(principalName, "password");
@@ -117,9 +118,7 @@ public class OAuth2ClientConfigurationTests {
when(clientRegistrationRepository.findByRegistrationId(clientRegistrationId)).thenReturn(clientRegistration);
OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("access-token-1234")
.tokenType(OAuth2AccessToken.TokenType.BEARER)
.expiresIn(300)
.build();
.tokenType(OAuth2AccessToken.TokenType.BEARER).expiresIn(300).build();
when(accessTokenResponseClient.getTokenResponse(any(OAuth2ClientCredentialsGrantRequest.class)))
.thenReturn(accessTokenResponse);
@@ -128,8 +127,7 @@ public class OAuth2ClientConfigurationTests {
OAuth2AuthorizedClientArgumentResolverConfig.ACCESS_TOKEN_RESPONSE_CLIENT = accessTokenResponseClient;
this.spring.register(OAuth2AuthorizedClientArgumentResolverConfig.class).autowire();
this.mockMvc.perform(get("/authorized-client").with(authentication(authentication)))
.andExpect(status().isOk())
this.mockMvc.perform(get("/authorized-client").with(authentication(authentication))).andExpect(status().isOk())
.andExpect(content().string("resolved"));
verify(accessTokenResponseClient, times(1)).getTokenResponse(any(OAuth2ClientCredentialsGrantRequest.class));
}
@@ -137,6 +135,7 @@ public class OAuth2ClientConfigurationTests {
@EnableWebMvc
@EnableWebSecurity
static class OAuth2AuthorizedClientArgumentResolverConfig extends WebSecurityConfigurerAdapter {
static ClientRegistrationRepository CLIENT_REGISTRATION_REPOSITORY;
static OAuth2AuthorizedClientRepository AUTHORIZED_CLIENT_REPOSITORY;
static OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> ACCESS_TOKEN_RESPONSE_CLIENT;
@@ -149,9 +148,11 @@ public class OAuth2ClientConfigurationTests {
public class Controller {
@GetMapping("/authorized-client")
public String authorizedClient(@RegisteredOAuth2AuthorizedClient("client1") OAuth2AuthorizedClient authorizedClient) {
public String authorizedClient(
@RegisteredOAuth2AuthorizedClient("client1") OAuth2AuthorizedClient authorizedClient) {
return authorizedClient != null ? "resolved" : "not-resolved";
}
}
@Bean
@@ -168,15 +169,18 @@ public class OAuth2ClientConfigurationTests {
public OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> accessTokenResponseClient() {
return ACCESS_TOKEN_RESPONSE_CLIENT;
}
}
// gh-5321
@Test
public void loadContextWhenOAuth2AuthorizedClientRepositoryRegisteredTwiceThenThrowNoUniqueBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(OAuth2AuthorizedClientRepositoryRegisteredTwiceConfig.class).autowire())
.hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class)
.hasMessageContaining("Expected single matching bean of type '" + OAuth2AuthorizedClientRepository.class.getName() +
"' but found 2: authorizedClientRepository1,authorizedClientRepository2");
assertThatThrownBy(
() -> this.spring.register(OAuth2AuthorizedClientRepositoryRegisteredTwiceConfig.class).autowire())
.hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class)
.hasMessageContaining("Expected single matching bean of type '"
+ OAuth2AuthorizedClientRepository.class.getName()
+ "' but found 2: authorizedClientRepository1,authorizedClientRepository2");
}
@EnableWebMvc
@@ -213,13 +217,14 @@ public class OAuth2ClientConfigurationTests {
public OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> accessTokenResponseClient() {
return mock(OAuth2AccessTokenResponseClient.class);
}
}
@Test
public void loadContextWhenClientRegistrationRepositoryNotRegisteredThenThrowNoSuchBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(ClientRegistrationRepositoryNotRegisteredConfig.class).autowire())
.hasRootCauseInstanceOf(NoSuchBeanDefinitionException.class)
.hasMessageContaining("No qualifying bean of type '" + ClientRegistrationRepository.class.getName() + "' available");
.hasRootCauseInstanceOf(NoSuchBeanDefinitionException.class).hasMessageContaining(
"No qualifying bean of type '" + ClientRegistrationRepository.class.getName() + "' available");
}
@EnableWebMvc
@@ -236,13 +241,14 @@ public class OAuth2ClientConfigurationTests {
.oauth2Login();
// @formatter:on
}
}
@Test
public void loadContextWhenClientRegistrationRepositoryRegisteredTwiceThenThrowNoUniqueBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(ClientRegistrationRepositoryRegisteredTwiceConfig.class).autowire())
.hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class)
.hasMessageContaining("expected single matching bean but found 2: clientRegistrationRepository1,clientRegistrationRepository2");
assertThatThrownBy(() -> this.spring.register(ClientRegistrationRepositoryRegisteredTwiceConfig.class)
.autowire()).hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class).hasMessageContaining(
"expected single matching bean but found 2: clientRegistrationRepository1,clientRegistrationRepository2");
}
@EnableWebMvc
@@ -279,13 +285,14 @@ public class OAuth2ClientConfigurationTests {
public OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> accessTokenResponseClient() {
return mock(OAuth2AccessTokenResponseClient.class);
}
}
@Test
public void loadContextWhenAccessTokenResponseClientRegisteredTwiceThenThrowNoUniqueBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(AccessTokenResponseClientRegisteredTwiceConfig.class).autowire())
.hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class)
.hasMessageContaining("expected single matching bean but found 2: accessTokenResponseClient1,accessTokenResponseClient2");
.hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class).hasMessageContaining(
"expected single matching bean but found 2: accessTokenResponseClient1,accessTokenResponseClient2");
}
@EnableWebMvc
@@ -322,6 +329,7 @@ public class OAuth2ClientConfigurationTests {
public OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> accessTokenResponseClient2() {
return mock(OAuth2AccessTokenResponseClient.class);
}
}
// gh-8700
@@ -336,8 +344,8 @@ public class OAuth2ClientConfigurationTests {
OAuth2AuthorizedClientManager authorizedClientManager = mock(OAuth2AuthorizedClientManager.class);
ClientRegistration clientRegistration = clientRegistration().registrationId(clientRegistrationId).build();
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
clientRegistration, principalName, TestOAuth2AccessTokens.noScopes());
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(clientRegistration, principalName,
TestOAuth2AccessTokens.noScopes());
when(authorizedClientManager.authorize(any())).thenReturn(authorizedClient);
@@ -346,8 +354,7 @@ public class OAuth2ClientConfigurationTests {
OAuth2AuthorizedClientManagerRegisteredConfig.AUTHORIZED_CLIENT_MANAGER = authorizedClientManager;
this.spring.register(OAuth2AuthorizedClientManagerRegisteredConfig.class).autowire();
this.mockMvc.perform(get("/authorized-client").with(authentication(authentication)))
.andExpect(status().isOk())
this.mockMvc.perform(get("/authorized-client").with(authentication(authentication))).andExpect(status().isOk())
.andExpect(content().string("resolved"));
verify(authorizedClientManager).authorize(any());
@@ -358,6 +365,7 @@ public class OAuth2ClientConfigurationTests {
@EnableWebMvc
@EnableWebSecurity
static class OAuth2AuthorizedClientManagerRegisteredConfig extends WebSecurityConfigurerAdapter {
static ClientRegistrationRepository CLIENT_REGISTRATION_REPOSITORY;
static OAuth2AuthorizedClientRepository AUTHORIZED_CLIENT_REPOSITORY;
static OAuth2AuthorizedClientManager AUTHORIZED_CLIENT_MANAGER;
@@ -370,9 +378,11 @@ public class OAuth2ClientConfigurationTests {
public class Controller {
@GetMapping("/authorized-client")
public String authorizedClient(@RegisteredOAuth2AuthorizedClient("client1") OAuth2AuthorizedClient authorizedClient) {
public String authorizedClient(
@RegisteredOAuth2AuthorizedClient("client1") OAuth2AuthorizedClient authorizedClient) {
return authorizedClient != null ? "resolved" : "not-resolved";
}
}
@Bean
@@ -389,5 +399,7 @@ public class OAuth2ClientConfigurationTests {
public OAuth2AuthorizedClientManager authorizedClientManager() {
return AUTHORIZED_CLIENT_MANAGER;
}
}
}

View File

@@ -34,6 +34,7 @@ import static org.mockito.Mockito.mock;
* @author Joe Grandja
*/
public class Sec2515Tests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -51,6 +52,7 @@ public class Sec2515Tests {
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@Test(expected = FatalBeanException.class)
@@ -62,10 +64,11 @@ public class Sec2515Tests {
static class CustomBeanNameStackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Bean(name="custom")
@Bean(name = "custom")
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
// SEC-2549
@@ -73,7 +76,8 @@ public class Sec2515Tests {
public void loadConfigWhenChildClassLoaderSetThenContextLoads() {
CanLoadWithChildConfig.AUTHENTICATION_MANAGER = mock(AuthenticationManager.class);
this.spring.register(CanLoadWithChildConfig.class);
AnnotationConfigWebApplicationContext context = (AnnotationConfigWebApplicationContext) this.spring.getContext();
AnnotationConfigWebApplicationContext context = (AnnotationConfigWebApplicationContext) this.spring
.getContext();
context.setClassLoader(new URLClassLoader(new URL[0], context.getClassLoader()));
this.spring.autowire();
@@ -82,12 +86,14 @@ public class Sec2515Tests {
@EnableWebSecurity
static class CanLoadWithChildConfig extends WebSecurityConfigurerAdapter {
static AuthenticationManager AUTHENTICATION_MANAGER;
@Bean
public AuthenticationManager authenticationManager() {
return AUTHENTICATION_MANAGER;
}
}
// SEC-2515
@@ -109,5 +115,7 @@ public class Sec2515Tests {
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication();
}
}
}

View File

@@ -44,11 +44,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for applications of {@link SecurityReactorContextConfiguration} in resource servers.
* Tests for applications of {@link SecurityReactorContextConfiguration} in resource
* servers.
*
* @author Josh Cummings
*/
public class SecurityReactorContextConfigurationResourceServerTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -61,9 +63,7 @@ public class SecurityReactorContextConfigurationResourceServerTests {
BearerTokenAuthentication authentication = bearer();
this.spring.register(BearerFilterConfig.class, WebServerConfig.class, Controller.class).autowire();
this.mockMvc.perform(get("/token")
.with(authentication(authentication)))
.andExpect(status().isOk())
this.mockMvc.perform(get("/token").with(authentication(authentication))).andExpect(status().isOk())
.andExpect(content().string("Bearer token"));
}
@@ -73,30 +73,28 @@ public class SecurityReactorContextConfigurationResourceServerTests {
BearerTokenAuthentication authentication = bearer();
this.spring.register(BearerFilterlessConfig.class, WebServerConfig.class, Controller.class).autowire();
this.mockMvc.perform(get("/token")
.with(authentication(authentication)))
.andExpect(status().isOk())
this.mockMvc.perform(get("/token").with(authentication(authentication))).andExpect(status().isOk())
.andExpect(content().string(""));
}
@EnableWebSecurity
static class BearerFilterConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
@Bean
WebClient rest() {
ServletBearerExchangeFilterFunction bearer =
new ServletBearerExchangeFilterFunction();
return WebClient.builder()
.filter(bearer).build();
ServletBearerExchangeFilterFunction bearer = new ServletBearerExchangeFilterFunction();
return WebClient.builder().filter(bearer).build();
}
}
@EnableWebSecurity
static class BearerFilterlessConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
@@ -105,35 +103,33 @@ public class SecurityReactorContextConfigurationResourceServerTests {
WebClient rest() {
return WebClient.create();
}
}
@RestController
static class Controller {
private final WebClient rest;
private final String uri;
@Autowired
Controller(MockWebServer server, WebClient rest) {
Controller(MockWebServer server, WebClient rest) {
this.uri = server.url("/").toString();
this.rest = rest;
}
@GetMapping("/token")
public String token() {
return this.rest.get()
.uri(this.uri)
.retrieve()
.bodyToMono(String.class)
.flatMap(result -> this.rest.get()
.uri(this.uri)
.retrieve()
.bodyToMono(String.class))
.block();
return this.rest.get().uri(this.uri).retrieve().bodyToMono(String.class)
.flatMap(result -> this.rest.get().uri(this.uri).retrieve().bodyToMono(String.class)).block();
}
}
@Configuration
static class WebServerConfig {
private final MockWebServer server = new MockWebServer();
@Bean
@@ -147,6 +143,7 @@ public class SecurityReactorContextConfigurationResourceServerTests {
void shutdown() throws Exception {
this.server.shutdown();
}
}
static class AuthorizationHeaderDispatcher extends Dispatcher {
@@ -161,5 +158,7 @@ public class SecurityReactorContextConfigurationResourceServerTests {
}
return response.setBody(header);
}
}
}

View File

@@ -59,11 +59,14 @@ import static org.springframework.security.config.annotation.web.configuration.S
* @since 5.2
*/
public class SecurityReactorContextConfigurationTests {
private MockHttpServletRequest servletRequest;
private MockHttpServletResponse servletResponse;
private Authentication authentication;
private SecurityReactorContextConfiguration.SecurityReactorContextSubscriberRegistrar subscriberRegistrar =
new SecurityReactorContextConfiguration.SecurityReactorContextSubscriberRegistrar();
private SecurityReactorContextConfiguration.SecurityReactorContextSubscriberRegistrar subscriberRegistrar = new SecurityReactorContextConfiguration.SecurityReactorContextSubscriberRegistrar();
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -90,14 +93,15 @@ public class SecurityReactorContextConfigurationTests {
return context;
}
};
CoreSubscriber<Object> resultSubscriber = this.subscriberRegistrar.createSubscriberIfNecessary(originalSubscriber);
CoreSubscriber<Object> resultSubscriber = this.subscriberRegistrar
.createSubscriberIfNecessary(originalSubscriber);
assertThat(resultSubscriber).isSameAs(originalSubscriber);
}
@Test
public void createSubscriberIfNecessaryWhenWebSecurityContextAvailableThenCreateWithParentContext() {
RequestContextHolder.setRequestAttributes(
new ServletRequestAttributes(this.servletRequest, this.servletResponse));
RequestContextHolder
.setRequestAttributes(new ServletRequestAttributes(this.servletRequest, this.servletResponse));
SecurityContextHolder.getContext().setAuthentication(this.authentication);
String testKey = "test_key";
@@ -116,16 +120,15 @@ public class SecurityReactorContextConfigurationTests {
assertThat(resultContext.getOrEmpty(testKey)).hasValue(testValue);
Map<Object, Object> securityContextAttributes = resultContext.getOrDefault(SECURITY_CONTEXT_ATTRIBUTES, null);
assertThat(securityContextAttributes).hasSize(3);
assertThat(securityContextAttributes).contains(
entry(HttpServletRequest.class, this.servletRequest),
assertThat(securityContextAttributes).contains(entry(HttpServletRequest.class, this.servletRequest),
entry(HttpServletResponse.class, this.servletResponse),
entry(Authentication.class, this.authentication));
}
@Test
public void createSubscriberIfNecessaryWhenParentContextContainsSecurityContextAttributesThenUseParentContext() {
RequestContextHolder.setRequestAttributes(
new ServletRequestAttributes(this.servletRequest, this.servletResponse));
RequestContextHolder
.setRequestAttributes(new ServletRequestAttributes(this.servletRequest, this.servletResponse));
SecurityContextHolder.getContext().setAuthentication(this.authentication);
Context parentContext = Context.of(SECURITY_CONTEXT_ATTRIBUTES, new HashMap<>());
@@ -143,76 +146,75 @@ public class SecurityReactorContextConfigurationTests {
@Test
public void createSubscriberIfNecessaryWhenNotServletRequestAttributesThenStillCreate() {
RequestContextHolder.setRequestAttributes(
new RequestAttributes() {
@Override
public Object getAttribute(String name, int scope) {
return null;
}
RequestContextHolder.setRequestAttributes(new RequestAttributes() {
@Override
public Object getAttribute(String name, int scope) {
return null;
}
@Override
public void setAttribute(String name, Object value, int scope) {
}
@Override
public void setAttribute(String name, Object value, int scope) {
}
@Override
public void removeAttribute(String name, int scope) {
}
@Override
public void removeAttribute(String name, int scope) {
}
@Override
public String[] getAttributeNames(int scope) {
return new String[0];
}
@Override
public String[] getAttributeNames(int scope) {
return new String[0];
}
@Override
public void registerDestructionCallback(String name, Runnable callback, int scope) {
}
@Override
public void registerDestructionCallback(String name, Runnable callback, int scope) {
}
@Override
public Object resolveReference(String key) {
return null;
}
@Override
public Object resolveReference(String key) {
return null;
}
@Override
public String getSessionId() {
return null;
}
@Override
public String getSessionId() {
return null;
}
@Override
public Object getSessionMutex() {
return null;
}
});
@Override
public Object getSessionMutex() {
return null;
}
});
CoreSubscriber<Object> subscriber = this.subscriberRegistrar.createSubscriberIfNecessary(Operators.emptySubscriber());
CoreSubscriber<Object> subscriber = this.subscriberRegistrar
.createSubscriberIfNecessary(Operators.emptySubscriber());
assertThat(subscriber).isInstanceOf(SecurityReactorContextConfiguration.SecurityReactorContextSubscriber.class);
}
@Test
public void createPublisherWhenLastOperatorAddedThenSecurityContextAttributesAvailable() {
// Trigger the importing of SecurityReactorContextConfiguration via OAuth2ImportSelector
// Trigger the importing of SecurityReactorContextConfiguration via
// OAuth2ImportSelector
this.spring.register(SecurityConfig.class).autowire();
// Setup for SecurityReactorContextSubscriberRegistrar
RequestContextHolder.setRequestAttributes(
new ServletRequestAttributes(this.servletRequest, this.servletResponse));
RequestContextHolder
.setRequestAttributes(new ServletRequestAttributes(this.servletRequest, this.servletResponse));
SecurityContextHolder.getContext().setAuthentication(this.authentication);
ClientResponse clientResponseOk = ClientResponse.create(HttpStatus.OK).build();
ExchangeFilterFunction filter = (req, next) ->
Mono.subscriberContext()
.filter(ctx -> ctx.hasKey(SECURITY_CONTEXT_ATTRIBUTES))
.map(ctx -> ctx.get(SECURITY_CONTEXT_ATTRIBUTES))
.cast(Map.class)
.map(attributes -> {
if (attributes.containsKey(HttpServletRequest.class) &&
attributes.containsKey(HttpServletResponse.class) &&
attributes.containsKey(Authentication.class)) {
return clientResponseOk;
} else {
return ClientResponse.create(HttpStatus.NOT_FOUND).build();
}
});
ExchangeFilterFunction filter = (req, next) -> Mono.subscriberContext()
.filter(ctx -> ctx.hasKey(SECURITY_CONTEXT_ATTRIBUTES)).map(ctx -> ctx.get(SECURITY_CONTEXT_ATTRIBUTES))
.cast(Map.class).map(attributes -> {
if (attributes.containsKey(HttpServletRequest.class)
&& attributes.containsKey(HttpServletResponse.class)
&& attributes.containsKey(Authentication.class)) {
return clientResponseOk;
}
else {
return ClientResponse.create(HttpStatus.NOT_FOUND).build();
}
});
ClientRequest clientRequest = ClientRequest.create(GET, URI.create("https://example.com")).build();
MockExchangeFunction exchange = new MockExchangeFunction();
@@ -225,11 +227,8 @@ public class SecurityReactorContextConfigurationTests {
Mono<ClientResponse> clientResponseMono = filter.filter(clientRequest, exchange)
.flatMap(response -> filter.filter(clientRequest, exchange));
StepVerifier.create(clientResponseMono)
.expectAccessibleContext()
.contains(SECURITY_CONTEXT_ATTRIBUTES, expectedContextAttributes)
.then()
.expectNext(clientResponseOk)
StepVerifier.create(clientResponseMono).expectAccessibleContext()
.contains(SECURITY_CONTEXT_ATTRIBUTES, expectedContextAttributes).then().expectNext(clientResponseOk)
.verifyComplete();
}
@@ -239,5 +238,7 @@ public class SecurityReactorContextConfigurationTests {
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}
}

View File

@@ -75,8 +75,7 @@ public class WebMvcSecurityConfigurationTests {
@Test
public void authenticationPrincipalResolved() throws Exception {
mockMvc.perform(get("/authentication-principal"))
.andExpect(assertResult(authentication.getPrincipal()))
mockMvc.perform(get("/authentication-principal")).andExpect(assertResult(authentication.getPrincipal()))
.andExpect(view().name("authentication-principal-view"));
}
@@ -90,8 +89,7 @@ public class WebMvcSecurityConfigurationTests {
@Test
public void csrfToken() throws Exception {
CsrfToken csrfToken = new DefaultCsrfToken("headerName", "paramName", "token");
MockHttpServletRequestBuilder request = get("/csrf").requestAttr(
CsrfToken.class.getName(), csrfToken);
MockHttpServletRequestBuilder request = get("/csrf").requestAttr(CsrfToken.class.getName(), csrfToken);
mockMvc.perform(request).andExpect(assertResult(csrfToken));
}
@@ -104,32 +102,33 @@ public class WebMvcSecurityConfigurationTests {
static class TestController {
@RequestMapping("/authentication-principal")
public ModelAndView authenticationPrincipal(
@AuthenticationPrincipal String principal) {
public ModelAndView authenticationPrincipal(@AuthenticationPrincipal String principal) {
return new ModelAndView("authentication-principal-view", "result", principal);
}
@RequestMapping("/deprecated-authentication-principal")
public ModelAndView deprecatedAuthenticationPrincipal(
@org.springframework.security.web.bind.annotation.AuthenticationPrincipal String principal) {
return new ModelAndView("deprecated-authentication-principal-view", "result",
principal);
return new ModelAndView("deprecated-authentication-principal-view", "result", principal);
}
@RequestMapping("/csrf")
public ModelAndView csrf(CsrfToken token) {
return new ModelAndView("view", "result", token);
}
}
@Configuration
@EnableWebMvc
@EnableWebSecurity
static class Config {
@Bean
public TestController testController() {
return new TestController();
}
}
}

View File

@@ -74,6 +74,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Evgeniy Cheban
*/
public class WebSecurityConfigurationTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -118,11 +119,10 @@ public class WebSecurityConfigurationTests {
@Configuration
@Order(1)
static class WebConfigurer1 extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers("/ignore1", "/ignore2");
web.ignoring().antMatchers("/ignore1", "/ignore2");
}
@Override
@@ -134,11 +134,13 @@ public class WebSecurityConfigurationTests {
.anyRequest().hasRole("1");
// @formatter:on
}
}
@Configuration
@Order(2)
static class WebConfigurer2 extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -148,11 +150,13 @@ public class WebSecurityConfigurationTests {
.anyRequest().hasRole("2");
// @formatter:on
}
}
@Configuration
@Order(3)
static class WebConfigurer3 extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -162,6 +166,7 @@ public class WebSecurityConfigurationTests {
.anyRequest().hasRole("3");
// @formatter:on
}
}
@Configuration
@@ -175,7 +180,9 @@ public class WebSecurityConfigurationTests {
.anyRequest().hasRole("4");
// @formatter:on
}
}
}
@Test
@@ -208,44 +215,29 @@ public class WebSecurityConfigurationTests {
@Order(1)
@Bean
SecurityFilterChain filterChain1(HttpSecurity http) throws Exception {
return http
.antMatcher("/role1/**")
.authorizeRequests(authorize -> authorize
.anyRequest().hasRole("1")
)
return http.antMatcher("/role1/**").authorizeRequests(authorize -> authorize.anyRequest().hasRole("1"))
.build();
}
@Order(2)
@Bean
SecurityFilterChain filterChain2(HttpSecurity http) throws Exception {
return http
.antMatcher("/role2/**")
.authorizeRequests(authorize -> authorize
.anyRequest().hasRole("2")
)
return http.antMatcher("/role2/**").authorizeRequests(authorize -> authorize.anyRequest().hasRole("2"))
.build();
}
@Order(3)
@Bean
SecurityFilterChain filterChain3(HttpSecurity http) throws Exception {
return http
.antMatcher("/role3/**")
.authorizeRequests(authorize -> authorize
.anyRequest().hasRole("3")
)
return http.antMatcher("/role3/**").authorizeRequests(authorize -> authorize.anyRequest().hasRole("3"))
.build();
}
@Bean
SecurityFilterChain filterChain4(HttpSecurity http) throws Exception {
return http
.authorizeRequests(authorize -> authorize
.anyRequest().hasRole("4")
)
.build();
return http.authorizeRequests(authorize -> authorize.anyRequest().hasRole("4")).build();
}
}
@Test
@@ -253,9 +245,9 @@ public class WebSecurityConfigurationTests {
Throwable thrown = catchThrowable(() -> this.spring.register(DuplicateOrderConfig.class).autowire());
assertThat(thrown).isInstanceOf(BeanCreationException.class)
.hasMessageContaining("@Order on WebSecurityConfigurers must be unique")
.hasMessageContaining(DuplicateOrderConfig.WebConfigurer1.class.getName())
.hasMessageContaining(DuplicateOrderConfig.WebConfigurer2.class.getName());
.hasMessageContaining("@Order on WebSecurityConfigurers must be unique")
.hasMessageContaining(DuplicateOrderConfig.WebConfigurer1.class.getName())
.hasMessageContaining(DuplicateOrderConfig.WebConfigurer2.class.getName());
}
@EnableWebSecurity
@@ -264,6 +256,7 @@ public class WebSecurityConfigurationTests {
@Configuration
static class WebConfigurer1 extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -273,10 +266,12 @@ public class WebSecurityConfigurationTests {
.anyRequest().hasRole("1");
// @formatter:on
}
}
@Configuration
static class WebConfigurer2 extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -286,7 +281,9 @@ public class WebSecurityConfigurationTests {
.anyRequest().hasRole("2");
// @formatter:on
}
}
}
@Test
@@ -296,32 +293,36 @@ public class WebSecurityConfigurationTests {
this.spring.register(PrivilegeEvaluatorConfigurerAdapterConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isSameAs(PrivilegeEvaluatorConfigurerAdapterConfig.PRIVILEGE_EVALUATOR);
.isSameAs(PrivilegeEvaluatorConfigurerAdapterConfig.PRIVILEGE_EVALUATOR);
}
@EnableWebSecurity
static class PrivilegeEvaluatorConfigurerAdapterConfig extends WebSecurityConfigurerAdapter {
static WebInvocationPrivilegeEvaluator PRIVILEGE_EVALUATOR;
@Override
public void configure(WebSecurity web) {
web.privilegeEvaluator(PRIVILEGE_EVALUATOR);
}
}
@Test
public void loadConfigWhenSecurityExpressionHandlerSetThenIsRegistered() {
WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER = mock(SecurityExpressionHandler.class);
when(WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER.getExpressionParser()).thenReturn(mock(ExpressionParser.class));
when(WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER.getExpressionParser())
.thenReturn(mock(ExpressionParser.class));
this.spring.register(WebSecurityExpressionHandlerConfig.class).autowire();
assertThat(this.spring.getContext().getBean(SecurityExpressionHandler.class))
.isSameAs(WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER);
.isSameAs(WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER);
}
@EnableWebSecurity
static class WebSecurityExpressionHandlerConfig extends WebSecurityConfigurerAdapter {
static SecurityExpressionHandler EXPRESSION_HANDLER;
@Override
@@ -338,13 +339,13 @@ public class WebSecurityConfigurationTests {
.expressionHandler(EXPRESSION_HANDLER);
// @formatter:on
}
}
@Test
public void loadConfigWhenSecurityExpressionHandlerIsNullThenException() {
Throwable thrown = catchThrowable(() ->
this.spring.register(NullWebSecurityExpressionHandlerConfig.class).autowire()
);
Throwable thrown = catchThrowable(
() -> this.spring.register(NullWebSecurityExpressionHandlerConfig.class).autowire());
assertThat(thrown).isInstanceOf(BeanCreationException.class);
assertThat(thrown).hasRootCauseExactlyInstanceOf(IllegalArgumentException.class);
@@ -357,6 +358,7 @@ public class WebSecurityConfigurationTests {
public void configure(WebSecurity web) {
web.expressionHandler(null);
}
}
@Test
@@ -364,11 +366,12 @@ public class WebSecurityConfigurationTests {
this.spring.register(WebSecurityExpressionHandlerDefaultsConfig.class).autowire();
assertThat(this.spring.getContext().getBean(SecurityExpressionHandler.class))
.isInstanceOf(DefaultWebSecurityExpressionHandler.class);
.isInstanceOf(DefaultWebSecurityExpressionHandler.class);
}
@EnableWebSecurity
static class WebSecurityExpressionHandlerDefaultsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -377,6 +380,7 @@ public class WebSecurityConfigurationTests {
.anyRequest().authenticated();
// @formatter:on
}
}
@Test
@@ -386,50 +390,53 @@ public class WebSecurityConfigurationTests {
FilterInvocation invocation = new FilterInvocation(new MockHttpServletRequest("GET", ""),
new MockHttpServletResponse(), new MockFilterChain());
AbstractSecurityExpressionHandler handler = this.spring.getContext().getBean(AbstractSecurityExpressionHandler.class);
AbstractSecurityExpressionHandler handler = this.spring.getContext()
.getBean(AbstractSecurityExpressionHandler.class);
EvaluationContext evaluationContext = handler.createEvaluationContext(authentication, invocation);
Expression expression = handler.getExpressionParser()
.parseExpression("hasRole('ROLE_USER')");
Expression expression = handler.getExpressionParser().parseExpression("hasRole('ROLE_USER')");
boolean granted = expression.getValue(evaluationContext, Boolean.class);
assertThat(granted).isTrue();
}
@EnableWebSecurity
static class WebSecurityExpressionHandlerRoleHierarchyBeanConfig extends WebSecurityConfigurerAdapter {
@Bean
RoleHierarchy roleHierarchy() {
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
return roleHierarchy;
}
}
@Test
public void securityExpressionHandlerWhenPermissionEvaluatorBeanThenPermissionEvaluatorUsed() {
this.spring.register(WebSecurityExpressionHandlerPermissionEvaluatorBeanConfig.class).autowire();
TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "notused");
FilterInvocation invocation = new FilterInvocation(new MockHttpServletRequest("GET", ""), new MockHttpServletResponse(), new MockFilterChain());
FilterInvocation invocation = new FilterInvocation(new MockHttpServletRequest("GET", ""),
new MockHttpServletResponse(), new MockFilterChain());
AbstractSecurityExpressionHandler handler = this.spring.getContext().getBean(AbstractSecurityExpressionHandler.class);
AbstractSecurityExpressionHandler handler = this.spring.getContext()
.getBean(AbstractSecurityExpressionHandler.class);
EvaluationContext evaluationContext = handler.createEvaluationContext(authentication, invocation);
Expression expression = handler.getExpressionParser()
.parseExpression("hasPermission(#study,'DELETE')");
Expression expression = handler.getExpressionParser().parseExpression("hasPermission(#study,'DELETE')");
boolean granted = expression.getValue(evaluationContext, Boolean.class);
assertThat(granted).isTrue();
}
@EnableWebSecurity
static class WebSecurityExpressionHandlerPermissionEvaluatorBeanConfig extends WebSecurityConfigurerAdapter {
static final PermissionEvaluator PERMIT_ALL_PERMISSION_EVALUATOR = new PermissionEvaluator() {
@Override
public boolean hasPermission(Authentication authentication,
Object targetDomainObject, Object permission) {
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
return true;
}
@Override
public boolean hasPermission(Authentication authentication,
Serializable targetId, String targetType, Object permission) {
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
return true;
}
};
@@ -438,6 +445,7 @@ public class WebSecurityConfigurationTests {
public PermissionEvaluator permissionEvaluator() {
return PERMIT_ALL_PERMISSION_EVALUATOR;
}
}
@Test
@@ -445,11 +453,12 @@ public class WebSecurityConfigurationTests {
this.spring.register(WebInvocationPrivilegeEvaluatorDefaultsConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
}
@EnableWebSecurity
static class WebInvocationPrivilegeEvaluatorDefaultsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -458,6 +467,7 @@ public class WebSecurityConfigurationTests {
.anyRequest().authenticated();
// @formatter:on
}
}
@Test
@@ -465,19 +475,17 @@ public class WebSecurityConfigurationTests {
this.spring.register(AuthorizeRequestsFilterChainConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
}
@EnableWebSecurity
static class AuthorizeRequestsFilterChainConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
.build();
return http.authorizeRequests(authorize -> authorize.anyRequest().authenticated()).build();
}
}
// SEC-2303
@@ -491,6 +499,7 @@ public class WebSecurityConfigurationTests {
@EnableWebSecurity
static class DefaultExpressionHandlerSetsBeanResolverConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -502,10 +511,12 @@ public class WebSecurityConfigurationTests {
@RestController
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
@Bean
@@ -514,6 +525,7 @@ public class WebSecurityConfigurationTests {
}
static class MyBean {
public boolean deny() {
return false;
}
@@ -521,7 +533,9 @@ public class WebSecurityConfigurationTests {
public boolean grant() {
return true;
}
}
}
@Rule
@@ -545,14 +559,17 @@ public class WebSecurityConfigurationTests {
@EnableWebSecurity
static class ParentConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication();
}
}
@EnableWebSecurity
static class ChildConfig extends WebSecurityConfigurerAdapter {
}
// SEC-2773
@@ -564,7 +581,8 @@ public class WebSecurityConfigurationTests {
@Test
public void loadConfigWhenBeanProxyingEnabledAndSubclassThenFilterChainsCreated() {
this.spring.register(GlobalAuthenticationWebSecurityConfigurerAdaptersConfig.class, SubclassConfig.class).autowire();
this.spring.register(GlobalAuthenticationWebSecurityConfigurerAdaptersConfig.class, SubclassConfig.class)
.autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
@@ -574,19 +592,20 @@ public class WebSecurityConfigurationTests {
@Configuration
static class SubclassConfig extends WebSecurityConfiguration {
}
@Import(AuthenticationTestConfiguration.class)
@EnableGlobalAuthentication
static class GlobalAuthenticationWebSecurityConfigurerAdaptersConfig {
@Configuration
@Order(1)
static class WebConfigurer1 extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers("/ignore1", "/ignore2");
web.ignoring().antMatchers("/ignore1", "/ignore2");
}
@Override
@@ -598,6 +617,7 @@ public class WebSecurityConfigurationTests {
.anyRequest().anonymous();
// @formatter:on
}
}
@Configuration
@@ -611,7 +631,9 @@ public class WebSecurityConfigurationTests {
.anyRequest().authenticated();
// @formatter:on
}
}
}
@Test
@@ -627,28 +649,25 @@ public class WebSecurityConfigurationTests {
@EnableWebSecurity
@Import(AuthenticationTestConfiguration.class)
static class AdapterAndFilterChainConfig {
@Order(1)
@Configuration
static class WebConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/config/**")
.authorizeRequests(authorize -> authorize
.anyRequest().permitAll()
);
http.antMatcher("/config/**").authorizeRequests(authorize -> authorize.anyRequest().permitAll());
}
}
@Order(2)
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.antMatcher("/filter/**")
.authorizeRequests(authorize -> authorize
.anyRequest().authenticated()
)
return http.antMatcher("/filter/**").authorizeRequests(authorize -> authorize.anyRequest().authenticated())
.build();
}
}
}

View File

@@ -38,10 +38,10 @@ public class Sec2377Tests {
public void refreshContextWhenParentAndChildRegisteredThenNoException() {
this.parent.register(Sec2377AConfig.class).autowire();
ConfigurableApplicationContext context =
this.child.register(Sec2377BConfig.class).getContext();
ConfigurableApplicationContext context = this.child.register(Sec2377BConfig.class).getContext();
context.setParent(this.parent.getContext());
this.child.autowire();
}
}

View File

@@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
public class AbstractConfigAttributeRequestMatcherRegistryTests {
private ConcreteAbstractRequestMatcherMappingConfigurer registry;
@Before
@@ -37,7 +38,7 @@ public class AbstractConfigAttributeRequestMatcherRegistryTests {
}
@Test
public void testGetRequestMatcherIsTypeRegexMatcher(){
public void testGetRequestMatcherIsTypeRegexMatcher() {
List<RequestMatcher> requestMatchers = registry.regexMatchers(HttpMethod.GET, "/a.*");
for (RequestMatcher requestMatcher : requestMatchers) {
@@ -46,8 +47,8 @@ public class AbstractConfigAttributeRequestMatcherRegistryTests {
}
@Test
public void testRequestMatcherIsTypeRegexMatcher(){
List<RequestMatcher> requestMatchers = registry.regexMatchers( "/a.*");
public void testRequestMatcherIsTypeRegexMatcher() {
List<RequestMatcher> requestMatchers = registry.regexMatchers("/a.*");
for (RequestMatcher requestMatcher : requestMatchers) {
assertThat(requestMatcher).isInstanceOf(RegexRequestMatcher.class);
@@ -55,7 +56,7 @@ public class AbstractConfigAttributeRequestMatcherRegistryTests {
}
@Test
public void testGetRequestMatcherIsTypeAntPathRequestMatcher(){
public void testGetRequestMatcherIsTypeAntPathRequestMatcher() {
List<RequestMatcher> requestMatchers = registry.antMatchers(HttpMethod.GET, "/a.*");
for (RequestMatcher requestMatcher : requestMatchers) {
@@ -64,7 +65,7 @@ public class AbstractConfigAttributeRequestMatcherRegistryTests {
}
@Test
public void testRequestMatcherIsTypeAntPathRequestMatcher(){
public void testRequestMatcherIsTypeAntPathRequestMatcher() {
List<RequestMatcher> requestMatchers = registry.antMatchers("/a.*");
for (RequestMatcher requestMatcher : requestMatchers) {
@@ -72,7 +73,9 @@ public class AbstractConfigAttributeRequestMatcherRegistryTests {
}
}
static class ConcreteAbstractRequestMatcherMappingConfigurer extends AbstractConfigAttributeRequestMatcherRegistry<List<RequestMatcher>> {
static class ConcreteAbstractRequestMatcherMappingConfigurer
extends AbstractConfigAttributeRequestMatcherRegistry<List<RequestMatcher>> {
List<AccessDecisionVoter> decisionVoters() {
return null;
}
@@ -88,5 +91,7 @@ public class AbstractConfigAttributeRequestMatcherRegistryTests {
public List<RequestMatcher> mvcMatchers(HttpMethod method, String... mvcPatterns) {
return null;
}
}
}

View File

@@ -40,6 +40,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Josh Cummings
*/
public class AnonymousConfigurerTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -50,8 +51,7 @@ public class AnonymousConfigurerTests {
public void requestWhenAnonymousTwiceInvokedThenDoesNotOverride() throws Exception {
this.spring.register(InvokeTwiceDoesNotOverride.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/"))
.andExpect(content().string("principal"));
this.mockMvc.perform(get("/")).andExpect(content().string("principal"));
}
@EnableWebSecurity
@@ -69,14 +69,14 @@ public class AnonymousConfigurerTests {
.anonymous();
// @formatter:on
}
}
@Test
public void requestWhenAnonymousPrincipalInLambdaThenPrincipalUsed() throws Exception {
this.spring.register(AnonymousPrincipalInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/"))
.andExpect(content().string("principal"));
this.mockMvc.perform(get("/")).andExpect(content().string("principal"));
}
@EnableWebSecurity
@@ -93,18 +93,19 @@ public class AnonymousConfigurerTests {
);
// @formatter:on
}
}
@Test
public void requestWhenAnonymousDisabledInLambdaThenRespondsWithForbidden() throws Exception {
this.spring.register(AnonymousDisabledInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/"))
.andExpect(status().isForbidden());
this.mockMvc.perform(get("/")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class AnonymousDisabledInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -124,18 +125,19 @@ public class AnonymousConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void requestWhenAnonymousWithDefaultsInLambdaThenRespondsWithOk() throws Exception {
this.spring.register(AnonymousWithDefaultsInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/"))
.andExpect(status().isOk());
this.mockMvc.perform(get("/")).andExpect(status().isOk());
}
@EnableWebSecurity
static class AnonymousWithDefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -155,13 +157,17 @@ public class AnonymousConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@RestController
static class PrincipalController {
@GetMapping("/")
String principal(@AuthenticationPrincipal String principal) {
return principal;
}
}
}

View File

@@ -58,11 +58,15 @@ import static org.springframework.security.config.Customizer.withDefaults;
*
*/
public class AuthorizeRequestsTests {
AnnotationConfigWebApplicationContext context;
MockHttpServletRequest request;
MockHttpServletResponse response;
MockFilterChain chain;
MockServletContext servletContext;
@Autowired
@@ -98,6 +102,7 @@ public class AuthorizeRequestsTests {
@EnableWebSecurity
@Configuration
static class AntMatchersNoPatternsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -114,6 +119,7 @@ public class AuthorizeRequestsTests {
.inMemoryAuthentication();
// @formatter:on
}
}
@Test
@@ -129,6 +135,7 @@ public class AuthorizeRequestsTests {
@EnableWebSecurity
@Configuration
static class AntMatchersNoPatternsInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -147,6 +154,7 @@ public class AuthorizeRequestsTests {
.inMemoryAuthentication();
// @formatter:on
}
}
// SEC-2256
@@ -190,6 +198,7 @@ public class AuthorizeRequestsTests {
@EnableWebSecurity
@Configuration
static class AntPatchersPathVariables extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -207,6 +216,7 @@ public class AuthorizeRequestsTests {
.inMemoryAuthentication();
// @formatter:on
}
}
// gh-3786
@@ -231,6 +241,7 @@ public class AuthorizeRequestsTests {
@EnableWebSecurity
@Configuration
static class AntMatchersPathVariablesCamelCaseVariables extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -248,6 +259,7 @@ public class AuthorizeRequestsTests {
.inMemoryAuthentication();
// @formatter:on
}
}
// gh-3394
@@ -256,8 +268,10 @@ public class AuthorizeRequestsTests {
loadConfig(RoleHiearchyConfig.class);
SecurityContext securityContext = new SecurityContextImpl();
securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("test", "notused", AuthorityUtils.createAuthorityList("ROLE_USER")));
this.request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, securityContext);
securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("test", "notused",
AuthorityUtils.createAuthorityList("ROLE_USER")));
this.request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
securityContext);
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
@@ -267,6 +281,7 @@ public class AuthorizeRequestsTests {
@EnableWebSecurity
@Configuration
static class RoleHiearchyConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -290,6 +305,7 @@ public class AuthorizeRequestsTests {
result.setHierarchy("ROLE_USER > ROLE_ADMIN");
return result;
}
}
@Test
@@ -299,30 +315,28 @@ public class AuthorizeRequestsTests {
this.request.setRequestURI("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setRequestURI("/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -343,11 +357,14 @@ public class AuthorizeRequestsTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -357,30 +374,28 @@ public class AuthorizeRequestsTests {
this.request.setRequestURI("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setRequestURI("/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -403,11 +418,14 @@ public class AuthorizeRequestsTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -418,8 +436,7 @@ public class AuthorizeRequestsTests {
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
@@ -427,8 +444,7 @@ public class AuthorizeRequestsTests {
this.request.setRequestURI("/spring/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
@@ -436,8 +452,7 @@ public class AuthorizeRequestsTests {
this.request.setRequestURI("/spring/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
@@ -460,6 +475,7 @@ public class AuthorizeRequestsTests {
@Configuration
@EnableWebMvc
static class MvcMatcherServletPathConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -480,11 +496,14 @@ public class AuthorizeRequestsTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -495,8 +514,7 @@ public class AuthorizeRequestsTests {
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
@@ -504,8 +522,7 @@ public class AuthorizeRequestsTests {
this.request.setRequestURI("/spring/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
@@ -513,8 +530,7 @@ public class AuthorizeRequestsTests {
this.request.setRequestURI("/spring/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
@@ -537,6 +553,7 @@ public class AuthorizeRequestsTests {
@Configuration
@EnableWebMvc
static class MvcMatcherServletPathInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -559,11 +576,14 @@ public class AuthorizeRequestsTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -581,14 +601,14 @@ public class AuthorizeRequestsTests {
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherPathVariablesConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -609,11 +629,14 @@ public class AuthorizeRequestsTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -631,14 +654,14 @@ public class AuthorizeRequestsTests {
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherPathVariablesInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -661,17 +684,21 @@ public class AuthorizeRequestsTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherPathServletPathRequiredConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -692,19 +719,24 @@ public class AuthorizeRequestsTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Configuration
static class LegacyMvcMatchingConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(true);
}
}
public void loadConfig(Class<?>... configs) {
@@ -715,4 +747,5 @@ public class AuthorizeRequestsTests {
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@@ -56,8 +56,7 @@ public class ChannelSecurityConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(InsecureChannelProcessor.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(InsecureChannelProcessor.class));
}
@Test
@@ -65,8 +64,7 @@ public class ChannelSecurityConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(SecureChannelProcessor.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(SecureChannelProcessor.class));
}
@Test
@@ -74,8 +72,7 @@ public class ChannelSecurityConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(ChannelDecisionManagerImpl.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ChannelDecisionManagerImpl.class));
}
@Test
@@ -83,12 +80,12 @@ public class ChannelSecurityConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(ChannelProcessingFilter.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ChannelProcessingFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor;
@Override
@@ -104,21 +101,23 @@ public class ChannelSecurityConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@Test
public void requiresChannelWhenInvokesTwiceThenUsesOriginalRequiresSecure() throws Exception {
this.spring.register(DuplicateInvocationsDoesNotOverrideConfig.class).autowire();
mvc.perform(get("/"))
.andExpect(redirectedUrl("https://localhost/"));
mvc.perform(get("/")).andExpect(redirectedUrl("https://localhost/"));
}
@EnableWebSecurity
@@ -134,14 +133,14 @@ public class ChannelSecurityConfigurerTests {
.requiresChannel();
// @formatter:on
}
}
@Test
public void requestWhenRequiresChannelConfiguredInLambdaThenRedirectsToHttps() throws Exception {
this.spring.register(RequiresChannelInLambdaConfig.class).autowire();
mvc.perform(get("/"))
.andExpect(redirectedUrl("https://localhost/"));
mvc.perform(get("/")).andExpect(redirectedUrl("https://localhost/"));
}
@EnableWebSecurity
@@ -157,5 +156,7 @@ public class ChannelSecurityConfigurerTests {
);
// @formatter:on
}
}
}

View File

@@ -55,6 +55,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Eleftheria Stein
*/
public class CorsConfigurerTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -64,8 +65,8 @@ public class CorsConfigurerTests {
@Test
public void configureWhenNoMvcThenException() {
assertThatThrownBy(() -> this.spring.register(DefaultCorsConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext");
.isInstanceOf(BeanCreationException.class).hasMessageContaining(
"Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext");
}
@EnableWebSecurity
@@ -81,14 +82,14 @@ public class CorsConfigurerTests {
.cors();
// @formatter:on
}
}
@Test
public void getWhenCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -99,8 +100,7 @@ public class CorsConfigurerTests {
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.header(HttpHeaders.ORIGIN, "https://example.com")).andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -121,23 +121,23 @@ public class CorsConfigurerTests {
}
@RestController
@CrossOrigin(methods = {
RequestMethod.GET, RequestMethod.POST
})
@CrossOrigin(methods = { RequestMethod.GET, RequestMethod.POST })
static class CorsController {
@RequestMapping("/")
String hello() {
return "Hello";
}
}
}
@Test
public void getWhenDefaultsInLambdaAndCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsInLambdaConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -148,8 +148,7 @@ public class CorsConfigurerTests {
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.header(HttpHeaders.ORIGIN, "https://example.com")).andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -171,23 +170,23 @@ public class CorsConfigurerTests {
}
@RestController
@CrossOrigin(methods = {
RequestMethod.GET, RequestMethod.POST
})
@CrossOrigin(methods = { RequestMethod.GET, RequestMethod.POST })
static class CorsController {
@RequestMapping("/")
String hello() {
return "Hello";
}
}
}
@Test
public void getWhenCorsConfigurationSourceBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(ConfigSourceConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -198,8 +197,7 @@ public class CorsConfigurerTests {
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.header(HttpHeaders.ORIGIN, "https://example.com")).andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -223,12 +221,11 @@ public class CorsConfigurerTests {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList(
RequestMethod.GET.name(),
RequestMethod.POST.name()));
corsConfiguration.setAllowedMethods(Arrays.asList(RequestMethod.GET.name(), RequestMethod.POST.name()));
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
}
@Test
@@ -236,8 +233,7 @@ public class CorsConfigurerTests {
throws Exception {
this.spring.register(ConfigSourceInLambdaConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -249,8 +245,7 @@ public class CorsConfigurerTests {
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.header(HttpHeaders.ORIGIN, "https://example.com")).andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -275,20 +270,18 @@ public class CorsConfigurerTests {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList(
RequestMethod.GET.name(),
RequestMethod.POST.name()));
corsConfiguration.setAllowedMethods(Arrays.asList(RequestMethod.GET.name(), RequestMethod.POST.name()));
source.registerCorsConfiguration("/**", corsConfiguration);
return source;
}
}
@Test
public void getWhenCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -299,8 +292,7 @@ public class CorsConfigurerTests {
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.header(HttpHeaders.ORIGIN, "https://example.com")).andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -324,20 +316,18 @@ public class CorsConfigurerTests {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList(
RequestMethod.GET.name(),
RequestMethod.POST.name()));
corsConfiguration.setAllowedMethods(Arrays.asList(RequestMethod.GET.name(), RequestMethod.POST.name()));
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
@Test
public void getWhenConfigSourceInLambdaConfigAndCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterInLambdaConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ORIGIN, "https://example.com"))
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -348,8 +338,7 @@ public class CorsConfigurerTests {
this.mvc.perform(options("/")
.header(org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(status().isOk())
.header(HttpHeaders.ORIGIN, "https://example.com")).andExpect(status().isOk())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@@ -374,11 +363,11 @@ public class CorsConfigurerTests {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(Collections.singletonList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList(
RequestMethod.GET.name(),
RequestMethod.POST.name()));
corsConfiguration.setAllowedMethods(Arrays.asList(RequestMethod.GET.name(), RequestMethod.POST.name()));
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
}

View File

@@ -48,21 +48,18 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
public final SpringTestRule spring = new SpringTestRule();
@Test
public void requestWhenIgnoringRequestMatchersThenAugmentedByConfiguredRequestMatcher()
throws Exception {
public void requestWhenIgnoringRequestMatchersThenAugmentedByConfiguredRequestMatcher() throws Exception {
this.spring.register(IgnoringRequestMatchers.class, BasicController.class).autowire();
this.mvc.perform(get("/path"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/path")).andExpect(status().isForbidden());
this.mvc.perform(post("/path"))
.andExpect(status().isOk());
this.mvc.perform(post("/path")).andExpect(status().isOk());
}
@EnableWebSecurity
static class IgnoringRequestMatchers extends WebSecurityConfigurerAdapter {
RequestMatcher requestMatcher =
request -> HttpMethod.POST.name().equals(request.getMethod());
RequestMatcher requestMatcher = request -> HttpMethod.POST.name().equals(request.getMethod());
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -73,24 +70,22 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
.ignoringRequestMatchers(this.requestMatcher);
// @formatter:on
}
}
@Test
public void requestWhenIgnoringRequestMatchersInLambdaThenAugmentedByConfiguredRequestMatcher()
throws Exception {
public void requestWhenIgnoringRequestMatchersInLambdaThenAugmentedByConfiguredRequestMatcher() throws Exception {
this.spring.register(IgnoringRequestInLambdaMatchers.class, BasicController.class).autowire();
this.mvc.perform(get("/path"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/path")).andExpect(status().isForbidden());
this.mvc.perform(post("/path"))
.andExpect(status().isOk());
this.mvc.perform(post("/path")).andExpect(status().isOk());
}
@EnableWebSecurity
static class IgnoringRequestInLambdaMatchers extends WebSecurityConfigurerAdapter {
RequestMatcher requestMatcher =
request -> HttpMethod.POST.name().equals(request.getMethod());
RequestMatcher requestMatcher = request -> HttpMethod.POST.name().equals(request.getMethod());
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -103,28 +98,25 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
);
// @formatter:on
}
}
@Test
public void requestWhenIgnoringRequestMatcherThenUnionsWithConfiguredIgnoringAntMatchers()
throws Exception {
public void requestWhenIgnoringRequestMatcherThenUnionsWithConfiguredIgnoringAntMatchers() throws Exception {
this.spring.register(IgnoringPathsAndMatchers.class, BasicController.class).autowire();
this.mvc.perform(put("/csrf"))
.andExpect(status().isForbidden());
this.mvc.perform(put("/csrf")).andExpect(status().isForbidden());
this.mvc.perform(post("/csrf"))
.andExpect(status().isOk());
this.mvc.perform(post("/csrf")).andExpect(status().isOk());
this.mvc.perform(put("/no-csrf"))
.andExpect(status().isOk());
this.mvc.perform(put("/no-csrf")).andExpect(status().isOk());
}
@EnableWebSecurity
static class IgnoringPathsAndMatchers extends WebSecurityConfigurerAdapter {
RequestMatcher requestMatcher =
request -> HttpMethod.POST.name().equals(request.getMethod());
RequestMatcher requestMatcher = request -> HttpMethod.POST.name().equals(request.getMethod());
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -135,6 +127,7 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
.ignoringRequestMatchers(this.requestMatcher);
// @formatter:on
}
}
@Test
@@ -143,20 +136,17 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
this.spring.register(IgnoringPathsAndMatchersInLambdaConfig.class, BasicController.class).autowire();
this.mvc.perform(put("/csrf"))
.andExpect(status().isForbidden());
this.mvc.perform(put("/csrf")).andExpect(status().isForbidden());
this.mvc.perform(post("/csrf"))
.andExpect(status().isOk());
this.mvc.perform(post("/csrf")).andExpect(status().isOk());
this.mvc.perform(put("/no-csrf"))
.andExpect(status().isOk());
this.mvc.perform(put("/no-csrf")).andExpect(status().isOk());
}
@EnableWebSecurity
static class IgnoringPathsAndMatchersInLambdaConfig extends WebSecurityConfigurerAdapter {
RequestMatcher requestMatcher =
request -> HttpMethod.POST.name().equals(request.getMethod());
RequestMatcher requestMatcher = request -> HttpMethod.POST.name().equals(request.getMethod());
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -169,10 +159,12 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
);
// @formatter:on
}
}
@RestController
public static class BasicController {
@RequestMapping("/path")
public String path() {
return "path";
@@ -187,5 +179,7 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
public String noCsrf() {
return "no-csrf";
}
}
}

View File

@@ -36,6 +36,7 @@ import org.springframework.web.servlet.support.RequestDataValueProcessor;
*
*/
public class CsrfConfigurerNoWebMvcTests {
ConfigurableApplicationContext context;
@After
@@ -73,15 +74,18 @@ public class CsrfConfigurerNoWebMvcTests {
@Override
protected void configure(HttpSecurity http) {
}
}
@EnableWebSecurity
static class EnableWebOverrideRequestDataConfig {
@Bean
@Primary
public RequestDataValueProcessor requestDataValueProcessor() {
return mock(RequestDataValueProcessor.class);
}
}
@EnableWebSecurity
@@ -90,6 +94,7 @@ public class CsrfConfigurerNoWebMvcTests {
@Override
protected void configure(HttpSecurity http) {
}
}
private void loadContext(Class<?> configs) {
@@ -98,4 +103,5 @@ public class CsrfConfigurerNoWebMvcTests {
annotationConfigApplicationContext.refresh();
this.context = annotationConfigApplicationContext;
}
}

View File

@@ -75,6 +75,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Sam Simmons
*/
public class CsrfConfigurerTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -83,83 +84,83 @@ public class CsrfConfigurerTests {
@Test
public void postWhenWebSecurityEnabledThenRespondsWithForbidden() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(post("/"))
.andExpect(status().isForbidden());
this.mvc.perform(post("/")).andExpect(status().isForbidden());
}
@Test
public void putWhenWebSecurityEnabledThenRespondsWithForbidden() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(put("/"))
.andExpect(status().isForbidden());
this.mvc.perform(put("/")).andExpect(status().isForbidden());
}
@Test
public void patchWhenWebSecurityEnabledThenRespondsWithForbidden() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(patch("/"))
.andExpect(status().isForbidden());
this.mvc.perform(patch("/")).andExpect(status().isForbidden());
}
@Test
public void deleteWhenWebSecurityEnabledThenRespondsWithForbidden() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(delete("/"))
.andExpect(status().isForbidden());
this.mvc.perform(delete("/")).andExpect(status().isForbidden());
}
@Test
public void invalidWhenWebSecurityEnabledThenRespondsWithForbidden() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(request("INVALID", URI.create("/")))
.andExpect(status().isForbidden());
this.mvc.perform(request("INVALID", URI.create("/"))).andExpect(status().isForbidden());
}
@Test
public void getWhenWebSecurityEnabledThenRespondsWithOk() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(get("/"))
.andExpect(status().isOk());
this.mvc.perform(get("/")).andExpect(status().isOk());
}
@Test
public void headWhenWebSecurityEnabledThenRespondsWithOk() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(head("/"))
.andExpect(status().isOk());
this.mvc.perform(head("/")).andExpect(status().isOk());
}
@Test
public void traceWhenWebSecurityEnabledThenRespondsWithOk() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(request(HttpMethod.TRACE, "/"))
.andExpect(status().isOk());
this.mvc.perform(request(HttpMethod.TRACE, "/")).andExpect(status().isOk());
}
@Test
public void optionsWhenWebSecurityEnabledThenRespondsWithOk() throws Exception {
this.spring.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
this.spring
.register(CsrfAppliedDefaultConfig.class, AllowHttpMethodsFirewallConfig.class, BasicController.class)
.autowire();
this.mvc.perform(options("/"))
.andExpect(status().isOk());
this.mvc.perform(options("/")).andExpect(status().isOk());
}
@Test
@@ -171,12 +172,14 @@ public class CsrfConfigurerTests {
@Configuration
static class AllowHttpMethodsFirewallConfig {
@Bean
StrictHttpFirewall strictHttpFirewall() {
StrictHttpFirewall result = new StrictHttpFirewall();
result.setUnsafeAllowAnyHttpMethod(true);
return result;
}
}
@EnableWebSecurity
@@ -185,14 +188,14 @@ public class CsrfConfigurerTests {
@Override
protected void configure(HttpSecurity http) {
}
}
@Test
public void postWhenCsrfDisabledThenRespondsWithOk() throws Exception {
this.spring.register(DisableCsrfConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/"))
.andExpect(status().isOk());
this.mvc.perform(post("/")).andExpect(status().isOk());
}
@EnableWebSecurity
@@ -206,14 +209,14 @@ public class CsrfConfigurerTests {
.disable();
// @formatter:on
}
}
@Test
public void postWhenCsrfDisabledInLambdaThenRespondsWithOk() throws Exception {
this.spring.register(DisableCsrfInLambdaConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/"))
.andExpect(status().isOk());
this.mvc.perform(post("/")).andExpect(status().isOk());
}
@EnableWebSecurity
@@ -226,6 +229,7 @@ public class CsrfConfigurerTests {
.csrf(AbstractHttpConfigurer::disable);
// @formatter:on
}
}
// SEC-2498
@@ -235,11 +239,8 @@ public class CsrfConfigurerTests {
MvcResult mvcResult = this.mvc.perform(post("/to-save")).andReturn();
this.mvc.perform(post("/login")
.param("username", "user")
.param("password", "password")
.session((MockHttpSession) mvcResult.getRequest().getSession()))
.andExpect(status().isFound())
this.mvc.perform(post("/login").param("username", "user").param("password", "password")
.session((MockHttpSession) mvcResult.getRequest().getSession())).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/to-save"));
}
@@ -268,6 +269,7 @@ public class CsrfConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
@@ -278,17 +280,13 @@ public class CsrfConfigurerTests {
when(CsrfDisablesPostRequestFromRequestCacheConfig.REPO.generateToken(any())).thenReturn(csrfToken);
this.spring.register(CsrfDisablesPostRequestFromRequestCacheConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(post("/some-url"))
.andReturn();
this.mvc.perform(post("/login")
.param("username", "user")
.param("password", "password")
.with(csrf())
.session((MockHttpSession) mvcResult.getRequest().getSession()))
.andExpect(status().isFound())
MvcResult mvcResult = this.mvc.perform(post("/some-url")).andReturn();
this.mvc.perform(post("/login").param("username", "user").param("password", "password").with(csrf())
.session((MockHttpSession) mvcResult.getRequest().getSession())).andExpect(status().isFound())
.andExpect(redirectedUrl("/"));
verify(CsrfDisablesPostRequestFromRequestCacheConfig.REPO, atLeastOnce()).loadToken(any(HttpServletRequest.class));
verify(CsrfDisablesPostRequestFromRequestCacheConfig.REPO, atLeastOnce())
.loadToken(any(HttpServletRequest.class));
}
@Test
@@ -299,21 +297,18 @@ public class CsrfConfigurerTests {
when(CsrfDisablesPostRequestFromRequestCacheConfig.REPO.generateToken(any())).thenReturn(csrfToken);
this.spring.register(CsrfDisablesPostRequestFromRequestCacheConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/some-url"))
.andReturn();
this.mvc.perform(post("/login")
.param("username", "user")
.param("password", "password")
.with(csrf())
.session((MockHttpSession) mvcResult.getRequest().getSession()))
.andExpect(status().isFound())
MvcResult mvcResult = this.mvc.perform(get("/some-url")).andReturn();
this.mvc.perform(post("/login").param("username", "user").param("password", "password").with(csrf())
.session((MockHttpSession) mvcResult.getRequest().getSession())).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/some-url"));
verify(CsrfDisablesPostRequestFromRequestCacheConfig.REPO, atLeastOnce()).loadToken(any(HttpServletRequest.class));
verify(CsrfDisablesPostRequestFromRequestCacheConfig.REPO, atLeastOnce())
.loadToken(any(HttpServletRequest.class));
}
@EnableWebSecurity
static class CsrfDisablesPostRequestFromRequestCacheConfig extends WebSecurityConfigurerAdapter {
static CsrfTokenRepository REPO;
@Override
@@ -338,6 +333,7 @@ public class CsrfConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
// SEC-2422
@@ -345,19 +341,16 @@ public class CsrfConfigurerTests {
public void postWhenCsrfEnabledAndSessionIsExpiredThenRespondsWithForbidden() throws Exception {
this.spring.register(InvalidSessionUrlConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(post("/")
.param("_csrf", "abc"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/error/sessionError"))
.andReturn();
MvcResult mvcResult = this.mvc.perform(post("/").param("_csrf", "abc")).andExpect(status().isFound())
.andExpect(redirectedUrl("/error/sessionError")).andReturn();
this.mvc.perform(post("/")
.session((MockHttpSession) mvcResult.getRequest().getSession()))
this.mvc.perform(post("/").session((MockHttpSession) mvcResult.getRequest().getSession()))
.andExpect(status().isForbidden());
}
@EnableWebSecurity
static class InvalidSessionUrlConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -368,16 +361,15 @@ public class CsrfConfigurerTests {
.invalidSessionUrl("/error/sessionError");
// @formatter:on
}
}
@Test
public void requireCsrfProtectionMatcherWhenRequestDoesNotMatchThenRespondsWithOk() throws Exception {
this.spring.register(RequireCsrfProtectionMatcherConfig.class, BasicController.class).autowire();
when(RequireCsrfProtectionMatcherConfig.MATCHER.matches(any()))
.thenReturn(false);
when(RequireCsrfProtectionMatcherConfig.MATCHER.matches(any())).thenReturn(false);
this.mvc.perform(get("/"))
.andExpect(status().isOk());
this.mvc.perform(get("/")).andExpect(status().isOk());
}
@Test
@@ -386,12 +378,12 @@ public class CsrfConfigurerTests {
when(RequireCsrfProtectionMatcherConfig.MATCHER.matches(any())).thenReturn(true);
this.spring.register(RequireCsrfProtectionMatcherConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RequireCsrfProtectionMatcherConfig extends WebSecurityConfigurerAdapter {
static RequestMatcher MATCHER;
@Override
@@ -402,17 +394,16 @@ public class CsrfConfigurerTests {
.requireCsrfProtectionMatcher(MATCHER);
// @formatter:on
}
}
@Test
public void requireCsrfProtectionMatcherInLambdaWhenRequestDoesNotMatchThenRespondsWithOk() throws Exception {
RequireCsrfProtectionMatcherInLambdaConfig.MATCHER = mock(RequestMatcher.class);
this.spring.register(RequireCsrfProtectionMatcherInLambdaConfig.class, BasicController.class).autowire();
when(RequireCsrfProtectionMatcherInLambdaConfig.MATCHER.matches(any()))
.thenReturn(false);
when(RequireCsrfProtectionMatcherInLambdaConfig.MATCHER.matches(any())).thenReturn(false);
this.mvc.perform(get("/"))
.andExpect(status().isOk());
this.mvc.perform(get("/")).andExpect(status().isOk());
}
@Test
@@ -421,12 +412,12 @@ public class CsrfConfigurerTests {
when(RequireCsrfProtectionMatcherInLambdaConfig.MATCHER.matches(any())).thenReturn(true);
this.spring.register(RequireCsrfProtectionMatcherInLambdaConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RequireCsrfProtectionMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
static RequestMatcher MATCHER;
@Override
@@ -436,6 +427,7 @@ public class CsrfConfigurerTests {
.csrf(csrf -> csrf.requireCsrfProtectionMatcher(MATCHER));
// @formatter:on
}
}
@Test
@@ -445,8 +437,7 @@ public class CsrfConfigurerTests {
.thenReturn(new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "token"));
this.spring.register(CsrfTokenRepositoryConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isOk());
this.mvc.perform(get("/")).andExpect(status().isOk());
verify(CsrfTokenRepositoryConfig.REPO).loadToken(any(HttpServletRequest.class));
}
@@ -455,12 +446,10 @@ public class CsrfConfigurerTests {
CsrfTokenRepositoryConfig.REPO = mock(CsrfTokenRepository.class);
this.spring.register(CsrfTokenRepositoryConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/logout")
.with(csrf())
.with(user("user")));
this.mvc.perform(post("/logout").with(csrf()).with(user("user")));
verify(CsrfTokenRepositoryConfig.REPO)
.saveToken(isNull(), any(HttpServletRequest.class), any(HttpServletResponse.class));
verify(CsrfTokenRepositoryConfig.REPO).saveToken(isNull(), any(HttpServletRequest.class),
any(HttpServletResponse.class));
}
@Test
@@ -471,18 +460,16 @@ public class CsrfConfigurerTests {
when(CsrfTokenRepositoryConfig.REPO.generateToken(any())).thenReturn(csrfToken);
this.spring.register(CsrfTokenRepositoryConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/login")
.with(csrf())
.param("username", "user")
.param("password", "password"))
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password"))
.andExpect(redirectedUrl("/"));
verify(CsrfTokenRepositoryConfig.REPO)
.saveToken(isNull(), any(HttpServletRequest.class), any(HttpServletResponse.class));
verify(CsrfTokenRepositoryConfig.REPO).saveToken(isNull(), any(HttpServletRequest.class),
any(HttpServletResponse.class));
}
@EnableWebSecurity
static class CsrfTokenRepositoryConfig extends WebSecurityConfigurerAdapter {
static CsrfTokenRepository REPO;
@Override
@@ -504,6 +491,7 @@ public class CsrfConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
@@ -513,13 +501,13 @@ public class CsrfConfigurerTests {
.thenReturn(new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "token"));
this.spring.register(CsrfTokenRepositoryInLambdaConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isOk());
this.mvc.perform(get("/")).andExpect(status().isOk());
verify(CsrfTokenRepositoryInLambdaConfig.REPO).loadToken(any(HttpServletRequest.class));
}
@EnableWebSecurity
static class CsrfTokenRepositoryInLambdaConfig extends WebSecurityConfigurerAdapter {
static CsrfTokenRepository REPO;
@Override
@@ -530,6 +518,7 @@ public class CsrfConfigurerTests {
.csrf(csrf -> csrf.csrfTokenRepository(REPO));
// @formatter:on
}
}
@Test
@@ -537,15 +526,15 @@ public class CsrfConfigurerTests {
AccessDeniedHandlerConfig.DENIED_HANDLER = mock(AccessDeniedHandler.class);
this.spring.register(AccessDeniedHandlerConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/"))
.andExpect(status().isOk());
this.mvc.perform(post("/")).andExpect(status().isOk());
verify(AccessDeniedHandlerConfig.DENIED_HANDLER)
.handle(any(HttpServletRequest.class), any(HttpServletResponse.class), any());
verify(AccessDeniedHandlerConfig.DENIED_HANDLER).handle(any(HttpServletRequest.class),
any(HttpServletResponse.class), any());
}
@EnableWebSecurity
static class AccessDeniedHandlerConfig extends WebSecurityConfigurerAdapter {
static AccessDeniedHandler DENIED_HANDLER;
@Override
@@ -556,26 +545,22 @@ public class CsrfConfigurerTests {
.accessDeniedHandler(DENIED_HANDLER);
// @formatter:on
}
}
@Test
public void loginWhenNoCsrfTokenThenRespondsWithForbidden() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mvc.perform(post("/login")
.param("username", "user")
.param("password", "password"))
.andExpect(status().isForbidden())
.andExpect(unauthenticated());
this.mvc.perform(post("/login").param("username", "user").param("password", "password"))
.andExpect(status().isForbidden()).andExpect(unauthenticated());
}
@Test
public void logoutWhenNoCsrfTokenThenRespondsWithForbidden() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mvc.perform(post("/logout")
.with(user("username")))
.andExpect(status().isForbidden())
this.mvc.perform(post("/logout").with(user("username"))).andExpect(status().isForbidden())
.andExpect(authenticated());
}
@@ -584,9 +569,7 @@ public class CsrfConfigurerTests {
public void logoutWhenCsrfEnabledAndGetRequestThenDoesNotLogout() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mvc.perform(get("/logout")
.with(user("username")))
.andExpect(authenticated());
this.mvc.perform(get("/logout").with(user("username"))).andExpect(authenticated());
}
@EnableWebSecurity
@@ -599,15 +582,14 @@ public class CsrfConfigurerTests {
.formLogin();
// @formatter:on
}
}
@Test
public void logoutWhenGetRequestAndGetEnabledForLogoutThenLogsOut() throws Exception {
this.spring.register(LogoutAllowsGetConfig.class).autowire();
this.mvc.perform(get("/logout")
.with(user("username")))
.andExpect(unauthenticated());
this.mvc.perform(get("/logout").with(user("username"))).andExpect(unauthenticated());
}
@EnableWebSecurity
@@ -623,18 +605,19 @@ public class CsrfConfigurerTests {
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"));
// @formatter:on
}
}
// SEC-2749
@Test
public void configureWhenRequireCsrfProtectionMatcherNullThenException() {
assertThatThrownBy(() -> this.spring.register(NullRequireCsrfProtectionMatcherConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullRequireCsrfProtectionMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -643,14 +626,14 @@ public class CsrfConfigurerTests {
.requireCsrfProtectionMatcher(null);
// @formatter:on
}
}
@Test
public void getWhenDefaultCsrfTokenRepositoryThenDoesNotCreateSession() throws Exception {
this.spring.register(DefaultDoesNotCreateSession.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/"))
.andReturn();
MvcResult mvcResult = this.mvc.perform(get("/")).andReturn();
assertThat(mvcResult.getRequest().getSession(false)).isNull();
}
@@ -679,10 +662,12 @@ public class CsrfConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class NullAuthenticationStrategy extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -691,17 +676,18 @@ public class CsrfConfigurerTests {
.sessionAuthenticationStrategy(null);
// @formatter:on
}
}
@Test
public void getWhenNullAuthenticationStrategyThenException() {
assertThatThrownBy(() -> this.spring.register(NullAuthenticationStrategy.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class CsrfAuthenticationStrategyConfig extends WebSecurityConfigurerAdapter {
static SessionAuthenticationStrategy STRATEGY;
@Override
@@ -723,6 +709,7 @@ public class CsrfConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
@@ -731,18 +718,16 @@ public class CsrfConfigurerTests {
this.spring.register(CsrfAuthenticationStrategyConfig.class).autowire();
this.mvc.perform(post("/login")
.with(csrf())
.param("username", "user")
.param("password", "password"))
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password"))
.andExpect(redirectedUrl("/"));
verify(CsrfAuthenticationStrategyConfig.STRATEGY, atLeastOnce())
.onAuthentication(any(Authentication.class), any(HttpServletRequest.class), any(HttpServletResponse.class));
verify(CsrfAuthenticationStrategyConfig.STRATEGY, atLeastOnce()).onAuthentication(any(Authentication.class),
any(HttpServletRequest.class), any(HttpServletResponse.class));
}
@RestController
static class BasicController {
@GetMapping("/")
public void rootGet() {
}
@@ -750,5 +735,7 @@ public class CsrfConfigurerTests {
@PostMapping("/")
public void rootPost() {
}
}
}

View File

@@ -78,6 +78,7 @@ public class DefaultFiltersTests {
@EnableWebSecurity
static class FilterChainProxyBuilderMissingConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
@@ -86,31 +87,36 @@ public class DefaultFiltersTests {
.withUser("user").password("password").roles("USER");
// @formatter:on
}
}
@Test
public void nullWebInvocationPrivilegeEvaluator() {
this.spring.register(NullWebInvocationPrivilegeEvaluatorConfig.class, UserDetailsServiceConfig.class);
List<SecurityFilterChain> filterChains = this.spring.getContext().getBean(FilterChainProxy.class).getFilterChains();
List<SecurityFilterChain> filterChains = this.spring.getContext().getBean(FilterChainProxy.class)
.getFilterChains();
assertThat(filterChains.size()).isEqualTo(1);
DefaultSecurityFilterChain filterChain = (DefaultSecurityFilterChain) filterChains.get(0);
assertThat(filterChain.getRequestMatcher()).isInstanceOf(AnyRequestMatcher.class);
assertThat(filterChain.getFilters().size()).isEqualTo(1);
long filter = filterChain.getFilters().stream()
.filter(it -> it instanceof UsernamePasswordAuthenticationFilter).count();
long filter = filterChain.getFilters().stream().filter(it -> it instanceof UsernamePasswordAuthenticationFilter)
.count();
assertThat(filter).isEqualTo(1);
}
@Configuration
static class UserDetailsServiceConfig {
@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(PasswordEncodedUser.user(), PasswordEncodedUser.admin());
}
}
@EnableWebSecurity
static class NullWebInvocationPrivilegeEvaluatorConfig extends WebSecurityConfigurerAdapter {
NullWebInvocationPrivilegeEvaluatorConfig() {
super(true);
}
@@ -118,12 +124,14 @@ public class DefaultFiltersTests {
protected void configure(HttpSecurity http) throws Exception {
http.formLogin();
}
}
@Test
public void filterChainProxyBuilderIgnoringResources() {
this.spring.register(FilterChainProxyBuilderIgnoringConfig.class, UserDetailsServiceConfig.class);
List<SecurityFilterChain> filterChains = this.spring.getContext().getBean(FilterChainProxy.class).getFilterChains();
List<SecurityFilterChain> filterChains = this.spring.getContext().getBean(FilterChainProxy.class)
.getFilterChains();
assertThat(filterChains.size()).isEqualTo(2);
DefaultSecurityFilterChain firstFilter = (DefaultSecurityFilterChain) filterChains.get(0);
DefaultSecurityFilterChain secondFilter = (DefaultSecurityFilterChain) filterChains.get(1);
@@ -148,6 +156,7 @@ public class DefaultFiltersTests {
@EnableWebSecurity
static class FilterChainProxyBuilderIgnoringConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
// @formatter:off
@@ -165,6 +174,7 @@ public class DefaultFiltersTests {
.anyRequest().hasRole("USER");
// @formatter:on
}
}
@Test
@@ -185,7 +195,10 @@ public class DefaultFiltersTests {
@EnableWebSecurity
static class DefaultFiltersConfigPermitAll extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) {
}
}
}

View File

@@ -68,8 +68,7 @@ public class DefaultLoginPageConfigurerTests {
public void getWhenFormLoginEnabledThenRedirectsToLoginPage() throws Exception {
this.spring.register(DefaultLoginPageConfig.class).autowire();
this.mvc.perform(get("/"))
.andExpect(redirectedUrl("http://localhost/login"));
this.mvc.perform(get("/")).andExpect(redirectedUrl("http://localhost/login"));
}
@Test
@@ -78,47 +77,33 @@ public class DefaultLoginPageConfigurerTests {
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
String csrfAttributeName = HttpSessionCsrfTokenRepository.class.getName().concat(".CSRF_TOKEN");
this.mvc.perform(get("/login")
.sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string(
"<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
" <head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n" +
" <meta name=\"description\" content=\"\">\n" +
" <meta name=\"author\" content=\"\">\n" +
" <title>Please sign in</title>\n" +
" <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n" +
" <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n" +
" </head>\n" +
" <body>\n" +
" <div class=\"container\">\n" +
" <form class=\"form-signin\" method=\"post\" action=\"/login\">\n" +
" <h2 class=\"form-signin-heading\">Please sign in</h2>\n" +
" <p>\n" +
" <label for=\"username\" class=\"sr-only\">Username</label>\n" +
" <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n" +
" </p>\n" +
" <p>\n" +
" <label for=\"password\" class=\"sr-only\">Password</label>\n" +
" <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n" +
" </p>\n" +
"<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n" +
" <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n" +
" </form>\n" +
"</div>\n" +
"</body></html>"
));
this.mvc.perform(get("/login").sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string("<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + " <head>\n"
+ " <meta charset=\"utf-8\">\n"
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
+ " <meta name=\"description\" content=\"\">\n" + " <meta name=\"author\" content=\"\">\n"
+ " <title>Please sign in</title>\n"
+ " <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n"
+ " <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
+ " </head>\n" + " <body>\n" + " <div class=\"container\">\n"
+ " <form class=\"form-signin\" method=\"post\" action=\"/login\">\n"
+ " <h2 class=\"form-signin-heading\">Please sign in</h2>\n" + " <p>\n"
+ " <label for=\"username\" class=\"sr-only\">Username</label>\n"
+ " <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
+ " </p>\n" + " <p>\n"
+ " <label for=\"password\" class=\"sr-only\">Password</label>\n"
+ " <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n"
+ " </p>\n" + "<input name=\"" + csrfToken.getParameterName()
+ "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n"
+ " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@Test
public void loginWhenNoCredentialsThenRedirectedToLoginPageWithError() throws Exception {
this.spring.register(DefaultLoginPageConfig.class).autowire();
this.mvc.perform(post("/login")
.with(csrf()))
.andExpect(redirectedUrl("/login?error"));
this.mvc.perform(post("/login").with(csrf())).andExpect(redirectedUrl("/login?error"));
}
@Test
@@ -127,53 +112,37 @@ public class DefaultLoginPageConfigurerTests {
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
String csrfAttributeName = HttpSessionCsrfTokenRepository.class.getName().concat(".CSRF_TOKEN");
MvcResult mvcResult = this.mvc.perform(post("/login")
.with(csrf()))
.andReturn();
MvcResult mvcResult = this.mvc.perform(post("/login").with(csrf())).andReturn();
this.mvc.perform(get("/login?error")
.session((MockHttpSession) mvcResult.getRequest().getSession())
this.mvc.perform(get("/login?error").session((MockHttpSession) mvcResult.getRequest().getSession())
.sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string(
"<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
" <head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n" +
" <meta name=\"description\" content=\"\">\n" +
" <meta name=\"author\" content=\"\">\n" +
" <title>Please sign in</title>\n" +
" <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n" +
" <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n" +
" </head>\n" +
" <body>\n" +
" <div class=\"container\">\n" +
" <form class=\"form-signin\" method=\"post\" action=\"/login\">\n" +
" <h2 class=\"form-signin-heading\">Please sign in</h2>\n" +
"<div class=\"alert alert-danger\" role=\"alert\">Bad credentials</div> <p>\n" +
" <label for=\"username\" class=\"sr-only\">Username</label>\n" +
" <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n" +
" </p>\n" +
" <p>\n" +
" <label for=\"password\" class=\"sr-only\">Password</label>\n" +
" <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n" +
" </p>\n" +
"<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n" +
" <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n" +
" </form>\n" +
"</div>\n" +
"</body></html>"
));
.andExpect(content().string("<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + " <head>\n"
+ " <meta charset=\"utf-8\">\n"
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
+ " <meta name=\"description\" content=\"\">\n" + " <meta name=\"author\" content=\"\">\n"
+ " <title>Please sign in</title>\n"
+ " <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n"
+ " <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
+ " </head>\n" + " <body>\n" + " <div class=\"container\">\n"
+ " <form class=\"form-signin\" method=\"post\" action=\"/login\">\n"
+ " <h2 class=\"form-signin-heading\">Please sign in</h2>\n"
+ "<div class=\"alert alert-danger\" role=\"alert\">Bad credentials</div> <p>\n"
+ " <label for=\"username\" class=\"sr-only\">Username</label>\n"
+ " <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
+ " </p>\n" + " <p>\n"
+ " <label for=\"password\" class=\"sr-only\">Password</label>\n"
+ " <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n"
+ " </p>\n" + "<input name=\"" + csrfToken.getParameterName()
+ "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n"
+ " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@Test
public void loginWhenValidCredentialsThenRedirectsToDefaultSuccessPage() throws Exception {
this.spring.register(DefaultLoginPageConfig.class).autowire();
this.mvc.perform(post("/login")
.with(csrf())
.param("username", "user")
.param("password", "password"))
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password"))
.andExpect(redirectedUrl("/"));
}
@@ -183,42 +152,32 @@ public class DefaultLoginPageConfigurerTests {
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
String csrfAttributeName = HttpSessionCsrfTokenRepository.class.getName().concat(".CSRF_TOKEN");
this.mvc.perform(get("/login?logout")
.sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string(
"<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
" <head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n" +
" <meta name=\"description\" content=\"\">\n" +
" <meta name=\"author\" content=\"\">\n" +
" <title>Please sign in</title>\n" +
" <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n" +
" <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n" +
" </head>\n" +
" <body>\n" +
" <div class=\"container\">\n" +
" <form class=\"form-signin\" method=\"post\" action=\"/login\">\n" +
" <h2 class=\"form-signin-heading\">Please sign in</h2>\n" +
"<div class=\"alert alert-success\" role=\"alert\">You have been signed out</div> <p>\n" +
" <label for=\"username\" class=\"sr-only\">Username</label>\n" +
" <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n" +
" </p>\n" +
" <p>\n" +
" <label for=\"password\" class=\"sr-only\">Password</label>\n" +
" <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n" +
" </p>\n" +
"<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n" +
" <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n" +
" </form>\n" +
"</div>\n" +
"</body></html>"
));
this.mvc.perform(get("/login?logout").sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string("<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + " <head>\n"
+ " <meta charset=\"utf-8\">\n"
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
+ " <meta name=\"description\" content=\"\">\n" + " <meta name=\"author\" content=\"\">\n"
+ " <title>Please sign in</title>\n"
+ " <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n"
+ " <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
+ " </head>\n" + " <body>\n" + " <div class=\"container\">\n"
+ " <form class=\"form-signin\" method=\"post\" action=\"/login\">\n"
+ " <h2 class=\"form-signin-heading\">Please sign in</h2>\n"
+ "<div class=\"alert alert-success\" role=\"alert\">You have been signed out</div> <p>\n"
+ " <label for=\"username\" class=\"sr-only\">Username</label>\n"
+ " <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
+ " </p>\n" + " <p>\n"
+ " <label for=\"password\" class=\"sr-only\">Password</label>\n"
+ " <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n"
+ " </p>\n" + "<input name=\"" + csrfToken.getParameterName()
+ "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n"
+ " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@EnableWebSecurity
static class DefaultLoginPageConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -238,19 +197,19 @@ public class DefaultLoginPageConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void loginPageWhenLoggedOutAndCustomLogoutSuccessHandlerThenDoesNotRenderLoginPage() throws Exception {
this.spring.register(DefaultLoginPageCustomLogoutSuccessHandlerConfig.class).autowire();
this.mvc.perform(get("/login?logout"))
.andExpect(content().string(""));
this.mvc.perform(get("/login?logout")).andExpect(content().string(""));
}
@EnableWebSecurity
static class DefaultLoginPageCustomLogoutSuccessHandlerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -264,18 +223,19 @@ public class DefaultLoginPageConfigurerTests {
.formLogin();
// @formatter:on
}
}
@Test
public void loginPageWhenLoggedOutAndCustomLogoutSuccessUrlThenDoesNotRenderLoginPage() throws Exception {
this.spring.register(DefaultLoginPageCustomLogoutSuccessUrlConfig.class).autowire();
this.mvc.perform(get("/login?logout"))
.andExpect(content().string(""));
this.mvc.perform(get("/login?logout")).andExpect(content().string(""));
}
@EnableWebSecurity
static class DefaultLoginPageCustomLogoutSuccessUrlConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -289,6 +249,7 @@ public class DefaultLoginPageConfigurerTests {
.formLogin();
// @formatter:on
}
}
@Test
@@ -297,43 +258,33 @@ public class DefaultLoginPageConfigurerTests {
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
String csrfAttributeName = HttpSessionCsrfTokenRepository.class.getName().concat(".CSRF_TOKEN");
this.mvc.perform(get("/login")
.sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string(
"<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
" <head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n" +
" <meta name=\"description\" content=\"\">\n" +
" <meta name=\"author\" content=\"\">\n" +
" <title>Please sign in</title>\n" +
" <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n" +
" <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n" +
" </head>\n" +
" <body>\n" +
" <div class=\"container\">\n" +
" <form class=\"form-signin\" method=\"post\" action=\"/login\">\n" +
" <h2 class=\"form-signin-heading\">Please sign in</h2>\n" +
" <p>\n" +
" <label for=\"username\" class=\"sr-only\">Username</label>\n" +
" <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n" +
" </p>\n" +
" <p>\n" +
" <label for=\"password\" class=\"sr-only\">Password</label>\n" +
" <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n" +
" </p>\n" +
"<p><input type='checkbox' name='remember-me'/> Remember me on this computer.</p>\n" +
"<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n" +
" <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n" +
" </form>\n" +
"</div>\n" +
"</body></html>"
));
this.mvc.perform(get("/login").sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string("<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + " <head>\n"
+ " <meta charset=\"utf-8\">\n"
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
+ " <meta name=\"description\" content=\"\">\n" + " <meta name=\"author\" content=\"\">\n"
+ " <title>Please sign in</title>\n"
+ " <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n"
+ " <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
+ " </head>\n" + " <body>\n" + " <div class=\"container\">\n"
+ " <form class=\"form-signin\" method=\"post\" action=\"/login\">\n"
+ " <h2 class=\"form-signin-heading\">Please sign in</h2>\n" + " <p>\n"
+ " <label for=\"username\" class=\"sr-only\">Username</label>\n"
+ " <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
+ " </p>\n" + " <p>\n"
+ " <label for=\"password\" class=\"sr-only\">Password</label>\n"
+ " <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n"
+ " </p>\n"
+ "<p><input type='checkbox' name='remember-me'/> Remember me on this computer.</p>\n"
+ "<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\""
+ csrfToken.getToken() + "\" />\n"
+ " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@EnableWebSecurity
static class DefaultLoginPageWithRememberMeConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -346,6 +297,7 @@ public class DefaultLoginPageConfigurerTests {
.rememberMe();
// @formatter:on
}
}
@Test
@@ -355,38 +307,28 @@ public class DefaultLoginPageConfigurerTests {
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
String csrfAttributeName = HttpSessionCsrfTokenRepository.class.getName().concat(".CSRF_TOKEN");
this.mvc.perform(get("/login")
.sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string(
"<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
" <head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n" +
" <meta name=\"description\" content=\"\">\n" +
" <meta name=\"author\" content=\"\">\n" +
" <title>Please sign in</title>\n" +
" <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n" +
" <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n" +
" </head>\n" +
" <body>\n" +
" <div class=\"container\">\n" +
" <form name=\"oidf\" class=\"form-signin\" method=\"post\" action=\"/login/openid\">\n" +
" <h2 class=\"form-signin-heading\">Login with OpenID Identity</h2>\n" +
" <p>\n" +
" <label for=\"username\" class=\"sr-only\">Identity</label>\n" +
" <input type=\"text\" id=\"username\" name=\"openid_identifier\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n" +
" </p>\n" +
"<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n" +
" <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n" +
" </form>\n" +
"</div>\n" +
"</body></html>"
));
this.mvc.perform(get("/login").sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string("<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + " <head>\n"
+ " <meta charset=\"utf-8\">\n"
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
+ " <meta name=\"description\" content=\"\">\n" + " <meta name=\"author\" content=\"\">\n"
+ " <title>Please sign in</title>\n"
+ " <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n"
+ " <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
+ " </head>\n" + " <body>\n" + " <div class=\"container\">\n"
+ " <form name=\"oidf\" class=\"form-signin\" method=\"post\" action=\"/login/openid\">\n"
+ " <h2 class=\"form-signin-heading\">Login with OpenID Identity</h2>\n"
+ " <p>\n" + " <label for=\"username\" class=\"sr-only\">Identity</label>\n"
+ " <input type=\"text\" id=\"username\" name=\"openid_identifier\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
+ " </p>\n" + "<input name=\"" + csrfToken.getParameterName()
+ "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n"
+ " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@EnableWebSecurity
static class DefaultLoginPageWithOpenIDConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -397,6 +339,7 @@ public class DefaultLoginPageConfigurerTests {
.openidLogin();
// @formatter:on
}
}
@Test
@@ -405,53 +348,43 @@ public class DefaultLoginPageConfigurerTests {
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
String csrfAttributeName = HttpSessionCsrfTokenRepository.class.getName().concat(".CSRF_TOKEN");
this.mvc.perform(get("/login")
.sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string(
"<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
" <head>\n" +
" <meta charset=\"utf-8\">\n" +
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n" +
" <meta name=\"description\" content=\"\">\n" +
" <meta name=\"author\" content=\"\">\n" +
" <title>Please sign in</title>\n" +
" <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n" +
" <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n" +
" </head>\n" +
" <body>\n" +
" <div class=\"container\">\n" +
" <form class=\"form-signin\" method=\"post\" action=\"/login\">\n" +
" <h2 class=\"form-signin-heading\">Please sign in</h2>\n" +
" <p>\n" +
" <label for=\"username\" class=\"sr-only\">Username</label>\n" +
" <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n" +
" </p>\n" +
" <p>\n" +
" <label for=\"password\" class=\"sr-only\">Password</label>\n" +
" <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n" +
" </p>\n" +
"<p><input type='checkbox' name='remember-me'/> Remember me on this computer.</p>\n" +
"<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n" +
" <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n" +
" </form>\n" +
" <form name=\"oidf\" class=\"form-signin\" method=\"post\" action=\"/login/openid\">\n" +
" <h2 class=\"form-signin-heading\">Login with OpenID Identity</h2>\n" +
" <p>\n" +
" <label for=\"username\" class=\"sr-only\">Identity</label>\n" +
" <input type=\"text\" id=\"username\" name=\"openid_identifier\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n" +
" </p>\n" +
"<p><input type='checkbox' name='remember-me'/> Remember me on this computer.</p>\n" +
"<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\"" + csrfToken.getToken() + "\" />\n" +
" <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n" +
" </form>\n" +
"</div>\n" +
"</body></html>"
));
this.mvc.perform(get("/login").sessionAttr(csrfAttributeName, csrfToken))
.andExpect(content().string("<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + " <head>\n"
+ " <meta charset=\"utf-8\">\n"
+ " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n"
+ " <meta name=\"description\" content=\"\">\n" + " <meta name=\"author\" content=\"\">\n"
+ " <title>Please sign in</title>\n"
+ " <link href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css\" rel=\"stylesheet\" integrity=\"sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M\" crossorigin=\"anonymous\">\n"
+ " <link href=\"https://getbootstrap.com/docs/4.0/examples/signin/signin.css\" rel=\"stylesheet\" crossorigin=\"anonymous\"/>\n"
+ " </head>\n" + " <body>\n" + " <div class=\"container\">\n"
+ " <form class=\"form-signin\" method=\"post\" action=\"/login\">\n"
+ " <h2 class=\"form-signin-heading\">Please sign in</h2>\n" + " <p>\n"
+ " <label for=\"username\" class=\"sr-only\">Username</label>\n"
+ " <input type=\"text\" id=\"username\" name=\"username\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
+ " </p>\n" + " <p>\n"
+ " <label for=\"password\" class=\"sr-only\">Password</label>\n"
+ " <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\" placeholder=\"Password\" required>\n"
+ " </p>\n"
+ "<p><input type='checkbox' name='remember-me'/> Remember me on this computer.</p>\n"
+ "<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\""
+ csrfToken.getToken() + "\" />\n"
+ " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
+ " </form>\n"
+ " <form name=\"oidf\" class=\"form-signin\" method=\"post\" action=\"/login/openid\">\n"
+ " <h2 class=\"form-signin-heading\">Login with OpenID Identity</h2>\n"
+ " <p>\n" + " <label for=\"username\" class=\"sr-only\">Identity</label>\n"
+ " <input type=\"text\" id=\"username\" name=\"openid_identifier\" class=\"form-control\" placeholder=\"Username\" required autofocus>\n"
+ " </p>\n"
+ "<p><input type='checkbox' name='remember-me'/> Remember me on this computer.</p>\n"
+ "<input name=\"" + csrfToken.getParameterName() + "\" type=\"hidden\" value=\""
+ csrfToken.getToken() + "\" />\n"
+ " <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Sign in</button>\n"
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@EnableWebSecurity
static class DefaultLoginPageWithFormLoginOpenIDRememberMeConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -466,6 +399,7 @@ public class DefaultLoginPageConfigurerTests {
.openidLogin();
// @formatter:on
}
}
@Test
@@ -474,13 +408,13 @@ public class DefaultLoginPageConfigurerTests {
FilterChainProxy filterChain = this.spring.getContext().getBean(FilterChainProxy.class);
assertThat(filterChain.getFilterChains().get(0).getFilters().stream()
.filter(filter -> filter.getClass().isAssignableFrom(DefaultLoginPageGeneratingFilter.class))
.count())
.isZero();
.filter(filter -> filter.getClass().isAssignableFrom(DefaultLoginPageGeneratingFilter.class)).count())
.isZero();
}
@EnableWebSecurity
static class DefaultLoginWithCustomAuthenticationEntryPointConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -494,6 +428,7 @@ public class DefaultLoginPageConfigurerTests {
.formLogin();
// @formatter:on
}
}
@Test
@@ -501,8 +436,7 @@ public class DefaultLoginPageConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(DefaultLoginPageGeneratingFilter.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(DefaultLoginPageGeneratingFilter.class));
}
@Test
@@ -519,8 +453,7 @@ public class DefaultLoginPageConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(LoginUrlAuthenticationEntryPoint.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(LoginUrlAuthenticationEntryPoint.class));
}
@Test
@@ -528,12 +461,12 @@ public class DefaultLoginPageConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(ExceptionTranslationFilter.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ExceptionTranslationFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor;
@Override
@@ -550,12 +483,16 @@ public class DefaultLoginPageConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
}

View File

@@ -43,6 +43,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@RunWith(SpringJUnit4ClassRunner.class)
@SecurityTestExecutionListeners
public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
@Autowired
MockMvc mvc;
@@ -51,22 +52,19 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
@Test
@WithMockUser(roles = "ANYTHING")
public void getWhenAccessDeniedOverriddenThenCustomizesResponseByRequest()
throws Exception {
public void getWhenAccessDeniedOverriddenThenCustomizesResponseByRequest() throws Exception {
this.spring.register(RequestMatcherBasedAccessDeniedHandlerConfig.class).autowire();
this.mvc.perform(get("/hello"))
.andExpect(status().isIAmATeapot());
this.mvc.perform(get("/hello")).andExpect(status().isIAmATeapot());
this.mvc.perform(get("/goodbye"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/goodbye")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RequestMatcherBasedAccessDeniedHandlerConfig extends WebSecurityConfigurerAdapter {
AccessDeniedHandler teapotDeniedHandler =
(request, response, exception) ->
response.setStatus(HttpStatus.I_AM_A_TEAPOT.value());
AccessDeniedHandler teapotDeniedHandler = (request, response, exception) -> response
.setStatus(HttpStatus.I_AM_A_TEAPOT.value());
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -84,26 +82,24 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
AnyRequestMatcher.INSTANCE);
// @formatter:on
}
}
@Test
@WithMockUser(roles = "ANYTHING")
public void getWhenAccessDeniedOverriddenInLambdaThenCustomizesResponseByRequest()
throws Exception {
public void getWhenAccessDeniedOverriddenInLambdaThenCustomizesResponseByRequest() throws Exception {
this.spring.register(RequestMatcherBasedAccessDeniedHandlerInLambdaConfig.class).autowire();
this.mvc.perform(get("/hello"))
.andExpect(status().isIAmATeapot());
this.mvc.perform(get("/hello")).andExpect(status().isIAmATeapot());
this.mvc.perform(get("/goodbye"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/goodbye")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RequestMatcherBasedAccessDeniedHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
AccessDeniedHandler teapotDeniedHandler =
(request, response, exception) ->
response.setStatus(HttpStatus.I_AM_A_TEAPOT.value());
AccessDeniedHandler teapotDeniedHandler = (request, response, exception) -> response
.setStatus(HttpStatus.I_AM_A_TEAPOT.value());
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -126,26 +122,24 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
);
// @formatter:on
}
}
@Test
@WithMockUser(roles = "ANYTHING")
public void getWhenAccessDeniedOverriddenByOnlyOneHandlerThenAllRequestsUseThatHandler()
throws Exception {
public void getWhenAccessDeniedOverriddenByOnlyOneHandlerThenAllRequestsUseThatHandler() throws Exception {
this.spring.register(SingleRequestMatcherAccessDeniedHandlerConfig.class).autowire();
this.mvc.perform(get("/hello"))
.andExpect(status().isIAmATeapot());
this.mvc.perform(get("/hello")).andExpect(status().isIAmATeapot());
this.mvc.perform(get("/goodbye"))
.andExpect(status().isIAmATeapot());
this.mvc.perform(get("/goodbye")).andExpect(status().isIAmATeapot());
}
@EnableWebSecurity
static class SingleRequestMatcherAccessDeniedHandlerConfig extends WebSecurityConfigurerAdapter {
AccessDeniedHandler teapotDeniedHandler =
(request, response, exception) ->
response.setStatus(HttpStatus.I_AM_A_TEAPOT.value());
AccessDeniedHandler teapotDeniedHandler = (request, response, exception) -> response
.setStatus(HttpStatus.I_AM_A_TEAPOT.value());
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -160,5 +154,7 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
new AntPathRequestMatcher("/hello/**"));
// @formatter:on
}
}
}

View File

@@ -67,12 +67,12 @@ public class ExceptionHandlingConfigurerTests {
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnExceptionTranslationFilter() {
this.spring.register(ObjectPostProcessorConfig.class, DefaultSecurityConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(ExceptionTranslationFilter.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ExceptionTranslationFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
@@ -87,13 +87,16 @@ public class ExceptionHandlingConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
// SEC-2199
@@ -101,8 +104,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsApplicationXhtmlXmlThenRespondsWith302() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_XHTML_XML))
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_XHTML_XML))
.andExpect(status().isFound());
}
@@ -111,9 +113,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsImageGifThenRespondsWith302() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.IMAGE_GIF))
.andExpect(status().isFound());
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.IMAGE_GIF)).andExpect(status().isFound());
}
// SEC-2199
@@ -121,9 +121,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsImageJpgThenRespondsWith302() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.IMAGE_JPEG))
.andExpect(status().isFound());
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.IMAGE_JPEG)).andExpect(status().isFound());
}
// SEC-2199
@@ -131,9 +129,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsImagePngThenRespondsWith302() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.IMAGE_PNG))
.andExpect(status().isFound());
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.IMAGE_PNG)).andExpect(status().isFound());
}
// SEC-2199
@@ -141,9 +137,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsTextHtmlThenRespondsWith302() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML))
.andExpect(status().isFound());
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML)).andExpect(status().isFound());
}
// SEC-2199
@@ -151,9 +145,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsTextPlainThenRespondsWith302() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.TEXT_PLAIN))
.andExpect(status().isFound());
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.TEXT_PLAIN)).andExpect(status().isFound());
}
// SEC-2199
@@ -161,8 +153,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsApplicationAtomXmlThenRespondsWith401() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_ATOM_XML))
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_ATOM_XML))
.andExpect(status().isUnauthorized());
}
@@ -171,8 +162,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsApplicationFormUrlEncodedThenRespondsWith401() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_FORM_URLENCODED))
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_FORM_URLENCODED))
.andExpect(status().isUnauthorized());
}
@@ -181,8 +171,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsApplicationJsonThenRespondsWith401() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON))
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON))
.andExpect(status().isUnauthorized());
}
@@ -191,8 +180,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsApplicationOctetStreamThenRespondsWith401() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM))
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.APPLICATION_OCTET_STREAM))
.andExpect(status().isUnauthorized());
}
@@ -201,8 +189,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsMultipartFormDataThenRespondsWith401() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.MULTIPART_FORM_DATA))
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.MULTIPART_FORM_DATA))
.andExpect(status().isUnauthorized());
}
@@ -211,9 +198,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptHeaderIsTextXmlThenRespondsWith401() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.TEXT_XML))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.TEXT_XML)).andExpect(status().isUnauthorized());
}
// gh-4831
@@ -221,18 +206,15 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptIsAnyThenRespondsWith401() throws Exception {
this.spring.register(DefaultSecurityConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, MediaType.ALL))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, MediaType.ALL)).andExpect(status().isUnauthorized());
}
@Test
public void getWhenAcceptIsChromeThenRespondsWith302() throws Exception {
this.spring.register(DefaultSecurityConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT,
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"))
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT,
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"))
.andExpect(status().isFound());
}
@@ -240,9 +222,7 @@ public class ExceptionHandlingConfigurerTests {
public void getWhenAcceptIsTextPlainAndXRequestedWithIsXHRThenRespondsWith401() throws Exception {
this.spring.register(HttpBasicAndFormLoginEntryPointsConfig.class).autowire();
this.mvc.perform(get("/")
.header("Accept", MediaType.TEXT_PLAIN)
.header("X-Requested-With", "XMLHttpRequest"))
this.mvc.perform(get("/").header("Accept", MediaType.TEXT_PLAIN).header("X-Requested-With", "XMLHttpRequest"))
.andExpect(status().isUnauthorized());
}
@@ -284,12 +264,13 @@ public class ExceptionHandlingConfigurerTests {
.formLogin();
// @formatter:on
}
}
@Test
public void getWhenCustomContentNegotiationStrategyThenStrategyIsUsed() throws Exception {
this.spring.register(OverrideContentNegotiationStrategySharedObjectConfig.class,
DefaultSecurityConfig.class).autowire();
this.spring.register(OverrideContentNegotiationStrategySharedObjectConfig.class, DefaultSecurityConfig.class)
.autowire();
this.mvc.perform(get("/"));
@@ -299,38 +280,39 @@ public class ExceptionHandlingConfigurerTests {
@EnableWebSecurity
static class OverrideContentNegotiationStrategySharedObjectConfig extends WebSecurityConfigurerAdapter {
static ContentNegotiationStrategy CNS = mock(ContentNegotiationStrategy.class);
@Bean
public static ContentNegotiationStrategy cns() {
return CNS;
}
}
@Test
public void getWhenUsingDefaultsAndUnauthenticatedThenRedirectsToLogin() throws Exception {
this.spring.register(DefaultHttpConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, "bogus/type"))
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, "bogus/type"))
.andExpect(redirectedUrl("http://localhost/login"));
}
@EnableWebSecurity
static class DefaultHttpConfig extends WebSecurityConfigurerAdapter {
}
@Test
public void getWhenDeclaringHttpBasicBeforeFormLoginThenRespondsWith401() throws Exception {
this.spring.register(BasicAuthenticationEntryPointBeforeFormLoginConfig.class).autowire();
this.mvc.perform(get("/")
.header(HttpHeaders.ACCEPT, "bogus/type"))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, "bogus/type")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class BasicAuthenticationEntryPointBeforeFormLoginConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -343,6 +325,7 @@ public class ExceptionHandlingConfigurerTests {
.formLogin();
// @formatter:on
}
}
@Test
@@ -351,26 +334,20 @@ public class ExceptionHandlingConfigurerTests {
this.mvc.perform(get("/"));
verify(InvokeTwiceDoesNotOverrideConfig.AEP)
.commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
verify(InvokeTwiceDoesNotOverrideConfig.AEP).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
static AuthenticationEntryPoint AEP = mock(AuthenticationEntryPoint.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:on
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(AEP)
.and()
.exceptionHandling();
http.authorizeRequests().anyRequest().authenticated().and().exceptionHandling()
.authenticationEntryPoint(AEP).and().exceptionHandling();
// @formatter:off
}
}

View File

@@ -84,13 +84,14 @@ public class ExpressionUrlAuthorizationConfigurerTests {
@Test
public void configureWhenHasRoleStartingWithStringRoleThenException() {
assertThatThrownBy(() -> this.spring.register(HasRoleStartingWithRoleConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_USER'");
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasMessageContaining(
"role should not start with 'ROLE_' since it is automatically inserted. Got 'ROLE_USER'");
}
@EnableWebSecurity
static class HasRoleStartingWithRoleConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -99,18 +100,19 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().hasRole("ROLE_USER");
// @formatter:on
}
}
@Test
public void configureWhenNoCustomAccessDecisionManagerThenUsesAffirmativeBased() {
this.spring.register(NoSpecificAccessDecisionManagerConfig.class).autowire();
verify(NoSpecificAccessDecisionManagerConfig.objectPostProcessor)
.postProcess(any(AffirmativeBased.class));
verify(NoSpecificAccessDecisionManagerConfig.objectPostProcessor).postProcess(any(AffirmativeBased.class));
}
@EnableWebSecurity
static class NoSpecificAccessDecisionManagerConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
@@ -126,34 +128,37 @@ public class ExpressionUrlAuthorizationConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
@Test
public void configureWhenAuthorizedRequestsAndNoRequestsThenException() {
assertThatThrownBy(() -> this.spring.register(NoRequestsConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("At least one mapping is required (i.e. authorizeRequests().anyRequest().authenticated())");
.isInstanceOf(BeanCreationException.class).hasMessageContaining(
"At least one mapping is required (i.e. authorizeRequests().anyRequest().authenticated())");
}
@EnableWebSecurity
static class NoRequestsConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests();
// @formatter:on
}
}
@Test
public void configureWhenAnyRequestIncompleteMappingThenException() {
assertThatThrownBy(() -> this.spring.register(IncompleteMappingConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("An incomplete mapping was found for ");
.isInstanceOf(BeanCreationException.class).hasMessageContaining("An incomplete mapping was found for ");
}
@EnableWebSecurity
static class IncompleteMappingConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -163,15 +168,14 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest();
// @formatter:on
}
}
@Test
public void getWhenHasAnyAuthorityRoleUserConfiguredAndAuthorityIsRoleUserThenRespondsWithOk()
throws Exception {
public void getWhenHasAnyAuthorityRoleUserConfiguredAndAuthorityIsRoleUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserAnyAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").authorities(new SimpleGrantedAuthority("ROLE_USER"))))
this.mvc.perform(get("/").with(user("user").authorities(new SimpleGrantedAuthority("ROLE_USER"))))
.andExpect(status().isOk());
}
@@ -180,22 +184,20 @@ public class ExpressionUrlAuthorizationConfigurerTests {
throws Exception {
this.spring.register(RoleUserAnyAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").authorities(new SimpleGrantedAuthority("ROLE_ADMIN"))))
this.mvc.perform(get("/").with(user("user").authorities(new SimpleGrantedAuthority("ROLE_ADMIN"))))
.andExpect(status().isForbidden());
}
@Test
public void getWhenHasAnyAuthorityRoleUserConfiguredAndNoAuthorityThenRespondsWithUnauthorized()
throws Exception {
public void getWhenHasAnyAuthorityRoleUserConfiguredAndNoAuthorityThenRespondsWithUnauthorized() throws Exception {
this.spring.register(RoleUserAnyAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class RoleUserAnyAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -206,15 +208,14 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().hasAnyAuthority("ROLE_USER");
// @formatter:on
}
}
@Test
public void getWhenHasAuthorityRoleUserConfiguredAndAuthorityIsRoleUserThenRespondsWithOk()
throws Exception {
public void getWhenHasAuthorityRoleUserConfiguredAndAuthorityIsRoleUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").authorities(new SimpleGrantedAuthority("ROLE_USER"))))
this.mvc.perform(get("/").with(user("user").authorities(new SimpleGrantedAuthority("ROLE_USER"))))
.andExpect(status().isOk());
}
@@ -223,22 +224,20 @@ public class ExpressionUrlAuthorizationConfigurerTests {
throws Exception {
this.spring.register(RoleUserAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").authorities(new SimpleGrantedAuthority("ROLE_ADMIN"))))
this.mvc.perform(get("/").with(user("user").authorities(new SimpleGrantedAuthority("ROLE_ADMIN"))))
.andExpect(status().isForbidden());
}
@Test
public void getWhenHasAuthorityRoleUserConfiguredAndNoAuthorityThenRespondsWithUnauthorized()
throws Exception {
public void getWhenHasAuthorityRoleUserConfiguredAndNoAuthorityThenRespondsWithUnauthorized() throws Exception {
this.spring.register(RoleUserAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class RoleUserAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -249,25 +248,22 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().hasAuthority("ROLE_USER");
// @formatter:on
}
}
@Test
public void getWhenAuthorityRoleUserOrAdminRequiredAndAuthorityIsRoleUserThenRespondsWithOk()
throws Exception {
public void getWhenAuthorityRoleUserOrAdminRequiredAndAuthorityIsRoleUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserOrRoleAdminAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").authorities(new SimpleGrantedAuthority("ROLE_USER"))))
this.mvc.perform(get("/").with(user("user").authorities(new SimpleGrantedAuthority("ROLE_USER"))))
.andExpect(status().isOk());
}
@Test
public void getWhenAuthorityRoleUserOrAdminRequiredAndAuthorityIsRoleAdminThenRespondsWithOk()
throws Exception {
public void getWhenAuthorityRoleUserOrAdminRequiredAndAuthorityIsRoleAdminThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserOrRoleAdminAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").authorities(new SimpleGrantedAuthority("ROLE_ADMIN"))))
this.mvc.perform(get("/").with(user("user").authorities(new SimpleGrantedAuthority("ROLE_ADMIN"))))
.andExpect(status().isOk());
}
@@ -276,22 +272,20 @@ public class ExpressionUrlAuthorizationConfigurerTests {
throws Exception {
this.spring.register(RoleUserOrRoleAdminAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").authorities(new SimpleGrantedAuthority("ROLE_OTHER"))))
this.mvc.perform(get("/").with(user("user").authorities(new SimpleGrantedAuthority("ROLE_OTHER"))))
.andExpect(status().isForbidden());
}
@Test
public void getWhenAuthorityRoleUserOrAdminAuthRequiredAndNoUserThenRespondsWithUnauthorized()
throws Exception {
public void getWhenAuthorityRoleUserOrAdminAuthRequiredAndNoUserThenRespondsWithUnauthorized() throws Exception {
this.spring.register(RoleUserOrRoleAdminAuthorityConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class RoleUserOrRoleAdminAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -302,28 +296,26 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().hasAnyAuthority("ROLE_USER", "ROLE_ADMIN");
// @formatter:on
}
}
@Test
public void getWhenHasAnyRoleUserConfiguredAndRoleIsUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(get("/").with(user("user").roles("USER"))).andExpect(status().isOk());
}
@Test
public void getWhenHasAnyRoleUserConfiguredAndRoleIsAdminThenRespondsWithForbidden() throws Exception {
this.spring.register(RoleUserConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").roles("ADMIN")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/").with(user("user").roles("ADMIN"))).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RoleUserConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -332,37 +324,33 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().hasAnyRole("USER");
// @formatter:on
}
}
@Test
public void getWhenRoleUserOrAdminConfiguredAndRoleIsUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserOrAdminConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(get("/").with(user("user").roles("USER"))).andExpect(status().isOk());
}
@Test
public void getWhenRoleUserOrAdminConfiguredAndRoleIsAdminThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserOrAdminConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").roles("ADMIN")))
.andExpect(status().isOk());
this.mvc.perform(get("/").with(user("user").roles("ADMIN"))).andExpect(status().isOk());
}
@Test
public void getWhenRoleUserOrAdminConfiguredAndRoleIsOtherThenRespondsWithForbidden() throws Exception {
this.spring.register(RoleUserOrAdminConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").roles("OTHER")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/").with(user("user").roles("OTHER"))).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RoleUserOrAdminConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -371,34 +359,32 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().hasAnyRole("USER", "ADMIN");
// @formatter:on
}
}
@Test
public void getWhenHasIpAddressConfiguredAndIpAddressMatchesThenRespondsWithOk() throws Exception {
this.spring.register(HasIpAddressConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(request -> {
request.setRemoteAddr("192.168.1.0");
return request;
}))
.andExpect(status().isOk());
this.mvc.perform(get("/").with(request -> {
request.setRemoteAddr("192.168.1.0");
return request;
})).andExpect(status().isOk());
}
@Test
public void getWhenHasIpAddressConfiguredAndIpAddressDoesNotMatchThenRespondsWithUnauthorized() throws Exception {
this.spring.register(HasIpAddressConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(request -> {
request.setRemoteAddr("192.168.1.1");
return request;
}))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/").with(request -> {
request.setRemoteAddr("192.168.1.1");
return request;
})).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class HasIpAddressConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -409,27 +395,26 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().hasIpAddress("192.168.1.0");
// @formatter:on
}
}
@Test
public void getWhenAnonymousConfiguredAndAnonymousUserThenRespondsWithOk() throws Exception {
this.spring.register(AnonymousConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isOk());
this.mvc.perform(get("/")).andExpect(status().isOk());
}
@Test
public void getWhenAnonymousConfiguredAndLoggedInUserThenRespondsWithForbidden() throws Exception {
this.spring.register(AnonymousConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/").with(user("user"))).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class AnonymousConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -440,27 +425,28 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().anonymous();
// @formatter:on
}
}
@Test
public void getWhenRememberMeConfiguredAndNoUserThenRespondsWithUnauthorized() throws Exception {
this.spring.register(RememberMeConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
}
@Test
public void getWhenRememberMeConfiguredAndRememberMeTokenThenRespondsWithOk() throws Exception {
this.spring.register(RememberMeConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(authentication(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER")))))
this.mvc.perform(get("/").with(authentication(
new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER")))))
.andExpect(status().isOk());
}
@EnableWebSecurity
static class RememberMeConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -482,27 +468,26 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.withUser("user").password("password").roles("USER");
// @formatter:on
}
}
@Test
public void getWhenDenyAllConfiguredAndNoUserThenRespondsWithUnauthorized() throws Exception {
this.spring.register(DenyAllConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
}
@Test
public void getWheDenyAllConfiguredAndUserLoggedInThenRespondsWithForbidden() throws Exception {
this.spring.register(DenyAllConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").roles("USER")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/").with(user("user").roles("USER"))).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class DenyAllConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -513,27 +498,28 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().denyAll();
// @formatter:on
}
}
@Test
public void getWhenNotDenyAllConfiguredAndNoUserThenRespondsWithOk() throws Exception {
this.spring.register(NotDenyAllConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isOk());
this.mvc.perform(get("/")).andExpect(status().isOk());
}
@Test
public void getWhenNotDenyAllConfiguredAndRememberMeTokenThenRespondsWithOk() throws Exception {
this.spring.register(NotDenyAllConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(authentication(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER")))))
this.mvc.perform(get("/").with(authentication(
new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER")))))
.andExpect(status().isOk());
}
@EnableWebSecurity
static class NotDenyAllConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -544,14 +530,15 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().not().denyAll();
// @formatter:on
}
}
@Test
public void getWhenFullyAuthenticatedConfiguredAndRememberMeTokenThenRespondsWithUnauthorized() throws Exception {
this.spring.register(FullyAuthenticatedConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(authentication(new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER")))))
this.mvc.perform(get("/").with(authentication(
new RememberMeAuthenticationToken("key", "user", AuthorityUtils.createAuthorityList("ROLE_USER")))))
.andExpect(status().isUnauthorized());
}
@@ -559,13 +546,12 @@ public class ExpressionUrlAuthorizationConfigurerTests {
public void getWhenFullyAuthenticatedConfiguredAndUserThenRespondsWithOk() throws Exception {
this.spring.register(FullyAuthenticatedConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(get("/").with(user("user").roles("USER"))).andExpect(status().isOk());
}
@EnableWebSecurity
static class FullyAuthenticatedConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -578,37 +564,33 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().fullyAuthenticated();
// @formatter:on
}
}
@Test
public void getWhenAccessRoleUserOrGetRequestConfiguredThenRespondsWithOk() throws Exception {
this.spring.register(AccessConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isOk());
this.mvc.perform(get("/")).andExpect(status().isOk());
}
@Test
public void postWhenAccessRoleUserOrGetRequestConfiguredAndRoleUserThenRespondsWithOk() throws Exception {
this.spring.register(AccessConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/")
.with(csrf())
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(post("/").with(csrf()).with(user("user").roles("USER"))).andExpect(status().isOk());
}
@Test
public void postWhenAccessRoleUserOrGetRequestConfiguredThenRespondsWithUnauthorized() throws Exception {
this.spring.register(AccessConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/")
.with(csrf()))
.andExpect(status().isUnauthorized());
this.mvc.perform(post("/").with(csrf())).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class AccessConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -621,19 +603,19 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.anyRequest().access("hasRole('ROLE_USER') or request.method == 'GET'");
// @formatter:on
}
}
@Test
public void authorizeRequestsWhenInvokedTwiceThenUsesOriginalConfiguration() throws Exception {
this.spring.register(InvokeTwiceDoesNotResetConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/")
.with(csrf()))
.andExpect(status().isUnauthorized());
this.mvc.perform(post("/").with(csrf())).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class InvokeTwiceDoesNotResetConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -646,6 +628,7 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.authorizeRequests();
// @formatter:on
}
}
@Test
@@ -655,6 +638,7 @@ public class ExpressionUrlAuthorizationConfigurerTests {
@EnableWebSecurity
static class AllPropertiesWorkConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
SecurityExpressionHandler<FilterInvocation> handler = new DefaultWebSecurityExpressionHandler();
@@ -672,6 +656,7 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.formLogin();
// @formatter:on
}
}
@Test
@@ -686,6 +671,7 @@ public class ExpressionUrlAuthorizationConfigurerTests {
@EnableWebSecurity
static class AuthorizedRequestsWithPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ApplicationListener<AuthorizedEvent> AL = mock(ApplicationListener.class);
@Override
@@ -708,46 +694,40 @@ public class ExpressionUrlAuthorizationConfigurerTests {
public ApplicationListener<AuthorizedEvent> applicationListener() {
return AL;
}
}
@Test
public void getWhenPermissionCheckAndRoleDoesNotMatchThenRespondsWithForbidden() throws Exception {
this.spring.register(UseBeansInExpressions.class, WildcardController.class).autowire();
this.mvc.perform(get("/admin")
.with(user("user").roles("USER")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/admin").with(user("user").roles("USER"))).andExpect(status().isForbidden());
}
@Test
public void getWhenPermissionCheckAndRoleMatchesThenRespondsWithOk() throws Exception {
this.spring.register(UseBeansInExpressions.class, WildcardController.class).autowire();
this.mvc.perform(get("/user")
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(get("/user").with(user("user").roles("USER"))).andExpect(status().isOk());
}
@Test
public void getWhenPermissionCheckAndAuthenticationNameMatchesThenRespondsWithOk() throws Exception {
this.spring.register(UseBeansInExpressions.class, WildcardController.class).autowire();
this.mvc.perform(get("/allow")
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(get("/allow").with(user("user").roles("USER"))).andExpect(status().isOk());
}
@Test
public void getWhenPermissionCheckAndAuthenticationNameDoesNotMatchThenRespondsWithForbidden() throws Exception {
this.spring.register(UseBeansInExpressions.class, WildcardController.class).autowire();
this.mvc.perform(get("/deny")
.with(user("user").roles("USER")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/deny").with(user("user").roles("USER"))).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class UseBeansInExpressions extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -766,40 +746,34 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
static class Checker {
public boolean check(Authentication authentication, String customArg) {
return authentication.getName().contains(customArg);
}
}
}
@Test
public void getWhenCustomExpressionHandlerAndRoleDoesNotMatchThenRespondsWithForbidden()
throws Exception {
public void getWhenCustomExpressionHandlerAndRoleDoesNotMatchThenRespondsWithForbidden() throws Exception {
this.spring.register(CustomExpressionRootConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/admin")
.with(user("user").roles("USER")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/admin").with(user("user").roles("USER"))).andExpect(status().isForbidden());
}
@Test
public void getWhenCustomExpressionHandlerAndRoleMatchesThenRespondsWithOk()
throws Exception {
public void getWhenCustomExpressionHandlerAndRoleMatchesThenRespondsWithOk() throws Exception {
this.spring.register(CustomExpressionRootConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/user")
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(get("/user").with(user("user").roles("USER"))).andExpect(status().isOk());
}
@Test
public void getWhenCustomExpressionHandlerAndAuthenticationNameMatchesThenRespondsWithOk()
throws Exception {
public void getWhenCustomExpressionHandlerAndAuthenticationNameMatchesThenRespondsWithOk() throws Exception {
this.spring.register(CustomExpressionRootConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/allow")
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(get("/allow").with(user("user").roles("USER"))).andExpect(status().isOk());
}
@Test
@@ -807,13 +781,12 @@ public class ExpressionUrlAuthorizationConfigurerTests {
throws Exception {
this.spring.register(CustomExpressionRootConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/deny")
.with(user("user").roles("USER")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/deny").with(user("user").roles("USER"))).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class CustomExpressionRootConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -835,14 +808,15 @@ public class ExpressionUrlAuthorizationConfigurerTests {
static class CustomExpressionHandler extends DefaultWebSecurityExpressionHandler {
@Override
protected SecurityExpressionOperations createSecurityExpressionRoot(
Authentication authentication, FilterInvocation fi) {
protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
FilterInvocation fi) {
WebSecurityExpressionRoot root = new CustomExpressionRoot(authentication, fi);
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(new AuthenticationTrustResolverImpl());
root.setRoleHierarchy(getRoleHierarchy());
return root;
}
}
static class CustomExpressionRoot extends WebSecurityExpressionRoot {
@@ -855,20 +829,22 @@ public class ExpressionUrlAuthorizationConfigurerTests {
Authentication auth = this.getAuthentication();
return auth.getName().contains(customArg);
}
}
}
//SEC-3011
// SEC-3011
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnAccessDecisionManager() {
this.spring.register(Sec3011Config.class).autowire();
verify(Sec3011Config.objectPostProcessor)
.postProcess(any(AccessDecisionManager.class));
verify(Sec3011Config.objectPostProcessor).postProcess(any(AccessDecisionManager.class));
}
@EnableWebSecurity
static class Sec3011Config extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
@@ -892,6 +868,7 @@ public class ExpressionUrlAuthorizationConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
@Test
@@ -899,8 +876,7 @@ public class ExpressionUrlAuthorizationConfigurerTests {
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/allow"))
.andExpect(status().isOk());
this.mvc.perform(get("/allow")).andExpect(status().isOk());
}
@Test
@@ -908,8 +884,7 @@ public class ExpressionUrlAuthorizationConfigurerTests {
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/deny"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/deny")).andExpect(status().isForbidden());
}
@Test
@@ -917,8 +892,7 @@ public class ExpressionUrlAuthorizationConfigurerTests {
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/allowObject"))
.andExpect(status().isOk());
this.mvc.perform(get("/allowObject")).andExpect(status().isOk());
}
@Test
@@ -926,12 +900,12 @@ public class ExpressionUrlAuthorizationConfigurerTests {
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/denyObject"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/denyObject")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class PermissionEvaluatorConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -949,7 +923,8 @@ public class ExpressionUrlAuthorizationConfigurerTests {
public PermissionEvaluator permissionEvaluator() {
return new PermissionEvaluator() {
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
public boolean hasPermission(Authentication authentication, Object targetDomainObject,
Object permission) {
return "TESTOBJ".equals(targetDomainObject) && "PERMISSION".equals(permission);
}
@@ -960,28 +935,26 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
};
}
}
@Test
public void getWhenRegisteringRoleHierarchyAndRelatedRoleAllowedThenRespondsWithOk() throws Exception {
this.spring.register(RoleHierarchyConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/allow")
.with(user("user").roles("USER")))
.andExpect(status().isOk());
this.mvc.perform(get("/allow").with(user("user").roles("USER"))).andExpect(status().isOk());
}
@Test
public void getWhenRegisteringRoleHierarchyAndNoRelatedRolesAllowedThenRespondsWithForbidden() throws Exception {
this.spring.register(RoleHierarchyConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/deny")
.with(user("user").roles("USER")))
.andExpect(status().isForbidden());
this.mvc.perform(get("/deny").with(user("user").roles("USER"))).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RoleHierarchyConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -999,10 +972,12 @@ public class ExpressionUrlAuthorizationConfigurerTests {
roleHierarchy.setHierarchy("ROLE_USER > ROLE_MEMBER");
return roleHierarchy;
}
}
@RestController
static class BasicController {
@GetMapping("/")
public void rootGet() {
}
@@ -1010,19 +985,25 @@ public class ExpressionUrlAuthorizationConfigurerTests {
@PostMapping("/")
public void rootPost() {
}
}
@RestController
static class WildcardController {
@GetMapping("/{path}")
public void wildcard(@PathVariable String path) {
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
}

View File

@@ -58,6 +58,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @since 5.1
*/
public class FormLoginConfigurerTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -66,19 +67,18 @@ public class FormLoginConfigurerTests {
@Test
public void requestCache() throws Exception {
this.spring.register(RequestCacheConfig.class,
AuthenticationTestConfiguration.class).autowire();
this.spring.register(RequestCacheConfig.class, AuthenticationTestConfiguration.class).autowire();
RequestCacheConfig config = this.spring.getContext().getBean(RequestCacheConfig.class);
this.mockMvc.perform(formLogin())
.andExpect(authenticated());
this.mockMvc.perform(formLogin()).andExpect(authenticated());
verify(config.requestCache).getRequest(any(), any());
}
@EnableWebSecurity
static class RequestCacheConfig extends WebSecurityConfigurerAdapter {
private RequestCache requestCache = mock(RequestCache.class);
@Override
@@ -90,27 +90,28 @@ public class FormLoginConfigurerTests {
.requestCache(this.requestCache);
// @formatter:on
}
}
@Test
public void requestCacheAsBean() throws Exception {
this.spring.register(RequestCacheBeanConfig.class,
AuthenticationTestConfiguration.class).autowire();
this.spring.register(RequestCacheBeanConfig.class, AuthenticationTestConfiguration.class).autowire();
RequestCache requestCache = this.spring.getContext().getBean(RequestCache.class);
this.mockMvc.perform(formLogin())
.andExpect(authenticated());
this.mockMvc.perform(formLogin()).andExpect(authenticated());
verify(requestCache).getRequest(any(), any());
}
@EnableWebSecurity
static class RequestCacheBeanConfig {
@Bean
RequestCache requestCache() {
return mock(RequestCache.class);
}
}
@Test
@@ -118,16 +119,14 @@ public class FormLoginConfigurerTests {
this.spring.register(FormLoginConfig.class).autowire();
this.mockMvc.perform(formLogin().user("username", "user").password("password", "password"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/"));
.andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@Test
public void loginWhenFormLoginConfiguredThenHasDefaultFailureUrl() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mockMvc.perform(formLogin().user("invalid"))
.andExpect(status().isFound())
this.mockMvc.perform(formLogin().user("invalid")).andExpect(status().isFound())
.andExpect(redirectedUrl("/login?error"));
}
@@ -135,38 +134,34 @@ public class FormLoginConfigurerTests {
public void loginWhenFormLoginConfiguredThenHasDefaultSuccessUrl() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(status().isFound())
.andExpect(redirectedUrl("/"));
this.mockMvc.perform(formLogin()).andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@Test
public void getLoginPageWhenFormLoginConfiguredThenNotSecured() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mockMvc.perform(get("/login"))
.andExpect(status().isFound());
this.mockMvc.perform(get("/login")).andExpect(status().isFound());
}
@Test
public void loginWhenFormLoginConfiguredThenSecured() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mockMvc.perform(post("/login"))
.andExpect(status().isForbidden());
this.mockMvc.perform(post("/login")).andExpect(status().isForbidden());
}
@Test
public void requestProtectedWhenFormLoginConfiguredThenRedirectsToLogin() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mockMvc.perform(get("/private"))
.andExpect(status().isFound())
this.mockMvc.perform(get("/private")).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/login"));
}
@EnableWebSecurity
static class FormLoginConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
// @formatter:off
@@ -196,6 +191,7 @@ public class FormLoginConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
@@ -203,16 +199,14 @@ public class FormLoginConfigurerTests {
this.spring.register(FormLoginInLambdaConfig.class).autowire();
this.mockMvc.perform(formLogin().user("username", "user").password("password", "password"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/"));
.andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@Test
public void loginWhenFormLoginDefaultsInLambdaThenHasDefaultFailureUrl() throws Exception {
this.spring.register(FormLoginInLambdaConfig.class).autowire();
this.mockMvc.perform(formLogin().user("invalid"))
.andExpect(status().isFound())
this.mockMvc.perform(formLogin().user("invalid")).andExpect(status().isFound())
.andExpect(redirectedUrl("/login?error"));
}
@@ -220,38 +214,34 @@ public class FormLoginConfigurerTests {
public void loginWhenFormLoginDefaultsInLambdaThenHasDefaultSuccessUrl() throws Exception {
this.spring.register(FormLoginInLambdaConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(status().isFound())
.andExpect(redirectedUrl("/"));
this.mockMvc.perform(formLogin()).andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@Test
public void getLoginPageWhenFormLoginDefaultsInLambdaThenNotSecured() throws Exception {
this.spring.register(FormLoginInLambdaConfig.class).autowire();
this.mockMvc.perform(get("/login"))
.andExpect(status().isOk());
this.mockMvc.perform(get("/login")).andExpect(status().isOk());
}
@Test
public void loginWhenFormLoginDefaultsInLambdaThenSecured() throws Exception {
this.spring.register(FormLoginInLambdaConfig.class).autowire();
this.mockMvc.perform(post("/login"))
.andExpect(status().isForbidden());
this.mockMvc.perform(post("/login")).andExpect(status().isForbidden());
}
@Test
public void requestProtectedWhenFormLoginDefaultsInLambdaThenRedirectsToLogin() throws Exception {
this.spring.register(FormLoginInLambdaConfig.class).autowire();
this.mockMvc.perform(get("/private"))
.andExpect(status().isFound())
this.mockMvc.perform(get("/private")).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/login"));
}
@EnableWebSecurity
static class FormLoginInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -272,37 +262,34 @@ public class FormLoginConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void getLoginPageWhenFormLoginPermitAllThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginConfigPermitAll.class).autowire();
this.mockMvc.perform(get("/login"))
.andExpect(status().isOk())
.andExpect(redirectedUrl(null));
this.mockMvc.perform(get("/login")).andExpect(status().isOk()).andExpect(redirectedUrl(null));
}
@Test
public void getLoginPageWithErrorQueryWhenFormLoginPermitAllThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginConfigPermitAll.class).autowire();
this.mockMvc.perform(get("/login?error"))
.andExpect(status().isOk())
.andExpect(redirectedUrl(null));
this.mockMvc.perform(get("/login?error")).andExpect(status().isOk()).andExpect(redirectedUrl(null));
}
@Test
public void loginWhenFormLoginPermitAllAndInvalidUserThenRedirectsToLoginPageWithError() throws Exception {
this.spring.register(FormLoginConfigPermitAll.class).autowire();
this.mockMvc.perform(formLogin().user("invalid"))
.andExpect(status().isFound())
this.mockMvc.perform(formLogin().user("invalid")).andExpect(status().isFound())
.andExpect(redirectedUrl("/login?error"));
}
@EnableWebSecurity
static class FormLoginConfigPermitAll extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -314,30 +301,28 @@ public class FormLoginConfigurerTests {
.permitAll();
// @formatter:on
}
}
@Test
public void getLoginPageWhenCustomLoginPageThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginDefaultsConfig.class).autowire();
this.mockMvc.perform(get("/authenticate"))
.andExpect(redirectedUrl(null));
this.mockMvc.perform(get("/authenticate")).andExpect(redirectedUrl(null));
}
@Test
public void getLoginPageWithErrorQueryWhenCustomLoginPageThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginDefaultsConfig.class).autowire();
this.mockMvc.perform(get("/authenticate?error"))
.andExpect(redirectedUrl(null));
this.mockMvc.perform(get("/authenticate?error")).andExpect(redirectedUrl(null));
}
@Test
public void loginWhenCustomLoginPageAndInvalidUserThenRedirectsToCustomLoginPageWithError() throws Exception {
this.spring.register(FormLoginDefaultsConfig.class).autowire();
this.mockMvc.perform(formLogin("/authenticate").user("invalid"))
.andExpect(status().isFound())
this.mockMvc.perform(formLogin("/authenticate").user("invalid")).andExpect(status().isFound())
.andExpect(redirectedUrl("/authenticate?error"));
}
@@ -345,20 +330,19 @@ public class FormLoginConfigurerTests {
public void logoutWhenCustomLoginPageThenRedirectsToCustomLoginPage() throws Exception {
this.spring.register(FormLoginDefaultsConfig.class).autowire();
this.mockMvc.perform(logout())
.andExpect(redirectedUrl("/authenticate?logout"));
this.mockMvc.perform(logout()).andExpect(redirectedUrl("/authenticate?logout"));
}
@Test
public void getLoginPageWithLogoutQueryWhenCustomLoginPageThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginDefaultsConfig.class).autowire();
this.mockMvc.perform(get("/authenticate?logout"))
.andExpect(redirectedUrl(null));
this.mockMvc.perform(get("/authenticate?logout")).andExpect(redirectedUrl(null));
}
@EnableWebSecurity
static class FormLoginDefaultsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -374,18 +358,19 @@ public class FormLoginConfigurerTests {
.permitAll();
// @formatter:on
}
}
@Test
public void getLoginPageWhenCustomLoginPageInLambdaThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginDefaultsInLambdaConfig.class).autowire();
this.mockMvc.perform(get("/authenticate"))
.andExpect(redirectedUrl(null));
this.mockMvc.perform(get("/authenticate")).andExpect(redirectedUrl(null));
}
@EnableWebSecurity
static class FormLoginDefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -402,19 +387,19 @@ public class FormLoginConfigurerTests {
.logout(LogoutConfigurer::permitAll);
// @formatter:on
}
}
@Test
public void loginWhenCustomLoginProcessingUrlThenRedirectsToHome() throws Exception {
this.spring.register(FormLoginLoginProcessingUrlConfig.class).autowire();
this.mockMvc.perform(formLogin("/loginCheck"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/"));
this.mockMvc.perform(formLogin("/loginCheck")).andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@EnableWebSecurity
static class FormLoginLoginProcessingUrlConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -445,19 +430,19 @@ public class FormLoginConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void loginWhenCustomLoginProcessingUrlInLambdaThenRedirectsToHome() throws Exception {
this.spring.register(FormLoginLoginProcessingUrlInLambdaConfig.class).autowire();
this.mockMvc.perform(formLogin("/loginCheck"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/"));
this.mockMvc.perform(formLogin("/loginCheck")).andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@EnableWebSecurity
static class FormLoginLoginProcessingUrlInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -490,6 +475,7 @@ public class FormLoginConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
@@ -498,8 +484,7 @@ public class FormLoginConfigurerTests {
when(FormLoginUsesPortMapperConfig.PORT_MAPPER.lookupHttpsPort(any())).thenReturn(9443);
this.spring.register(FormLoginUsesPortMapperConfig.class).autowire();
this.mockMvc.perform(get("http://localhost:9090"))
.andExpect(status().isFound())
this.mockMvc.perform(get("http://localhost:9090")).andExpect(status().isFound())
.andExpect(redirectedUrl("https://localhost:9443/login"));
verify(FormLoginUsesPortMapperConfig.PORT_MAPPER).lookupHttpsPort(any());
@@ -507,6 +492,7 @@ public class FormLoginConfigurerTests {
@EnableWebSecurity
static class FormLoginUsesPortMapperConfig extends WebSecurityConfigurerAdapter {
static PortMapper PORT_MAPPER;
@Override
@@ -522,23 +508,24 @@ public class FormLoginConfigurerTests {
.portMapper()
.portMapper(PORT_MAPPER);
// @formatter:on
LoginUrlAuthenticationEntryPoint authenticationEntryPoint =
(LoginUrlAuthenticationEntryPoint) http.getConfigurer(FormLoginConfigurer.class).getAuthenticationEntryPoint();
LoginUrlAuthenticationEntryPoint authenticationEntryPoint = (LoginUrlAuthenticationEntryPoint) http
.getConfigurer(FormLoginConfigurer.class).getAuthenticationEntryPoint();
authenticationEntryPoint.setForceHttps(true);
}
}
@Test
public void failureUrlWhenPermitAllAndFailureHandlerThenSecured() throws Exception {
this.spring.register(PermitAllIgnoresFailureHandlerConfig.class).autowire();
this.mockMvc.perform(get("/login?error"))
.andExpect(status().isFound())
this.mockMvc.perform(get("/login?error")).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/login"));
}
@EnableWebSecurity
static class PermitAllIgnoresFailureHandlerConfig extends WebSecurityConfigurerAdapter {
static AuthenticationFailureHandler FAILURE_HANDLER = mock(AuthenticationFailureHandler.class);
@Override
@@ -553,18 +540,19 @@ public class FormLoginConfigurerTests {
.permitAll();
// @formatter:on
}
}
@Test
public void formLoginWhenInvokedTwiceThenUsesOriginalUsernameParameter() throws Exception {
this.spring.register(DuplicateInvocationsDoesNotOverrideConfig.class).autowire();
this.mockMvc.perform(formLogin().user("custom-username", "user"))
.andExpect(authenticated());
this.mockMvc.perform(formLogin().user("custom-username", "user")).andExpect(authenticated());
}
@EnableWebSecurity
static class DuplicateInvocationsDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -584,22 +572,21 @@ public class FormLoginConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void loginWhenInvalidLoginAndFailureForwardUrlThenForwardsToFailureForwardUrl() throws Exception {
this.spring.register(FormLoginUserForwardAuthenticationSuccessAndFailureConfig.class).autowire();
this.mockMvc.perform(formLogin().user("invalid"))
.andExpect(forwardedUrl("/failure_forward_url"));
this.mockMvc.perform(formLogin().user("invalid")).andExpect(forwardedUrl("/failure_forward_url"));
}
@Test
public void loginWhenSuccessForwardUrlThenForwardsToSuccessForwardUrl() throws Exception {
this.spring.register(FormLoginUserForwardAuthenticationSuccessAndFailureConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(forwardedUrl("/success_forward_url"));
this.mockMvc.perform(formLogin()).andExpect(forwardedUrl("/success_forward_url"));
}
@EnableWebSecurity
@@ -629,6 +616,7 @@ public class FormLoginConfigurerTests {
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
@@ -645,8 +633,7 @@ public class FormLoginConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(LoginUrlAuthenticationEntryPoint.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(LoginUrlAuthenticationEntryPoint.class));
}
@Test
@@ -654,12 +641,12 @@ public class FormLoginConfigurerTests {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(ExceptionTranslationFilter.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ExceptionTranslationFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor;
@Override
@@ -676,12 +663,16 @@ public class FormLoginConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
}

View File

@@ -46,33 +46,32 @@ public class HeadersConfigurerEagerHeadersTests {
@EnableWebSecurity
public static class HeadersAtTheBeginningOfRequestConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//@ formatter:off
http
.headers()
.addObjectPostProcessor(new ObjectPostProcessor<HeaderWriterFilter>() {
@Override
public HeaderWriterFilter postProcess(HeaderWriterFilter filter) {
filter.setShouldWriteHeadersEagerly(true);
return filter;
}
});
//@ formatter:on
// @ formatter:off
http.headers().addObjectPostProcessor(new ObjectPostProcessor<HeaderWriterFilter>() {
@Override
public HeaderWriterFilter postProcess(HeaderWriterFilter filter) {
filter.setShouldWriteHeadersEagerly(true);
return filter;
}
});
// @ formatter:on
}
}
@Test
public void requestWhenHeadersEagerlyConfiguredThenHeadersAreWritten() throws Exception {
this.spring.register(HeadersAtTheBeginningOfRequestConfig.class).autowire();
this.mvc.perform(get("/").secure(true))
.andExpect(header().string("X-Content-Type-Options", "nosniff"))
this.mvc.perform(get("/").secure(true)).andExpect(header().string("X-Content-Type-Options", "nosniff"))
.andExpect(header().string("X-Frame-Options", "DENY"))
.andExpect(header().string("Strict-Transport-Security", "max-age=31536000 ; includeSubDomains"))
.andExpect(header().string(CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string(EXPIRES, "0"))
.andExpect(header().string(PRAGMA, "no-cache"))
.andExpect(header().string(EXPIRES, "0")).andExpect(header().string(PRAGMA, "no-cache"))
.andExpect(header().string("X-XSS-Protection", "1; mode=block"));
}
}

View File

@@ -65,12 +65,12 @@ public class HeadersConfigurerTests {
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.X_CONTENT_TYPE_OPTIONS, "nosniff"))
.andExpect(header().string(HttpHeaders.X_FRAME_OPTIONS, XFrameOptionsMode.DENY.name()))
.andExpect(header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains"))
.andExpect(
header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains"))
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string(HttpHeaders.EXPIRES, "0"))
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache"))
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block"))
.andReturn();
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactlyInAnyOrder(
HttpHeaders.X_CONTENT_TYPE_OPTIONS, HttpHeaders.X_FRAME_OPTIONS, HttpHeaders.STRICT_TRANSPORT_SECURITY,
HttpHeaders.CACHE_CONTROL, HttpHeaders.EXPIRES, HttpHeaders.PRAGMA, HttpHeaders.X_XSS_PROTECTION);
@@ -86,6 +86,7 @@ public class HeadersConfigurerTests {
.headers();
// @formatter:on
}
}
@Test
@@ -95,12 +96,12 @@ public class HeadersConfigurerTests {
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.X_CONTENT_TYPE_OPTIONS, "nosniff"))
.andExpect(header().string(HttpHeaders.X_FRAME_OPTIONS, XFrameOptionsMode.DENY.name()))
.andExpect(header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains"))
.andExpect(
header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains"))
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string(HttpHeaders.EXPIRES, "0"))
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache"))
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block"))
.andReturn();
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactlyInAnyOrder(
HttpHeaders.X_CONTENT_TYPE_OPTIONS, HttpHeaders.X_FRAME_OPTIONS, HttpHeaders.STRICT_TRANSPORT_SECURITY,
HttpHeaders.CACHE_CONTROL, HttpHeaders.EXPIRES, HttpHeaders.PRAGMA, HttpHeaders.X_XSS_PROTECTION);
@@ -116,6 +117,7 @@ public class HeadersConfigurerTests {
.headers(withDefaults());
// @formatter:on
}
}
@Test
@@ -124,8 +126,7 @@ public class HeadersConfigurerTests {
this.spring.register(ContentTypeOptionsConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/"))
.andExpect(header().string(HttpHeaders.X_CONTENT_TYPE_OPTIONS, "nosniff"))
.andReturn();
.andExpect(header().string(HttpHeaders.X_CONTENT_TYPE_OPTIONS, "nosniff")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.X_CONTENT_TYPE_OPTIONS);
}
@@ -141,16 +142,15 @@ public class HeadersConfigurerTests {
.contentTypeOptions();
// @formatter:on
}
}
@Test
public void getWhenOnlyContentTypeConfiguredInLambdaThenOnlyContentTypeHeaderInResponse()
throws Exception {
public void getWhenOnlyContentTypeConfiguredInLambdaThenOnlyContentTypeHeaderInResponse() throws Exception {
this.spring.register(ContentTypeOptionsInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/"))
.andExpect(header().string(HttpHeaders.X_CONTENT_TYPE_OPTIONS, "nosniff"))
.andReturn();
.andExpect(header().string(HttpHeaders.X_CONTENT_TYPE_OPTIONS, "nosniff")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.X_CONTENT_TYPE_OPTIONS);
}
@@ -168,6 +168,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -176,8 +177,7 @@ public class HeadersConfigurerTests {
this.spring.register(FrameOptionsConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/"))
.andExpect(header().string(HttpHeaders.X_FRAME_OPTIONS, XFrameOptionsMode.DENY.name()))
.andReturn();
.andExpect(header().string(HttpHeaders.X_FRAME_OPTIONS, XFrameOptionsMode.DENY.name())).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.X_FRAME_OPTIONS);
}
@@ -193,6 +193,7 @@ public class HeadersConfigurerTests {
.frameOptions();
// @formatter:on
}
}
@Test
@@ -201,7 +202,8 @@ public class HeadersConfigurerTests {
this.spring.register(HstsConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains"))
.andExpect(
header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains"))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.STRICT_TRANSPORT_SECURITY);
}
@@ -218,6 +220,7 @@ public class HeadersConfigurerTests {
.httpStrictTransportSecurity();
// @formatter:on
}
}
@Test
@@ -228,8 +231,7 @@ public class HeadersConfigurerTests {
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string(HttpHeaders.EXPIRES, "0"))
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache"))
.andReturn();
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactlyInAnyOrder(HttpHeaders.CACHE_CONTROL,
HttpHeaders.EXPIRES, HttpHeaders.PRAGMA);
}
@@ -246,6 +248,7 @@ public class HeadersConfigurerTests {
.cacheControl();
// @formatter:on
}
}
@Test
@@ -256,8 +259,7 @@ public class HeadersConfigurerTests {
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, max-age=0, must-revalidate"))
.andExpect(header().string(HttpHeaders.EXPIRES, "0"))
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache"))
.andReturn();
.andExpect(header().string(HttpHeaders.PRAGMA, "no-cache")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactlyInAnyOrder(HttpHeaders.CACHE_CONTROL,
HttpHeaders.EXPIRES, HttpHeaders.PRAGMA);
}
@@ -276,6 +278,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -284,8 +287,7 @@ public class HeadersConfigurerTests {
this.spring.register(XssProtectionConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block"))
.andReturn();
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.X_XSS_PROTECTION);
}
@@ -301,16 +303,15 @@ public class HeadersConfigurerTests {
.xssProtection();
// @formatter:on
}
}
@Test
public void getWhenOnlyXssProtectionConfiguredInLambdaThenOnlyXssProtectionHeaderInResponse()
throws Exception {
public void getWhenOnlyXssProtectionConfiguredInLambdaThenOnlyXssProtectionHeaderInResponse() throws Exception {
this.spring.register(XssProtectionInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block"))
.andReturn();
.andExpect(header().string(HttpHeaders.X_XSS_PROTECTION, "1; mode=block")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.X_XSS_PROTECTION);
}
@@ -328,6 +329,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -350,6 +352,7 @@ public class HeadersConfigurerTests {
.frameOptions().sameOrigin();
// @formatter:on
}
}
@Test
@@ -375,14 +378,14 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
public void getWhenHeaderDefaultsDisabledAndPublicHpkpWithNoPinThenNoHeadersInResponse() throws Exception {
this.spring.register(HpkpConfigNoPins.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/"))
.andReturn();
MvcResult mvcResult = this.mvc.perform(get("/")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).isEmpty();
}
@@ -398,11 +401,11 @@ public class HeadersConfigurerTests {
.httpPublicKeyPinning();
// @formatter:on
}
}
@Test
public void getWhenSecureRequestAndHpkpWithPinThenPublicKeyPinsReportOnlyHeaderInResponse()
throws Exception {
public void getWhenSecureRequestAndHpkpWithPinThenPublicKeyPinsReportOnlyHeaderInResponse() throws Exception {
this.spring.register(HpkpConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
@@ -413,12 +416,10 @@ public class HeadersConfigurerTests {
}
@Test
public void getWhenInsecureRequestHeaderDefaultsDisabledAndHpkpWithPinThenNoHeadersInResponse()
throws Exception {
public void getWhenInsecureRequestHeaderDefaultsDisabledAndHpkpWithPinThenNoHeadersInResponse() throws Exception {
this.spring.register(HpkpConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/"))
.andReturn();
MvcResult mvcResult = this.mvc.perform(get("/")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).isEmpty();
}
@@ -435,6 +436,7 @@ public class HeadersConfigurerTests {
.addSha256Pins("d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=");
// @formatter:on
}
}
@Test
@@ -442,9 +444,9 @@ public class HeadersConfigurerTests {
throws Exception {
this.spring.register(HpkpConfigWithPins.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\""))
MvcResult mvcResult = this.mvc.perform(get("/").secure(true)).andExpect(header().string(
HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\""))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY);
}
@@ -466,6 +468,7 @@ public class HeadersConfigurerTests {
.withPins(pins);
// @formatter:on
}
}
@Test
@@ -493,6 +496,7 @@ public class HeadersConfigurerTests {
.maxAgeInSeconds(604800);
// @formatter:on
}
}
@Test
@@ -520,6 +524,7 @@ public class HeadersConfigurerTests {
.reportOnly(false);
// @formatter:on
}
}
@Test
@@ -527,9 +532,9 @@ public class HeadersConfigurerTests {
throws Exception {
this.spring.register(HpkpConfigIncludeSubDomains.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; includeSubDomains"))
MvcResult mvcResult = this.mvc.perform(get("/").secure(true)).andExpect(header().string(
HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; includeSubDomains"))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY);
}
@@ -548,15 +553,16 @@ public class HeadersConfigurerTests {
.includeSubDomains(true);
// @formatter:on
}
}
@Test
public void getWhenHpkpWithReportUriThenPublicKeyPinsReportOnlyHeaderWithReportUriInResponse() throws Exception {
this.spring.register(HpkpConfigWithReportURI.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; report-uri=\"https://example.net/pkp-report\""))
MvcResult mvcResult = this.mvc.perform(get("/").secure(true)).andExpect(header().string(
HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; report-uri=\"https://example.net/pkp-report\""))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY);
}
@@ -575,6 +581,7 @@ public class HeadersConfigurerTests {
.reportUri(new URI("https://example.net/pkp-report"));
// @formatter:on
}
}
@Test
@@ -582,9 +589,9 @@ public class HeadersConfigurerTests {
throws Exception {
this.spring.register(HpkpConfigWithReportURIAsString.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; report-uri=\"https://example.net/pkp-report\""))
MvcResult mvcResult = this.mvc.perform(get("/").secure(true)).andExpect(header().string(
HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; report-uri=\"https://example.net/pkp-report\""))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY);
}
@@ -603,6 +610,7 @@ public class HeadersConfigurerTests {
.reportUri("https://example.net/pkp-report");
// @formatter:on
}
}
@Test
@@ -610,9 +618,9 @@ public class HeadersConfigurerTests {
throws Exception {
this.spring.register(HpkpWithReportUriInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; report-uri=\"https://example.net/pkp-report\""))
MvcResult mvcResult = this.mvc.perform(get("/").secure(true)).andExpect(header().string(
HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY,
"max-age=5184000 ; pin-sha256=\"d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM=\" ; report-uri=\"https://example.net/pkp-report\""))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.PUBLIC_KEY_PINS_REPORT_ONLY);
}
@@ -635,6 +643,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -642,8 +651,7 @@ public class HeadersConfigurerTests {
this.spring.register(ContentSecurityPolicyDefaultConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.CONTENT_SECURITY_POLICY, "default-src 'self'"))
.andReturn();
.andExpect(header().string(HttpHeaders.CONTENT_SECURITY_POLICY, "default-src 'self'")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.CONTENT_SECURITY_POLICY);
}
@@ -659,17 +667,20 @@ public class HeadersConfigurerTests {
.contentSecurityPolicy("default-src 'self'");
// @formatter:on
}
}
@Test
public void getWhenContentSecurityPolicyWithReportOnlyThenContentSecurityPolicyReportOnlyHeaderInResponse() throws Exception {
public void getWhenContentSecurityPolicyWithReportOnlyThenContentSecurityPolicyReportOnlyHeaderInResponse()
throws Exception {
this.spring.register(ContentSecurityPolicyReportOnlyConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.CONTENT_SECURITY_POLICY_REPORT_ONLY,
"default-src 'self'; script-src trustedscripts.example.com"))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.CONTENT_SECURITY_POLICY_REPORT_ONLY);
assertThat(mvcResult.getResponse().getHeaderNames())
.containsExactly(HttpHeaders.CONTENT_SECURITY_POLICY_REPORT_ONLY);
}
@EnableWebSecurity
@@ -685,6 +696,7 @@ public class HeadersConfigurerTests {
.reportOnly();
// @formatter:on
}
}
@Test
@@ -696,7 +708,8 @@ public class HeadersConfigurerTests {
.andExpect(header().string(HttpHeaders.CONTENT_SECURITY_POLICY_REPORT_ONLY,
"default-src 'self'; script-src trustedscripts.example.com"))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.CONTENT_SECURITY_POLICY_REPORT_ONLY);
assertThat(mvcResult.getResponse().getHeaderNames())
.containsExactly(HttpHeaders.CONTENT_SECURITY_POLICY_REPORT_ONLY);
}
@EnableWebSecurity
@@ -717,13 +730,13 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
public void configureWhenContentSecurityPolicyEmptyThenException() {
assertThatThrownBy(() -> this.spring.register(ContentSecurityPolicyInvalidConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
@@ -738,13 +751,13 @@ public class HeadersConfigurerTests {
.contentSecurityPolicy("");
// @formatter:on
}
}
@Test
public void configureWhenContentSecurityPolicyEmptyInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(ContentSecurityPolicyInvalidInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
@@ -763,6 +776,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -770,9 +784,7 @@ public class HeadersConfigurerTests {
this.spring.register(ContentSecurityPolicyNoDirectivesInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.CONTENT_SECURITY_POLICY,
"default-src 'self'"))
.andReturn();
.andExpect(header().string(HttpHeaders.CONTENT_SECURITY_POLICY, "default-src 'self'")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.CONTENT_SECURITY_POLICY);
}
@@ -790,6 +802,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -797,8 +810,7 @@ public class HeadersConfigurerTests {
this.spring.register(ReferrerPolicyDefaultConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string("Referrer-Policy", ReferrerPolicy.NO_REFERRER.getPolicy()))
.andReturn();
.andExpect(header().string("Referrer-Policy", ReferrerPolicy.NO_REFERRER.getPolicy())).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly("Referrer-Policy");
}
@@ -814,6 +826,7 @@ public class HeadersConfigurerTests {
.referrerPolicy();
// @formatter:on
}
}
@Test
@@ -821,8 +834,7 @@ public class HeadersConfigurerTests {
this.spring.register(ReferrerPolicyDefaultInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string("Referrer-Policy", ReferrerPolicy.NO_REFERRER.getPolicy()))
.andReturn();
.andExpect(header().string("Referrer-Policy", ReferrerPolicy.NO_REFERRER.getPolicy())).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly("Referrer-Policy");
}
@@ -840,6 +852,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -848,8 +861,7 @@ public class HeadersConfigurerTests {
this.spring.register(ReferrerPolicyCustomConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string("Referrer-Policy", ReferrerPolicy.SAME_ORIGIN.getPolicy()))
.andReturn();
.andExpect(header().string("Referrer-Policy", ReferrerPolicy.SAME_ORIGIN.getPolicy())).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly("Referrer-Policy");
}
@@ -865,6 +877,7 @@ public class HeadersConfigurerTests {
.referrerPolicy(ReferrerPolicy.SAME_ORIGIN);
// @formatter:on
}
}
@Test
@@ -872,8 +885,7 @@ public class HeadersConfigurerTests {
this.spring.register(ReferrerPolicyCustomInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string("Referrer-Policy", ReferrerPolicy.SAME_ORIGIN.getPolicy()))
.andReturn();
.andExpect(header().string("Referrer-Policy", ReferrerPolicy.SAME_ORIGIN.getPolicy())).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly("Referrer-Policy");
}
@@ -893,6 +905,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -900,8 +913,7 @@ public class HeadersConfigurerTests {
this.spring.register(FeaturePolicyConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string("Feature-Policy", "geolocation 'self'"))
.andReturn();
.andExpect(header().string("Feature-Policy", "geolocation 'self'")).andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly("Feature-Policy");
}
@@ -917,13 +929,13 @@ public class HeadersConfigurerTests {
.featurePolicy("geolocation 'self'");
// @formatter:on
}
}
@Test
public void configureWhenFeaturePolicyEmptyThenException() {
assertThatThrownBy(() -> this.spring.register(FeaturePolicyInvalidConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
@@ -938,6 +950,7 @@ public class HeadersConfigurerTests {
.featurePolicy("");
// @formatter:on
}
}
@Test
@@ -945,9 +958,8 @@ public class HeadersConfigurerTests {
throws Exception {
this.spring.register(HstsWithPreloadConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY,
"max-age=31536000 ; includeSubDomains ; preload"))
MvcResult mvcResult = this.mvc.perform(get("/").secure(true)).andExpect(header()
.string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains ; preload"))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.STRICT_TRANSPORT_SECURITY);
}
@@ -965,6 +977,7 @@ public class HeadersConfigurerTests {
.preload(true);
// @formatter:on
}
}
@Test
@@ -972,9 +985,8 @@ public class HeadersConfigurerTests {
throws Exception {
this.spring.register(HstsWithPreloadInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/").secure(true))
.andExpect(header().string(HttpHeaders.STRICT_TRANSPORT_SECURITY,
"max-age=31536000 ; includeSubDomains ; preload"))
MvcResult mvcResult = this.mvc.perform(get("/").secure(true)).andExpect(header()
.string(HttpHeaders.STRICT_TRANSPORT_SECURITY, "max-age=31536000 ; includeSubDomains ; preload"))
.andReturn();
assertThat(mvcResult.getResponse().getHeaderNames()).containsExactly(HttpHeaders.STRICT_TRANSPORT_SECURITY);
}
@@ -993,5 +1005,7 @@ public class HeadersConfigurerTests {
);
// @formatter:on
}
}
}

View File

@@ -62,12 +62,12 @@ public class HttpBasicConfigurerTests {
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnBasicAuthenticationFilter() {
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(BasicAuthenticationFilter.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(BasicAuthenticationFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
@@ -82,26 +82,29 @@ public class HttpBasicConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@Test
public void httpBasicWhenUsingDefaultsInLambdaThenResponseIncludesBasicChallenge() throws Exception {
this.spring.register(DefaultsLambdaEntryPointConfig.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized())
this.mvc.perform(get("/")).andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
}
@EnableWebSecurity
static class DefaultsLambdaEntryPointConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -121,20 +124,21 @@ public class HttpBasicConfigurerTests {
.inMemoryAuthentication();
// @formatter:on
}
}
//SEC-2198
// SEC-2198
@Test
public void httpBasicWhenUsingDefaultsThenResponseIncludesBasicChallenge() throws Exception {
this.spring.register(DefaultsEntryPointConfig.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized())
this.mvc.perform(get("/")).andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
}
@EnableWebSecurity
static class DefaultsEntryPointConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -153,6 +157,7 @@ public class HttpBasicConfigurerTests {
.inMemoryAuthentication();
// @formatter:on
}
}
@Test
@@ -161,14 +166,13 @@ public class HttpBasicConfigurerTests {
this.mvc.perform(get("/"));
verify(CustomAuthenticationEntryPointConfig.ENTRY_POINT)
.commence(any(HttpServletRequest.class),
any(HttpServletResponse.class),
any(AuthenticationException.class));
verify(CustomAuthenticationEntryPointConfig.ENTRY_POINT).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@EnableWebSecurity
static class CustomAuthenticationEntryPointConfig extends WebSecurityConfigurerAdapter {
static AuthenticationEntryPoint ENTRY_POINT = mock(AuthenticationEntryPoint.class);
@Override
@@ -190,6 +194,7 @@ public class HttpBasicConfigurerTests {
.inMemoryAuthentication();
// @formatter:on
}
}
@Test
@@ -198,14 +203,13 @@ public class HttpBasicConfigurerTests {
this.mvc.perform(get("/"));
verify(DuplicateDoesNotOverrideConfig.ENTRY_POINT)
.commence(any(HttpServletRequest.class),
any(HttpServletResponse.class),
any(AuthenticationException.class));
verify(DuplicateDoesNotOverrideConfig.ENTRY_POINT).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
static AuthenticationEntryPoint ENTRY_POINT = mock(AuthenticationEntryPoint.class);
@Override
@@ -229,16 +233,15 @@ public class HttpBasicConfigurerTests {
.inMemoryAuthentication();
// @formatter:on
}
}
//SEC-3019
// SEC-3019
@Test
public void httpBasicWhenRememberMeConfiguredThenSetsRememberMeCookie() throws Exception {
this.spring.register(BasicUsesRememberMeConfig.class).autowire();
this.mvc.perform(get("/")
.with(httpBasic("user", "password"))
.param("remember-me", "true"))
this.mvc.perform(get("/").with(httpBasic("user", "password")).param("remember-me", "true"))
.andExpect(cookie().exists("remember-me"));
}
@@ -259,7 +262,7 @@ public class HttpBasicConfigurerTests {
@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(
// @formatter:off
// @formatter:off
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
@@ -268,5 +271,7 @@ public class HttpBasicConfigurerTests {
// @formatter:on
);
}
}
}

View File

@@ -40,10 +40,13 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
*
*/
public class HttpSecurityAntMatchersTests {
AnnotationConfigWebApplicationContext context;
MockHttpServletRequest request;
MockHttpServletResponse response;
MockFilterChain chain;
@Autowired
@@ -77,6 +80,7 @@ public class HttpSecurityAntMatchersTests {
@EnableWebSecurity
@Configuration
static class AntMatchersNoPatternsConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -95,6 +99,7 @@ public class HttpSecurityAntMatchersTests {
.inMemoryAuthentication();
// @formatter:on
}
}
// SEC-3135
@@ -111,6 +116,7 @@ public class HttpSecurityAntMatchersTests {
@EnableWebSecurity
@Configuration
static class AntMatchersEmptyPatternsConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -130,6 +136,7 @@ public class HttpSecurityAntMatchersTests {
.inMemoryAuthentication();
// @formatter:on
}
}
public void loadConfig(Class<?>... configs) {
@@ -140,5 +147,4 @@ public class HttpSecurityAntMatchersTests {
context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@@ -41,10 +41,13 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
*
*/
public class HttpSecurityLogoutTests {
AnnotationConfigWebApplicationContext context;
MockHttpServletRequest request;
MockHttpServletResponse response;
MockFilterChain chain;
@Autowired
@@ -72,7 +75,8 @@ public class HttpSecurityLogoutTests {
SecurityContext currentContext = SecurityContextHolder.createEmptyContext();
currentContext.setAuthentication(new TestingAuthenticationToken("user", "password", "ROLE_USER"));
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, currentContext);
request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
currentContext);
request.setMethod("POST");
request.setServletPath("/logout");
@@ -84,6 +88,7 @@ public class HttpSecurityLogoutTests {
@EnableWebSecurity
@Configuration
static class ClearAuthenticationFalseConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -100,6 +105,7 @@ public class HttpSecurityLogoutTests {
.inMemoryAuthentication();
// @formatter:on
}
}
public void loadConfig(Class<?>... configs) {
@@ -110,5 +116,4 @@ public class HttpSecurityLogoutTests {
context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@@ -47,10 +47,13 @@ import static org.springframework.security.config.Customizer.withDefaults;
*
*/
public class HttpSecurityRequestMatchersTests {
AnnotationConfigWebApplicationContext context;
MockHttpServletRequest request;
MockHttpServletResponse response;
MockFilterChain chain;
@Autowired
@@ -78,24 +81,21 @@ public class HttpSecurityRequestMatchersTests {
this.request.setServletPath("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@Test
@@ -109,6 +109,7 @@ public class HttpSecurityRequestMatchersTests {
@Configuration
@EnableWebMvc
static class MvcMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -130,11 +131,14 @@ public class HttpSecurityRequestMatchersTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -144,30 +148,28 @@ public class HttpSecurityRequestMatchersTests {
this.request.setServletPath("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class RequestMatchersMvcMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -191,11 +193,14 @@ public class HttpSecurityRequestMatchersTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -205,30 +210,28 @@ public class HttpSecurityRequestMatchersTests {
this.request.setServletPath("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class RequestMatchersMvcMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -247,11 +250,14 @@ public class HttpSecurityRequestMatchersTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -262,8 +268,7 @@ public class HttpSecurityRequestMatchersTests {
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
@@ -286,8 +291,8 @@ public class HttpSecurityRequestMatchersTests {
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class RequestMatchersMvcMatcherServeltPathConfig
extends WebSecurityConfigurerAdapter {
static class RequestMatchersMvcMatcherServeltPathConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -312,11 +317,14 @@ public class HttpSecurityRequestMatchersTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
@@ -327,8 +335,7 @@ public class HttpSecurityRequestMatchersTests {
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus())
.isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
@@ -351,8 +358,8 @@ public class HttpSecurityRequestMatchersTests {
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class RequestMatchersMvcMatcherServletPathInLambdaConfig
extends WebSecurityConfigurerAdapter {
static class RequestMatchersMvcMatcherServletPathInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -372,19 +379,24 @@ public class HttpSecurityRequestMatchersTests {
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Configuration
static class LegacyMvcMatchingConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(true);
}
}
public void loadConfig(Class<?>... configs) {
@@ -395,4 +407,5 @@ public class HttpSecurityRequestMatchersTests {
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@@ -59,9 +59,9 @@ public class Issue55Tests {
assertThat(filter.getAuthenticationManager().authenticate(token)).isEqualTo(CustomAuthenticationManager.RESULT);
}
@EnableWebSecurity
static class WebSecurityConfigurerAdapterDefaultsAuthManagerConfig {
@Component
public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter {
@@ -73,19 +73,24 @@ public class Issue55Tests {
.anyRequest().hasRole("USER");
// @formatter:on
}
}
@Configuration
public static class AuthenticationManagerConfiguration {
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return new CustomAuthenticationManager();
}
}
}
@Test
public void multiHttpWebSecurityConfigurerAdapterDefaultsToAutowired() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
public void multiHttpWebSecurityConfigurerAdapterDefaultsToAutowired()
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this");
this.spring.register(MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig.class);
this.spring.getContext().getBean(FilterChainProxy.class);
@@ -93,15 +98,19 @@ public class Issue55Tests {
FilterSecurityInterceptor filter = (FilterSecurityInterceptor) findFilter(FilterSecurityInterceptor.class, 0);
assertThat(filter.getAuthenticationManager().authenticate(token)).isEqualTo(CustomAuthenticationManager.RESULT);
FilterSecurityInterceptor secondFilter = (FilterSecurityInterceptor) findFilter(FilterSecurityInterceptor.class, 1);
assertThat(secondFilter.getAuthenticationManager().authenticate(token)).isEqualTo(CustomAuthenticationManager.RESULT);
FilterSecurityInterceptor secondFilter = (FilterSecurityInterceptor) findFilter(FilterSecurityInterceptor.class,
1);
assertThat(secondFilter.getAuthenticationManager().authenticate(token))
.isEqualTo(CustomAuthenticationManager.RESULT);
}
@EnableWebSecurity
static class MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig {
@Component
@Order(1)
public static class ApiWebSecurityAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -110,10 +119,12 @@ public class Issue55Tests {
.anyRequest().hasRole("USER");
// @formatter:on
}
}
@Component
public static class WebSecurityAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -122,23 +133,29 @@ public class Issue55Tests {
.anyRequest().hasRole("USER");
// @formatter:on
}
}
@Configuration
public static class AuthenticationManagerConfiguration {
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return new CustomAuthenticationManager();
}
}
}
static class CustomAuthenticationManager implements AuthenticationManager {
static Authentication RESULT = new TestingAuthenticationToken("test", "this", "ROLE_USER");
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
return RESULT;
}
}
Filter findFilter(Class<?> filter, int index) {
@@ -154,4 +171,5 @@ public class Issue55Tests {
SecurityFilterChain filterChain(int index) {
return this.spring.getContext().getBean(FilterChainProxy.class).getFilterChains().get(index);
}
}

View File

@@ -76,6 +76,7 @@ public class JeeConfigurerTests {
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor;
@Override
@@ -90,13 +91,16 @@ public class JeeConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@Test
@@ -105,18 +109,16 @@ public class JeeConfigurerTests {
Principal user = mock(Principal.class);
when(user.getName()).thenReturn("user");
this.mvc.perform(get("/")
.principal(user)
.with(request -> {
request.addUserRole("ROLE_ADMIN");
request.addUserRole("ROLE_USER");
return request;
}))
.andExpect(authenticated().withRoles("USER"));
this.mvc.perform(get("/").principal(user).with(request -> {
request.addUserRole("ROLE_ADMIN");
request.addUserRole("ROLE_USER");
return request;
})).andExpect(authenticated().withRoles("USER"));
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -127,6 +129,7 @@ public class JeeConfigurerTests {
.jee();
// @formatter:on
}
}
@Test
@@ -135,18 +138,16 @@ public class JeeConfigurerTests {
Principal user = mock(Principal.class);
when(user.getName()).thenReturn("user");
this.mvc.perform(get("/")
.principal(user)
.with(request -> {
request.addUserRole("ROLE_ADMIN");
request.addUserRole("ROLE_USER");
return request;
}))
.andExpect(authenticated().withRoles("USER"));
this.mvc.perform(get("/").principal(user).with(request -> {
request.addUserRole("ROLE_ADMIN");
request.addUserRole("ROLE_USER");
return request;
})).andExpect(authenticated().withRoles("USER"));
}
@EnableWebSecurity
public static class JeeMappableRolesConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -161,6 +162,7 @@ public class JeeConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -169,14 +171,11 @@ public class JeeConfigurerTests {
Principal user = mock(Principal.class);
when(user.getName()).thenReturn("user");
this.mvc.perform(get("/")
.principal(user)
.with(request -> {
request.addUserRole("ROLE_ADMIN");
request.addUserRole("ROLE_USER");
return request;
}))
.andExpect(authenticated().withAuthorities(AuthorityUtils.createAuthorityList("ROLE_USER")));
this.mvc.perform(get("/").principal(user).with(request -> {
request.addUserRole("ROLE_ADMIN");
request.addUserRole("ROLE_USER");
return request;
})).andExpect(authenticated().withAuthorities(AuthorityUtils.createAuthorityList("ROLE_USER")));
}
@EnableWebSecurity
@@ -196,6 +195,7 @@ public class JeeConfigurerTests {
);
// @formatter:on
}
}
@Test
@@ -209,20 +209,18 @@ public class JeeConfigurerTests {
when(JeeCustomAuthenticatedUserDetailsServiceConfig.authenticationUserDetailsService.loadUserDetails(any()))
.thenReturn(userDetails);
this.mvc.perform(get("/")
.principal(user)
.with(request -> {
request.addUserRole("ROLE_ADMIN");
request.addUserRole("ROLE_USER");
return request;
}))
.andExpect(authenticated().withRoles("USER"));
this.mvc.perform(get("/").principal(user).with(request -> {
request.addUserRole("ROLE_ADMIN");
request.addUserRole("ROLE_USER");
return request;
})).andExpect(authenticated().withRoles("USER"));
}
@EnableWebSecurity
public static class JeeCustomAuthenticatedUserDetailsServiceConfig extends WebSecurityConfigurerAdapter {
static AuthenticationUserDetailsService authenticationUserDetailsService =
mock(AuthenticationUserDetailsService.class);
static AuthenticationUserDetailsService authenticationUserDetailsService = mock(
AuthenticationUserDetailsService.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -238,5 +236,7 @@ public class JeeConfigurerTests {
);
// @formatter:on
}
}
}

View File

@@ -43,8 +43,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
/**
*
* Tests for {@link HeaderWriterLogoutHandler} that passing {@link ClearSiteDataHeaderWriter}
* implementation.
* Tests for {@link HeaderWriterLogoutHandler} that passing
* {@link ClearSiteDataHeaderWriter} implementation.
*
* @author Rafiullah Hamedy
*
@@ -55,8 +55,7 @@ public class LogoutConfigurerClearSiteDataTests {
private static final String CLEAR_SITE_DATA_HEADER = "Clear-Site-Data";
private static final ClearSiteDataHeaderWriter.Directive[] SOURCE =
{ CACHE, COOKIES, STORAGE, EXECUTION_CONTEXTS };
private static final ClearSiteDataHeaderWriter.Directive[] SOURCE = { CACHE, COOKIES, STORAGE, EXECUTION_CONTEXTS };
private static final String HEADER_VALUE = "\"cache\", \"cookies\", \"storage\", \"executionContexts\"";
@@ -72,7 +71,7 @@ public class LogoutConfigurerClearSiteDataTests {
this.spring.register(HttpLogoutConfig.class).autowire();
this.mvc.perform(get("/logout").secure(true).with(csrf()))
.andExpect(header().doesNotExist(CLEAR_SITE_DATA_HEADER));
.andExpect(header().doesNotExist(CLEAR_SITE_DATA_HEADER));
}
@Test
@@ -80,8 +79,7 @@ public class LogoutConfigurerClearSiteDataTests {
public void logoutWhenRequestTypePostAndNotSecureThenHeaderNotPresent() throws Exception {
this.spring.register(HttpLogoutConfig.class).autowire();
this.mvc.perform(post("/logout").with(csrf()))
.andExpect(header().doesNotExist(CLEAR_SITE_DATA_HEADER));
this.mvc.perform(post("/logout").with(csrf())).andExpect(header().doesNotExist(CLEAR_SITE_DATA_HEADER));
}
@Test
@@ -90,11 +88,12 @@ public class LogoutConfigurerClearSiteDataTests {
this.spring.register(HttpLogoutConfig.class).autowire();
this.mvc.perform(post("/logout").secure(true).with(csrf()))
.andExpect(header().stringValues(CLEAR_SITE_DATA_HEADER, HEADER_VALUE));
.andExpect(header().stringValues(CLEAR_SITE_DATA_HEADER, HEADER_VALUE));
}
@EnableWebSecurity
static class HttpLogoutConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -103,5 +102,7 @@ public class LogoutConfigurerClearSiteDataTests {
.addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(SOURCE)));
// @formatter:on
}
}
}

View File

@@ -66,12 +66,12 @@ public class LogoutConfigurerTests {
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullLogoutHandlerThenException() {
assertThatThrownBy(() -> this.spring.register(NullLogoutSuccessHandlerConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutSuccessHandlerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -80,17 +80,18 @@ public class LogoutConfigurerTests {
.defaultLogoutSuccessHandlerFor(null, mock(RequestMatcher.class));
// @formatter:on
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullLogoutHandlerInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullLogoutSuccessHandlerInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutSuccessHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -100,17 +101,18 @@ public class LogoutConfigurerTests {
);
// @formatter:on
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullMatcherThenException() {
assertThatThrownBy(() -> this.spring.register(NullMatcherConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -119,17 +121,18 @@ public class LogoutConfigurerTests {
.defaultLogoutSuccessHandlerFor(mock(LogoutSuccessHandler.class), null);
// @formatter:on
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullMatcherInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullMatcherInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -139,18 +142,19 @@ public class LogoutConfigurerTests {
);
// @formatter:on
}
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnLogoutFilter() {
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(LogoutFilter.class));
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(LogoutFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
@@ -165,27 +169,29 @@ public class LogoutConfigurerTests {
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@Test
public void logoutWhenInvokedTwiceThenUsesOriginalLogoutUrl() throws Exception {
this.spring.register(DuplicateDoesNotOverrideConfig.class).autowire();
this.mvc.perform(post("/custom/logout")
.with(csrf()))
.andExpect(status().isFound())
this.mvc.perform(post("/custom/logout").with(csrf())).andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -204,6 +210,7 @@ public class LogoutConfigurerTests {
.inMemoryAuthentication();
// @formatter:on
}
}
// SEC-2311
@@ -211,36 +218,28 @@ public class LogoutConfigurerTests {
public void logoutWhenGetRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledConfig.class).autowire();
this.mvc.perform(get("/logout"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(get("/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@Test
public void logoutWhenPostRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledConfig.class).autowire();
this.mvc.perform(post("/logout"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(post("/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@Test
public void logoutWhenPutRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledConfig.class).autowire();
this.mvc.perform(put("/logout"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(put("/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@Test
public void logoutWhenDeleteRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledConfig.class).autowire();
this.mvc.perform(delete("/logout"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(delete("/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
@@ -255,23 +254,21 @@ public class LogoutConfigurerTests {
.logout();
// @formatter:on
}
}
@Test
public void logoutWhenGetRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire();
this.mvc.perform(get("/custom/logout"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(get("/custom/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@Test
public void logoutWhenPostRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire();
this.mvc.perform(post("/custom/logout"))
.andExpect(status().isFound())
this.mvc.perform(post("/custom/logout")).andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
}
@@ -279,17 +276,14 @@ public class LogoutConfigurerTests {
public void logoutWhenPutRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire();
this.mvc.perform(put("/custom/logout"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(put("/custom/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@Test
public void logoutWhenDeleteRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire();
this.mvc.perform(delete("/custom/logout"))
.andExpect(status().isFound())
this.mvc.perform(delete("/custom/logout")).andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
}
@@ -306,15 +300,14 @@ public class LogoutConfigurerTests {
.logoutUrl("/custom/logout");
// @formatter:on
}
}
@Test
public void logoutWhenCustomLogoutUrlInLambdaThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledAndCustomLogoutInLambdaConfig.class).autowire();
this.mvc.perform(get("/custom/logout"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(get("/custom/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
@@ -329,18 +322,19 @@ public class LogoutConfigurerTests {
.logout(logout -> logout.logoutUrl("/custom/logout"));
// @formatter:on
}
}
// SEC-3170
@Test
public void configureWhenLogoutHandlerNullThenException() {
assertThatThrownBy(() -> this.spring.register(NullLogoutHandlerConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutHandlerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -349,17 +343,18 @@ public class LogoutConfigurerTests {
.addLogoutHandler(null);
// @formatter:on
}
}
@Test
public void configureWhenLogoutHandlerNullInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullLogoutHandlerInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasRootCauseInstanceOf(IllegalArgumentException.class);
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -367,6 +362,7 @@ public class LogoutConfigurerTests {
.logout(logout -> logout.addLogoutHandler(null));
// @formatter:on
}
}
// SEC-3170
@@ -374,14 +370,13 @@ public class LogoutConfigurerTests {
public void rememberMeWhenRememberMeServicesNotLogoutHandlerThenRedirectsToLogin() throws Exception {
this.spring.register(RememberMeNoLogoutHandler.class).autowire();
this.mvc.perform(post("/logout")
.with(csrf()))
.andExpect(status().isFound())
this.mvc.perform(post("/logout").with(csrf())).andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
static class RememberMeNoLogoutHandler extends WebSecurityConfigurerAdapter {
static RememberMeServices REMEMBER_ME = mock(RememberMeServices.class);
@Override
@@ -392,18 +387,16 @@ public class LogoutConfigurerTests {
.rememberMeServices(REMEMBER_ME);
// @formatter:on
}
}
@Test
public void logoutWhenAcceptTextHtmlThenRedirectsToLogin() throws Exception {
this.spring.register(BasicSecurityConfig.class).autowire();
this.mvc.perform(post("/logout")
.with(csrf())
.with(user("user"))
.header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML_VALUE))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(
post("/logout").with(csrf()).with(user("user")).header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML_VALUE))
.andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
// gh-3282
@@ -411,11 +404,8 @@ public class LogoutConfigurerTests {
public void logoutWhenAcceptApplicationJsonThenReturnsStatusNoContent() throws Exception {
this.spring.register(BasicSecurityConfig.class).autowire();
this.mvc.perform(post("/logout")
.with(csrf())
.with(user("user"))
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE))
.andExpect(status().isNoContent());
this.mvc.perform(post("/logout").with(csrf()).with(user("user")).header(HttpHeaders.ACCEPT,
MediaType.APPLICATION_JSON_VALUE)).andExpect(status().isNoContent());
}
// gh-4831
@@ -423,10 +413,8 @@ public class LogoutConfigurerTests {
public void logoutWhenAcceptAllThenReturnsStatusNoContent() throws Exception {
this.spring.register(BasicSecurityConfig.class).autowire();
this.mvc.perform(post("/logout")
.with(csrf())
.with(user("user"))
.header(HttpHeaders.ACCEPT, MediaType.ALL_VALUE))
this.mvc.perform(
post("/logout").with(csrf()).with(user("user")).header(HttpHeaders.ACCEPT, MediaType.ALL_VALUE))
.andExpect(status().isNoContent());
}
@@ -435,11 +423,9 @@ public class LogoutConfigurerTests {
public void logoutWhenAcceptFromChromeThenRedirectsToLogin() throws Exception {
this.spring.register(BasicSecurityConfig.class).autowire();
this.mvc.perform(post("/logout")
.with(csrf()).with(user("user"))
.header(HttpHeaders.ACCEPT, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"))
.andExpect(status().isFound())
.andExpect(redirectedUrl("/login?logout"));
this.mvc.perform(post("/logout").with(csrf()).with(user("user")).header(HttpHeaders.ACCEPT,
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"))
.andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
// gh-3997
@@ -447,29 +433,26 @@ public class LogoutConfigurerTests {
public void logoutWhenXMLHttpRequestThenReturnsStatusNoContent() throws Exception {
this.spring.register(BasicSecurityConfig.class).autowire();
this.mvc.perform(post("/logout")
.with(csrf())
.with(user("user"))
.header(HttpHeaders.ACCEPT, "text/html,application/json")
.header("X-Requested-With", "XMLHttpRequest"))
this.mvc.perform(post("/logout").with(csrf()).with(user("user"))
.header(HttpHeaders.ACCEPT, "text/html,application/json").header("X-Requested-With", "XMLHttpRequest"))
.andExpect(status().isNoContent());
}
@EnableWebSecurity
static class BasicSecurityConfig extends WebSecurityConfigurerAdapter {
}
@Test
public void logoutWhenDisabledThenLogoutUrlNotFound() throws Exception {
this.spring.register(LogoutDisabledConfig.class).autowire();
this.mvc.perform(post("/logout")
.with(csrf()))
.andExpect(status().isNotFound());
this.mvc.perform(post("/logout").with(csrf())).andExpect(status().isNotFound());
}
@EnableWebSecurity
static class LogoutDisabledConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -478,5 +461,7 @@ public class LogoutConfigurerTests {
.disable();
// @formatter:on
}
}
}

View File

@@ -45,6 +45,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
* @author Josh Cummings
*/
public class NamespaceDebugTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@@ -60,8 +61,9 @@ public class NamespaceDebugTests {
verify(appender, atLeastOnce()).doAppend(any(ILoggingEvent.class));
}
@EnableWebSecurity(debug=true)
@EnableWebSecurity(debug = true)
static class DebugWebSecurity extends WebSecurityConfigurerAdapter {
}
@Test
@@ -75,6 +77,7 @@ public class NamespaceDebugTests {
@EnableWebSecurity
static class NoDebugWebSecurity extends WebSecurityConfigurerAdapter {
}
private Appender<ILoggingEvent> mockAppenderFor(String name) {
@@ -88,4 +91,5 @@ public class NamespaceDebugTests {
private Class<?> filterChainClass() {
return this.spring.getContext().getBean("springSecurityFilterChain").getClass();
}
}

View File

@@ -57,12 +57,12 @@ public class NamespaceHttpAnonymousTests {
public void anonymousRequestWhenUsingDefaultAnonymousConfigurationThenUsesAnonymousAuthentication()
throws Exception {
this.spring.register(AnonymousConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/type"))
.andExpect(content().string(AnonymousAuthenticationToken.class.getSimpleName()));
this.mvc.perform(get("/type")).andExpect(content().string(AnonymousAuthenticationToken.class.getSimpleName()));
}
@EnableWebSecurity
static class AnonymousConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -72,18 +72,18 @@ public class NamespaceHttpAnonymousTests {
.anyRequest().denyAll();
// @formatter:on
}
}
@Test
public void anonymousRequestWhenDisablingAnonymousThenDenies()
throws Exception {
public void anonymousRequestWhenDisablingAnonymousThenDenies() throws Exception {
this.spring.register(AnonymousDisabledConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/type"))
.andExpect(status().isForbidden());
this.mvc.perform(get("/type")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class AnonymousDisabledConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -103,18 +103,18 @@ public class NamespaceHttpAnonymousTests {
.withUser(PasswordEncodedUser.admin());
// @formatter:on
}
}
@Test
public void requestWhenAnonymousThenSendsAnonymousConfiguredAuthorities()
throws Exception {
public void requestWhenAnonymousThenSendsAnonymousConfiguredAuthorities() throws Exception {
this.spring.register(AnonymousGrantedAuthorityConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/type"))
.andExpect(content().string(AnonymousAuthenticationToken.class.getSimpleName()));
this.mvc.perform(get("/type")).andExpect(content().string(AnonymousAuthenticationToken.class.getSimpleName()));
}
@EnableWebSecurity
static class AnonymousGrantedAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -127,17 +127,18 @@ public class NamespaceHttpAnonymousTests {
.authorities("ROLE_ANON");
// @formatter:on
}
}
@Test
public void anonymousRequestWhenAnonymousKeyConfiguredThenKeyIsUsed() throws Exception {
this.spring.register(AnonymousKeyConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/key"))
.andExpect(content().string(String.valueOf("AnonymousKeyConfig".hashCode())));
this.mvc.perform(get("/key")).andExpect(content().string(String.valueOf("AnonymousKeyConfig".hashCode())));
}
@EnableWebSecurity
static class AnonymousKeyConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -149,17 +150,18 @@ public class NamespaceHttpAnonymousTests {
.anonymous().key("AnonymousKeyConfig");
// @formatter:on
}
}
@Test
public void anonymousRequestWhenAnonymousUsernameConfiguredThenUsernameIsUsed() throws Exception {
this.spring.register(AnonymousUsernameConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/principal"))
.andExpect(content().string("AnonymousUsernameConfig"));
this.mvc.perform(get("/principal")).andExpect(content().string("AnonymousUsernameConfig"));
}
@EnableWebSecurity
static class AnonymousUsernameConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -171,39 +173,33 @@ public class NamespaceHttpAnonymousTests {
.anonymous().principal("AnonymousUsernameConfig");
// @formatter:on
}
}
@RestController
static class AnonymousController {
@GetMapping("/type")
String type() {
return anonymousToken()
.map(AnonymousAuthenticationToken::getClass)
.map(Class::getSimpleName)
.orElse(null);
return anonymousToken().map(AnonymousAuthenticationToken::getClass).map(Class::getSimpleName).orElse(null);
}
@GetMapping("/key")
String key() {
return anonymousToken()
.map(AnonymousAuthenticationToken::getKeyHash)
.map(String::valueOf)
.orElse(null);
return anonymousToken().map(AnonymousAuthenticationToken::getKeyHash).map(String::valueOf).orElse(null);
}
@GetMapping("/principal")
String principal() {
return anonymousToken()
.map(AnonymousAuthenticationToken::getName)
.orElse(null);
return anonymousToken().map(AnonymousAuthenticationToken::getName).orElse(null);
}
Optional<AnonymousAuthenticationToken> anonymousToken() {
return Optional.of(SecurityContextHolder.getContext())
.map(SecurityContext::getAuthentication)
return Optional.of(SecurityContextHolder.getContext()).map(SecurityContext::getAuthentication)
.filter(a -> a instanceof AnonymousAuthenticationToken)
.map(AnonymousAuthenticationToken.class::cast);
}
}
}

View File

@@ -65,25 +65,21 @@ public class NamespaceHttpBasicTests {
public void basicAuthenticationWhenUsingDefaultsThenMatchesNamespace() throws Exception {
this.spring.register(HttpBasicConfig.class, UserConfig.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
this.mvc.perform(get("/")
.with(httpBasic("user", "invalid")))
.andExpect(status().isUnauthorized())
this.mvc.perform(get("/").with(httpBasic("user", "invalid"))).andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Realm\""));
this.mvc.perform(get("/")
.with(httpBasic("user", "password")))
.andExpect(status().isNotFound());
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@Configuration
static class UserConfig {
@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(
// @formatter:off
// @formatter:off
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
@@ -92,10 +88,12 @@ public class NamespaceHttpBasicTests {
// @formatter:on
);
}
}
@EnableWebSecurity
static class HttpBasicConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -105,27 +103,24 @@ public class NamespaceHttpBasicTests {
.httpBasic();
// @formatter:on
}
}
@Test
public void basicAuthenticationWhenUsingDefaultsInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(HttpBasicLambdaConfig.class, UserConfig.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().isUnauthorized());
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
this.mvc.perform(get("/")
.with(httpBasic("user", "invalid")))
.andExpect(status().isUnauthorized())
this.mvc.perform(get("/").with(httpBasic("user", "invalid"))).andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Realm\""));
this.mvc.perform(get("/")
.with(httpBasic("user", "password")))
.andExpect(status().isNotFound());
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@EnableWebSecurity
static class HttpBasicLambdaConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -136,6 +131,7 @@ public class NamespaceHttpBasicTests {
.httpBasic(withDefaults());
// @formatter:on
}
}
/**
@@ -145,14 +141,13 @@ public class NamespaceHttpBasicTests {
public void basicAuthenticationWhenUsingCustomRealmThenMatchesNamespace() throws Exception {
this.spring.register(CustomHttpBasicConfig.class, UserConfig.class).autowire();
this.mvc.perform(get("/")
.with(httpBasic("user", "invalid")))
.andExpect(status().isUnauthorized())
this.mvc.perform(get("/").with(httpBasic("user", "invalid"))).andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\""));
}
@EnableWebSecurity
static class CustomHttpBasicConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -163,20 +158,20 @@ public class NamespaceHttpBasicTests {
.httpBasic().realmName("Custom Realm");
// @formatter:on
}
}
@Test
public void basicAuthenticationWhenUsingCustomRealmInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(CustomHttpBasicLambdaConfig.class, UserConfig.class).autowire();
this.mvc.perform(get("/")
.with(httpBasic("user", "invalid")))
.andExpect(status().isUnauthorized())
this.mvc.perform(get("/").with(httpBasic("user", "invalid"))).andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\""));
}
@EnableWebSecurity
static class CustomHttpBasicLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@@ -188,6 +183,7 @@ public class NamespaceHttpBasicTests {
.httpBasic(httpBasicConfig -> httpBasicConfig.realmName("Custom Realm"));
// @formatter:on
}
}
/**
@@ -197,19 +193,19 @@ public class NamespaceHttpBasicTests {
public void basicAuthenticationWhenUsingAuthenticationDetailsSourceRefThenMatchesNamespace() throws Exception {
this.spring.register(AuthenticationDetailsSourceHttpBasicConfig.class, UserConfig.class).autowire();
AuthenticationDetailsSource<HttpServletRequest, ?> source =
this.spring.getContext().getBean(AuthenticationDetailsSource.class);
AuthenticationDetailsSource<HttpServletRequest, ?> source = this.spring.getContext()
.getBean(AuthenticationDetailsSource.class);
this.mvc.perform(get("/")
.with(httpBasic("user", "password")));
this.mvc.perform(get("/").with(httpBasic("user", "password")));
verify(source).buildDetails(any(HttpServletRequest.class));
}
@EnableWebSecurity
static class AuthenticationDetailsSourceHttpBasicConfig extends WebSecurityConfigurerAdapter {
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource =
mock(AuthenticationDetailsSource.class);
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = mock(
AuthenticationDetailsSource.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -224,6 +220,7 @@ public class NamespaceHttpBasicTests {
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource() {
return this.authenticationDetailsSource;
}
}
@Test
@@ -231,19 +228,19 @@ public class NamespaceHttpBasicTests {
throws Exception {
this.spring.register(AuthenticationDetailsSourceHttpBasicLambdaConfig.class, UserConfig.class).autowire();
AuthenticationDetailsSource<HttpServletRequest, ?> source =
this.spring.getContext().getBean(AuthenticationDetailsSource.class);
AuthenticationDetailsSource<HttpServletRequest, ?> source = this.spring.getContext()
.getBean(AuthenticationDetailsSource.class);
this.mvc.perform(get("/")
.with(httpBasic("user", "password")));
this.mvc.perform(get("/").with(httpBasic("user", "password")));
verify(source).buildDetails(any(HttpServletRequest.class));
}
@EnableWebSecurity
static class AuthenticationDetailsSourceHttpBasicLambdaConfig extends WebSecurityConfigurerAdapter {
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource =
mock(AuthenticationDetailsSource.class);
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = mock(
AuthenticationDetailsSource.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -258,6 +255,7 @@ public class NamespaceHttpBasicTests {
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource() {
return this.authenticationDetailsSource;
}
}
/**
@@ -267,22 +265,17 @@ public class NamespaceHttpBasicTests {
public void basicAuthenticationWhenUsingEntryPointRefThenMatchesNamespace() throws Exception {
this.spring.register(EntryPointRefHttpBasicConfig.class, UserConfig.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().is(999));
this.mvc.perform(get("/")).andExpect(status().is(999));
this.mvc.perform(get("/")
.with(httpBasic("user", "invalid")))
.andExpect(status().is(999));
this.mvc.perform(get("/").with(httpBasic("user", "invalid"))).andExpect(status().is(999));
this.mvc.perform(get("/")
.with(httpBasic("user", "password")))
.andExpect(status().isNotFound());
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@EnableWebSecurity
static class EntryPointRefHttpBasicConfig extends WebSecurityConfigurerAdapter {
AuthenticationEntryPoint authenticationEntryPoint =
(request, response, ex) -> response.setStatus(999);
AuthenticationEntryPoint authenticationEntryPoint = (request, response, ex) -> response.setStatus(999);
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -295,28 +288,24 @@ public class NamespaceHttpBasicTests {
.authenticationEntryPoint(this.authenticationEntryPoint);
// @formatter:on
}
}
@Test
public void basicAuthenticationWhenUsingEntryPointRefInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(EntryPointRefHttpBasicLambdaConfig.class, UserConfig.class).autowire();
this.mvc.perform(get("/"))
.andExpect(status().is(999));
this.mvc.perform(get("/")).andExpect(status().is(999));
this.mvc.perform(get("/")
.with(httpBasic("user", "invalid")))
.andExpect(status().is(999));
this.mvc.perform(get("/").with(httpBasic("user", "invalid"))).andExpect(status().is(999));
this.mvc.perform(get("/")
.with(httpBasic("user", "password")))
.andExpect(status().isNotFound());
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@EnableWebSecurity
static class EntryPointRefHttpBasicLambdaConfig extends WebSecurityConfigurerAdapter {
AuthenticationEntryPoint authenticationEntryPoint =
(request, response, ex) -> response.setStatus(999);
AuthenticationEntryPoint authenticationEntryPoint = (request, response, ex) -> response.setStatus(999);
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -330,5 +319,7 @@ public class NamespaceHttpBasicTests {
httpBasicConfig.authenticationEntryPoint(this.authenticationEntryPoint));
// @formatter:on
}
}
}

View File

@@ -15,7 +15,6 @@
*/
package org.springframework.security.config.annotation.web.configurers;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
@@ -66,6 +65,7 @@ public class NamespaceHttpCustomFilterTests {
@EnableWebSecurity
static class CustomFilterBeforeConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -73,6 +73,7 @@ public class NamespaceHttpCustomFilterTests {
.formLogin();
// @formatter:on
}
}
@Test
@@ -83,6 +84,7 @@ public class NamespaceHttpCustomFilterTests {
@EnableWebSecurity
static class CustomFilterAfterConfig extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
@@ -90,6 +92,7 @@ public class NamespaceHttpCustomFilterTests {
.formLogin();
// @formatter:on
}
}
@Test
@@ -100,6 +103,7 @@ public class NamespaceHttpCustomFilterTests {
@EnableWebSecurity
static class CustomFilterPositionConfig extends WebSecurityConfigurerAdapter {
CustomFilterPositionConfig() {
// do not add the default filters to make testing easier
super(true);
@@ -113,8 +117,8 @@ public class NamespaceHttpCustomFilterTests {
.addFilter(new CustomFilter());
// @formatter:on
}
}
}
@Test
public void getFiltersWhenFilterAddedAtPositionThenBehaviorMatchesNamespace() {
@@ -124,6 +128,7 @@ public class NamespaceHttpCustomFilterTests {
@EnableWebSecurity
static class CustomFilterPositionAtConfig extends WebSecurityConfigurerAdapter {
CustomFilterPositionAtConfig() {
// do not add the default filters to make testing easier
super(true);
@@ -135,6 +140,7 @@ public class NamespaceHttpCustomFilterTests {
.addFilterAt(new OtherCustomFilter(), UsernamePasswordAuthenticationFilter.class);
// @formatter:on
}
}
@Test
@@ -145,6 +151,7 @@ public class NamespaceHttpCustomFilterTests {
@EnableWebSecurity
static class NoAuthenticationManagerInHttpConfigurationConfig extends WebSecurityConfigurerAdapter {
NoAuthenticationManagerInHttpConfigurationConfig() {
super(true);
}
@@ -163,14 +170,16 @@ public class NamespaceHttpCustomFilterTests {
.addFilterBefore(new CustomFilter(), UsernamePasswordAuthenticationFilter.class);
// @formatter:on
}
}
@Configuration
static class UserDetailsServiceConfig {
@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(
// @formatter:off
// @formatter:off
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
@@ -178,28 +187,35 @@ public class NamespaceHttpCustomFilterTests {
.build());
// @formatter:on
}
}
static class CustomFilter extends UsernamePasswordAuthenticationFilter {
}
static class CustomFilter extends UsernamePasswordAuthenticationFilter {}
static class OtherCustomFilter extends OncePerRequestFilter {
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
filterChain.doFilter(request, response);
}
}
static class CustomAuthenticationManager implements AuthenticationManager {
public Authentication authenticate(Authentication authentication)
throws AuthenticationException {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
return null;
}
}
private ListAssert<Class<?>> assertThatFilters() {
FilterChainProxy filterChain = this.spring.getContext().getBean(FilterChainProxy.class);
List<Class<?>> filters = filterChain.getFilters("/").stream()
.map(Object::getClass).collect(Collectors.toList());
List<Class<?>> filters = filterChain.getFilters("/").stream().map(Object::getClass)
.collect(Collectors.toList());
return assertThat(filters);
}
}

Some files were not shown because too many files have changed in this diff Show More