Move inner-types so that they are always last

Move all inner-types so that they are consistently the last item
defined. This aligns with the style used by Spring Framework and
the consistency generally makes it easier to scan the source.

Issue gh-8945
This commit is contained in:
Phillip Webb 2020-07-26 13:35:03 -07:00 committed by Rob Winch
parent 418c3d6808
commit a2f2e9ac8d
163 changed files with 10287 additions and 10332 deletions

View File

@ -544,6 +544,14 @@ public class JdbcMutableAclServiceTests extends AbstractTransactionalJUnit4Sprin
assertThat(new Long(1L)).isEqualTo(result);
}
protected Authentication getAuth() {
return this.auth;
}
protected JdbcMutableAclService getJdbcMutableAclService() {
return this.jdbcMutableAclService;
}
/**
* This class needed to show how to extend {@link JdbcMutableAclService} for
* processing custom {@link Sid} implementations
@ -573,12 +581,4 @@ public class JdbcMutableAclServiceTests extends AbstractTransactionalJUnit4Sprin
}
protected Authentication getAuth() {
return this.auth;
}
protected JdbcMutableAclService getJdbcMutableAclService() {
return this.jdbcMutableAclService;
}
}

View File

@ -53,6 +53,8 @@ import static org.springframework.security.test.web.servlet.response.SecurityMoc
public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
static Integer port;
@Rule
public final SpringTestRule spring = new SpringTestRule();
@ -76,6 +78,80 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("ROLE_");
}
@Test
public void groupRolesCustom() {
this.spring.register(GroupRolesConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupRoleAttribute"))
.isEqualTo("group");
}
@Test
public void groupSearchCustom() {
this.spring.register(GroupSearchConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupSearchFilter"))
.isEqualTo("ou=groupName");
}
@Test
public void groupSubtreeSearchCustom() {
this.spring.register(GroupSubtreeSearchConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "searchControls"))
.extracting("searchScope").isEqualTo(SearchControls.SUBTREE_SCOPE);
}
@Test
public void rolePrefixCustom() {
this.spring.register(RolePrefixConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("role_");
}
@Test
public void bindAuthentication() throws Exception {
this.spring.register(BindAuthenticationConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword")).andExpect(authenticated()
.withUsername("bob").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
// SEC-2472
@Test
public void canUseCryptoPasswordEncoder() throws Exception {
this.spring.register(PasswordEncoderConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bcrypt").password("password")).andExpect(authenticated()
.withUsername("bcrypt").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
private LdapAuthenticationProvider ldapProvider() {
return ((List<LdapAuthenticationProvider>) ReflectionTestUtils.getField(this.authenticationManager,
"providers")).get(0);
}
private LdapAuthoritiesPopulator getAuthoritiesPopulator(LdapAuthenticationProvider provider) {
return (LdapAuthoritiesPopulator) ReflectionTestUtils.getField(provider, "authoritiesPopulator");
}
private GrantedAuthoritiesMapper getAuthoritiesMapper(LdapAuthenticationProvider provider) {
return (GrantedAuthoritiesMapper) ReflectionTestUtils.getField(provider, "authoritiesMapper");
}
static int getPort() throws IOException {
if (port == null) {
ServerSocket socket = new ServerSocket(0);
port = socket.getLocalPort();
socket.close();
}
return port;
}
@EnableWebSecurity
static class DefaultLdapConfig extends BaseLdapProviderConfig {
@ -91,15 +167,6 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
}
@Test
public void groupRolesCustom() {
this.spring.register(GroupRolesConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupRoleAttribute"))
.isEqualTo("group");
}
@EnableWebSecurity
static class GroupRolesConfig extends BaseLdapProviderConfig {
@ -116,15 +183,6 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
}
@Test
public void groupSearchCustom() {
this.spring.register(GroupSearchConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "groupSearchFilter"))
.isEqualTo("ou=groupName");
}
@EnableWebSecurity
static class GroupSearchConfig extends BaseLdapProviderConfig {
@ -141,15 +199,6 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
}
@Test
public void groupSubtreeSearchCustom() {
this.spring.register(GroupSubtreeSearchConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesPopulator(provider), "searchControls"))
.extracting("searchScope").isEqualTo(SearchControls.SUBTREE_SCOPE);
}
@EnableWebSecurity
static class GroupSubtreeSearchConfig extends BaseLdapProviderConfig {
@ -167,14 +216,6 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
}
@Test
public void rolePrefixCustom() {
this.spring.register(RolePrefixConfig.class).autowire();
LdapAuthenticationProvider provider = ldapProvider();
assertThat(ReflectionTestUtils.getField(getAuthoritiesMapper(provider), "prefix")).isEqualTo("role_");
}
@EnableWebSecurity
static class RolePrefixConfig extends BaseLdapProviderConfig {
@ -191,14 +232,6 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
}
@Test
public void bindAuthentication() throws Exception {
this.spring.register(BindAuthenticationConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bob").password("bobspassword")).andExpect(authenticated()
.withUsername("bob").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
@EnableWebSecurity
static class BindAuthenticationConfig extends BaseLdapServerConfig {
@ -216,15 +249,6 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
}
// SEC-2472
@Test
public void canUseCryptoPasswordEncoder() throws Exception {
this.spring.register(PasswordEncoderConfig.class).autowire();
this.mockMvc.perform(formLogin().user("bcrypt").password("password")).andExpect(authenticated()
.withUsername("bcrypt").withAuthorities(singleton(new SimpleGrantedAuthority("ROLE_DEVELOPERS"))));
}
@EnableWebSecurity
static class PasswordEncoderConfig extends BaseLdapServerConfig {
@ -243,19 +267,6 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
}
private LdapAuthenticationProvider ldapProvider() {
return ((List<LdapAuthenticationProvider>) ReflectionTestUtils.getField(this.authenticationManager,
"providers")).get(0);
}
private LdapAuthoritiesPopulator getAuthoritiesPopulator(LdapAuthenticationProvider provider) {
return (LdapAuthoritiesPopulator) ReflectionTestUtils.getField(provider, "authoritiesPopulator");
}
private GrantedAuthoritiesMapper getAuthoritiesMapper(LdapAuthenticationProvider provider) {
return (GrantedAuthoritiesMapper) ReflectionTestUtils.getField(provider, "authoritiesMapper");
}
@EnableWebSecurity
static abstract class BaseLdapServerConfig extends BaseLdapProviderConfig {
@ -295,15 +306,4 @@ public class LdapAuthenticationProviderBuilderSecurityBuilderTests {
}
static Integer port;
static int getPort() throws IOException {
if (port == null) {
ServerSocket socket = new ServerSocket(0);
port = socket.getLocalPort();
socket.close();
}
return port;
}
}

View File

@ -379,6 +379,21 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
builder.authenticationProvider(provider);
}
private BaseLdapPathContextSource getContextSource() throws Exception {
if (this.contextSource == null) {
this.contextSource = this.contextSourceBuilder.build();
}
return this.contextSource;
}
/**
* @return the {@link PasswordCompareConfigurer} for further customizations
*/
public PasswordCompareConfigurer passwordCompare() {
return new PasswordCompareConfigurer().passwordAttribute("password")
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
/**
* Sets up Password based comparison
*
@ -597,19 +612,4 @@ public class LdapAuthenticationProviderConfigurer<B extends ProviderManagerBuild
}
private BaseLdapPathContextSource getContextSource() throws Exception {
if (this.contextSource == null) {
this.contextSource = this.contextSourceBuilder.build();
}
return this.contextSource;
}
/**
* @return the {@link PasswordCompareConfigurer} for further customizations
*/
public PasswordCompareConfigurer passwordCompare() {
return new PasswordCompareConfigurer().passwordAttribute("password")
.passwordEncoder(NoOpPasswordEncoder.getInstance());
}
}

View File

@ -161,38 +161,6 @@ public class RSocketSecurity {
return this;
}
/**
* @since 5.3
*/
public final class SimpleAuthenticationSpec {
private ReactiveAuthenticationManager authenticationManager;
public SimpleAuthenticationSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
}
private ReactiveAuthenticationManager getAuthenticationManager() {
if (this.authenticationManager == null) {
return RSocketSecurity.this.authenticationManager;
}
return this.authenticationManager;
}
protected AuthenticationPayloadInterceptor build() {
ReactiveAuthenticationManager manager = getAuthenticationManager();
AuthenticationPayloadInterceptor result = new AuthenticationPayloadInterceptor(manager);
result.setAuthenticationConverter(new AuthenticationPayloadExchangeConverter());
result.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
return result;
}
private SimpleAuthenticationSpec() {
}
}
/**
* Adds authentication with BasicAuthenticationPayloadExchangeConverter.
* @param basic
@ -208,34 +176,6 @@ public class RSocketSecurity {
return this;
}
public final class BasicAuthenticationSpec {
private ReactiveAuthenticationManager authenticationManager;
public BasicAuthenticationSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
}
private ReactiveAuthenticationManager getAuthenticationManager() {
if (this.authenticationManager == null) {
return RSocketSecurity.this.authenticationManager;
}
return this.authenticationManager;
}
protected AuthenticationPayloadInterceptor build() {
ReactiveAuthenticationManager manager = getAuthenticationManager();
AuthenticationPayloadInterceptor result = new AuthenticationPayloadInterceptor(manager);
result.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
return result;
}
private BasicAuthenticationSpec() {
}
}
public RSocketSecurity jwt(Customizer<JwtSpec> jwt) {
if (this.jwtSpec == null) {
this.jwtSpec = new JwtSpec();
@ -244,45 +184,6 @@ public class RSocketSecurity {
return this;
}
public final class JwtSpec {
private ReactiveAuthenticationManager authenticationManager;
public JwtSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
}
private ReactiveAuthenticationManager getAuthenticationManager() {
if (this.authenticationManager != null) {
return this.authenticationManager;
}
ReactiveJwtDecoder jwtDecoder = getBeanOrNull(ReactiveJwtDecoder.class);
if (jwtDecoder != null) {
this.authenticationManager = new JwtReactiveAuthenticationManager(jwtDecoder);
return this.authenticationManager;
}
return RSocketSecurity.this.authenticationManager;
}
protected List<AuthenticationPayloadInterceptor> build() {
ReactiveAuthenticationManager manager = getAuthenticationManager();
AuthenticationPayloadInterceptor legacy = new AuthenticationPayloadInterceptor(manager);
legacy.setAuthenticationConverter(new BearerPayloadExchangeConverter());
legacy.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
AuthenticationPayloadInterceptor standard = new AuthenticationPayloadInterceptor(manager);
standard.setAuthenticationConverter(new AuthenticationPayloadExchangeConverter());
standard.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
return Arrays.asList(standard, legacy);
}
private JwtSpec() {
}
}
public RSocketSecurity authorizePayload(Customizer<AuthorizePayloadsSpec> authorize) {
if (this.authorizePayload == null) {
this.authorizePayload = new AuthorizePayloadsSpec();
@ -326,6 +227,131 @@ public class RSocketSecurity {
return result;
}
private <T> T getBean(Class<T> beanClass) {
if (this.context == null) {
return null;
}
return this.context.getBean(beanClass);
}
private <T> T getBeanOrNull(Class<T> beanClass) {
return getBeanOrNull(ResolvableType.forClass(beanClass));
}
private <T> T getBeanOrNull(ResolvableType type) {
if (this.context == null) {
return null;
}
String[] names = this.context.getBeanNamesForType(type);
if (names.length == 1) {
return (T) this.context.getBean(names[0]);
}
return null;
}
protected void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
/**
* @since 5.3
*/
public final class SimpleAuthenticationSpec {
private ReactiveAuthenticationManager authenticationManager;
public SimpleAuthenticationSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
}
private ReactiveAuthenticationManager getAuthenticationManager() {
if (this.authenticationManager == null) {
return RSocketSecurity.this.authenticationManager;
}
return this.authenticationManager;
}
protected AuthenticationPayloadInterceptor build() {
ReactiveAuthenticationManager manager = getAuthenticationManager();
AuthenticationPayloadInterceptor result = new AuthenticationPayloadInterceptor(manager);
result.setAuthenticationConverter(new AuthenticationPayloadExchangeConverter());
result.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
return result;
}
private SimpleAuthenticationSpec() {
}
}
public final class BasicAuthenticationSpec {
private ReactiveAuthenticationManager authenticationManager;
public BasicAuthenticationSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
}
private ReactiveAuthenticationManager getAuthenticationManager() {
if (this.authenticationManager == null) {
return RSocketSecurity.this.authenticationManager;
}
return this.authenticationManager;
}
protected AuthenticationPayloadInterceptor build() {
ReactiveAuthenticationManager manager = getAuthenticationManager();
AuthenticationPayloadInterceptor result = new AuthenticationPayloadInterceptor(manager);
result.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
return result;
}
private BasicAuthenticationSpec() {
}
}
public final class JwtSpec {
private ReactiveAuthenticationManager authenticationManager;
public JwtSpec authenticationManager(ReactiveAuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
return this;
}
private ReactiveAuthenticationManager getAuthenticationManager() {
if (this.authenticationManager != null) {
return this.authenticationManager;
}
ReactiveJwtDecoder jwtDecoder = getBeanOrNull(ReactiveJwtDecoder.class);
if (jwtDecoder != null) {
this.authenticationManager = new JwtReactiveAuthenticationManager(jwtDecoder);
return this.authenticationManager;
}
return RSocketSecurity.this.authenticationManager;
}
protected List<AuthenticationPayloadInterceptor> build() {
ReactiveAuthenticationManager manager = getAuthenticationManager();
AuthenticationPayloadInterceptor legacy = new AuthenticationPayloadInterceptor(manager);
legacy.setAuthenticationConverter(new BearerPayloadExchangeConverter());
legacy.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
AuthenticationPayloadInterceptor standard = new AuthenticationPayloadInterceptor(manager);
standard.setAuthenticationConverter(new AuthenticationPayloadExchangeConverter());
standard.setOrder(PayloadInterceptorOrder.AUTHENTICATION.getOrder());
return Arrays.asList(standard, legacy);
}
private JwtSpec() {
}
}
public class AuthorizePayloadsSpec {
private PayloadExchangeMatcherReactiveAuthorizationManager.Builder authzBuilder = PayloadExchangeMatcherReactiveAuthorizationManager
@ -417,30 +443,4 @@ public class RSocketSecurity {
}
private <T> T getBean(Class<T> beanClass) {
if (this.context == null) {
return null;
}
return this.context.getBean(beanClass);
}
private <T> T getBeanOrNull(Class<T> beanClass) {
return getBeanOrNull(ResolvableType.forClass(beanClass));
}
private <T> T getBeanOrNull(ResolvableType type) {
if (this.context == null) {
return null;
}
String[] names = this.context.getBeanNamesForType(type);
if (names.length == 1) {
return (T) this.context.getBean(names[0]);
}
return null;
}
protected void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
}

View File

@ -2912,6 +2912,24 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
return requestMatcher(new RegexRequestMatcher(pattern, null));
}
/**
* If the {@link SecurityConfigurer} has already been specified get the original,
* otherwise apply the new {@link SecurityConfigurerAdapter}.
* @param configurer the {@link SecurityConfigurer} to apply if one is not found for
* this {@link SecurityConfigurer} class.
* @return the current {@link SecurityConfigurer} for the configurer passed in
* @throws Exception
*/
@SuppressWarnings("unchecked")
private <C extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>> C getOrApply(C configurer)
throws Exception {
C existingConfig = (C) getConfigurer(configurer.getClass());
if (existingConfig != null) {
return existingConfig;
}
return apply(configurer);
}
/**
* An extension to {@link RequestMatcherConfigurer} that allows optionally configuring
* the servlet path.
@ -2987,22 +3005,4 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
}
/**
* If the {@link SecurityConfigurer} has already been specified get the original,
* otherwise apply the new {@link SecurityConfigurerAdapter}.
* @param configurer the {@link SecurityConfigurer} to apply if one is not found for
* this {@link SecurityConfigurer} class.
* @return the current {@link SecurityConfigurer} for the configurer passed in
* @throws Exception
*/
@SuppressWarnings("unchecked")
private <C extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity>> C getOrApply(C configurer)
throws Exception {
C existingConfig = (C) getConfigurer(configurer.getClass());
if (existingConfig != null) {
return existingConfig;
}
return apply(configurer);
}
}

View File

@ -304,6 +304,36 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
return result;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.defaultWebSecurityExpressionHandler.setApplicationContext(applicationContext);
try {
this.defaultWebSecurityExpressionHandler.setRoleHierarchy(applicationContext.getBean(RoleHierarchy.class));
}
catch (NoSuchBeanDefinitionException e) {
}
try {
this.defaultWebSecurityExpressionHandler
.setPermissionEvaluator(applicationContext.getBean(PermissionEvaluator.class));
}
catch (NoSuchBeanDefinitionException e) {
}
this.ignoredRequestRegistry = new IgnoredRequestConfigurer(applicationContext);
try {
this.httpFirewall = applicationContext.getBean(HttpFirewall.class);
}
catch (NoSuchBeanDefinitionException e) {
}
try {
this.requestRejectedHandler = applicationContext.getBean(RequestRejectedHandler.class);
}
catch (NoSuchBeanDefinitionException e) {
}
}
/**
* An {@link IgnoredRequestConfigurer} that allows optionally configuring the
* {@link MvcRequestMatcher#setMethod(HttpMethod)}
@ -368,34 +398,4 @@ public final class WebSecurity extends AbstractConfiguredSecurityBuilder<Filter,
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.defaultWebSecurityExpressionHandler.setApplicationContext(applicationContext);
try {
this.defaultWebSecurityExpressionHandler.setRoleHierarchy(applicationContext.getBean(RoleHierarchy.class));
}
catch (NoSuchBeanDefinitionException e) {
}
try {
this.defaultWebSecurityExpressionHandler
.setPermissionEvaluator(applicationContext.getBean(PermissionEvaluator.class));
}
catch (NoSuchBeanDefinitionException e) {
}
this.ignoredRequestRegistry = new IgnoredRequestConfigurer(applicationContext);
try {
this.httpFirewall = applicationContext.getBean(HttpFirewall.class);
}
catch (NoSuchBeanDefinitionException e) {
}
try {
this.requestRejectedHandler = applicationContext.getBean(RequestRejectedHandler.class);
}
catch (NoSuchBeanDefinitionException e) {
}
}
}

View File

@ -188,6 +188,35 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
return new AutowiredWebSecurityConfigurersIgnoreParents(beanFactory);
}
/*
* (non-Javadoc)
*
* @see org.springframework.context.annotation.ImportAware#setImportMetadata(org.
* springframework.core.type.AnnotationMetadata)
*/
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> enableWebSecurityAttrMap = importMetadata
.getAnnotationAttributes(EnableWebSecurity.class.getName());
AnnotationAttributes enableWebSecurityAttrs = AnnotationAttributes.fromMap(enableWebSecurityAttrMap);
this.debugEnabled = enableWebSecurityAttrs.getBoolean("debug");
if (this.webSecurity != null) {
this.webSecurity.debug(this.debugEnabled);
}
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.
* lang.ClassLoader)
*/
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
/**
* A custom verision of the Spring provided AnnotationAwareOrderComparator that uses
* {@link AnnotationUtils#findAnnotation(Class, Class)} to look on super class
@ -221,33 +250,4 @@ public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAwa
}
/*
* (non-Javadoc)
*
* @see org.springframework.context.annotation.ImportAware#setImportMetadata(org.
* springframework.core.type.AnnotationMetadata)
*/
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> enableWebSecurityAttrMap = importMetadata
.getAnnotationAttributes(EnableWebSecurity.class.getName());
AnnotationAttributes enableWebSecurityAttrs = AnnotationAttributes.fromMap(enableWebSecurityAttrMap);
this.debugEnabled = enableWebSecurityAttrs.getBoolean("debug");
if (this.webSecurity != null) {
this.webSecurity.debug(this.debugEnabled);
}
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.
* lang.ClassLoader)
*/
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
}

View File

@ -102,44 +102,6 @@ abstract class AbstractInterceptUrlConfigurer<C extends AbstractInterceptUrlConf
*/
abstract List<AccessDecisionVoter<?>> getDecisionVoters(H http);
abstract class AbstractInterceptUrlRegistry<R extends AbstractInterceptUrlRegistry<R, T>, T>
extends AbstractConfigAttributeRequestMatcherRegistry<T> {
/**
* Allows setting the {@link AccessDecisionManager}. If none is provided, a
* default {@link AccessDecisionManager} is created.
* @param accessDecisionManager the {@link AccessDecisionManager} to use
* @return the {@link AbstractInterceptUrlConfigurer} for further customization
*/
public R accessDecisionManager(AccessDecisionManager accessDecisionManager) {
AbstractInterceptUrlConfigurer.this.accessDecisionManager = accessDecisionManager;
return getSelf();
}
/**
* Allows setting if the {@link FilterSecurityInterceptor} should be only applied
* once per request (i.e. if the filter intercepts on a forward, should it be
* applied again).
* @param filterSecurityInterceptorOncePerRequest if the
* {@link FilterSecurityInterceptor} should be only applied once per request
* @return the {@link AbstractInterceptUrlConfigurer} for further customization
*/
public R filterSecurityInterceptorOncePerRequest(boolean filterSecurityInterceptorOncePerRequest) {
AbstractInterceptUrlConfigurer.this.filterSecurityInterceptorOncePerRequest = filterSecurityInterceptorOncePerRequest;
return getSelf();
}
/**
* Returns a reference to the current object with a single suppression of the type
* @return a reference to the current object
*/
@SuppressWarnings("unchecked")
private R getSelf() {
return (R) this;
}
}
/**
* Creates the default {@code AccessDecisionManager}
* @return the default {@code AccessDecisionManager}
@ -182,4 +144,42 @@ abstract class AbstractInterceptUrlConfigurer<C extends AbstractInterceptUrlConf
return securityInterceptor;
}
abstract class AbstractInterceptUrlRegistry<R extends AbstractInterceptUrlRegistry<R, T>, T>
extends AbstractConfigAttributeRequestMatcherRegistry<T> {
/**
* Allows setting the {@link AccessDecisionManager}. If none is provided, a
* default {@link AccessDecisionManager} is created.
* @param accessDecisionManager the {@link AccessDecisionManager} to use
* @return the {@link AbstractInterceptUrlConfigurer} for further customization
*/
public R accessDecisionManager(AccessDecisionManager accessDecisionManager) {
AbstractInterceptUrlConfigurer.this.accessDecisionManager = accessDecisionManager;
return getSelf();
}
/**
* Allows setting if the {@link FilterSecurityInterceptor} should be only applied
* once per request (i.e. if the filter intercepts on a forward, should it be
* applied again).
* @param filterSecurityInterceptorOncePerRequest if the
* {@link FilterSecurityInterceptor} should be only applied once per request
* @return the {@link AbstractInterceptUrlConfigurer} for further customization
*/
public R filterSecurityInterceptorOncePerRequest(boolean filterSecurityInterceptorOncePerRequest) {
AbstractInterceptUrlConfigurer.this.filterSecurityInterceptorOncePerRequest = filterSecurityInterceptorOncePerRequest;
return getSelf();
}
/**
* Returns a reference to the current object with a single suppression of the type
* @return a reference to the current object
*/
@SuppressWarnings("unchecked")
private R getSelf() {
return (R) this;
}
}
}

View File

@ -109,61 +109,6 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
return this.REGISTRY;
}
public final class ExpressionInterceptUrlRegistry extends
ExpressionUrlAuthorizationConfigurer<H>.AbstractInterceptUrlRegistry<ExpressionInterceptUrlRegistry, AuthorizedUrl> {
/**
* @param context
*/
private ExpressionInterceptUrlRegistry(ApplicationContext context) {
setApplicationContext(context);
}
@Override
public MvcMatchersAuthorizedUrl mvcMatchers(HttpMethod method, String... mvcPatterns) {
return new MvcMatchersAuthorizedUrl(createMvcMatchers(method, mvcPatterns));
}
@Override
public MvcMatchersAuthorizedUrl mvcMatchers(String... patterns) {
return mvcMatchers(null, patterns);
}
@Override
protected AuthorizedUrl chainRequestMatchersInternal(List<RequestMatcher> requestMatchers) {
return new AuthorizedUrl(requestMatchers);
}
/**
* Allows customization of the {@link SecurityExpressionHandler} to be used. The
* default is {@link DefaultWebSecurityExpressionHandler}
* @param expressionHandler the {@link SecurityExpressionHandler} to be used
* @return the {@link ExpressionUrlAuthorizationConfigurer} for further
* customization.
*/
public ExpressionInterceptUrlRegistry expressionHandler(
SecurityExpressionHandler<FilterInvocation> expressionHandler) {
ExpressionUrlAuthorizationConfigurer.this.expressionHandler = expressionHandler;
return this;
}
/**
* Adds an {@link ObjectPostProcessor} for this class.
* @param objectPostProcessor
* @return the {@link ExpressionUrlAuthorizationConfigurer} for further
* customizations
*/
public ExpressionInterceptUrlRegistry withObjectPostProcessor(ObjectPostProcessor<?> objectPostProcessor) {
addObjectPostProcessor(objectPostProcessor);
return this;
}
public H and() {
return ExpressionUrlAuthorizationConfigurer.this.and();
}
}
/**
* Allows registering multiple {@link RequestMatcher} instances to a collection of
* {@link ConfigAttribute} instances
@ -261,6 +206,61 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
return "hasIpAddress('" + ipAddressExpression + "')";
}
public final class ExpressionInterceptUrlRegistry extends
ExpressionUrlAuthorizationConfigurer<H>.AbstractInterceptUrlRegistry<ExpressionInterceptUrlRegistry, AuthorizedUrl> {
/**
* @param context
*/
private ExpressionInterceptUrlRegistry(ApplicationContext context) {
setApplicationContext(context);
}
@Override
public MvcMatchersAuthorizedUrl mvcMatchers(HttpMethod method, String... mvcPatterns) {
return new MvcMatchersAuthorizedUrl(createMvcMatchers(method, mvcPatterns));
}
@Override
public MvcMatchersAuthorizedUrl mvcMatchers(String... patterns) {
return mvcMatchers(null, patterns);
}
@Override
protected AuthorizedUrl chainRequestMatchersInternal(List<RequestMatcher> requestMatchers) {
return new AuthorizedUrl(requestMatchers);
}
/**
* Allows customization of the {@link SecurityExpressionHandler} to be used. The
* default is {@link DefaultWebSecurityExpressionHandler}
* @param expressionHandler the {@link SecurityExpressionHandler} to be used
* @return the {@link ExpressionUrlAuthorizationConfigurer} for further
* customization.
*/
public ExpressionInterceptUrlRegistry expressionHandler(
SecurityExpressionHandler<FilterInvocation> expressionHandler) {
ExpressionUrlAuthorizationConfigurer.this.expressionHandler = expressionHandler;
return this;
}
/**
* Adds an {@link ObjectPostProcessor} for this class.
* @param objectPostProcessor
* @return the {@link ExpressionUrlAuthorizationConfigurer} for further
* customizations
*/
public ExpressionInterceptUrlRegistry withObjectPostProcessor(ObjectPostProcessor<?> objectPostProcessor) {
addObjectPostProcessor(objectPostProcessor);
return this;
}
public H and() {
return ExpressionUrlAuthorizationConfigurer.this.and();
}
}
/**
* An {@link AuthorizedUrl} that allows optionally configuring the
* {@link MvcRequestMatcher#setMethod(HttpMethod)}

View File

@ -145,6 +145,357 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
return HeadersConfigurer.this;
}
/**
* <strong>Note this is not comprehensive XSS protection!</strong>
*
* <p>
* Allows customizing the {@link XXssProtectionHeaderWriter} which adds the <a href=
* "https://blogs.msdn.com/b/ieinternals/archive/2011/01/31/controlling-the-internet-explorer-xss-filter-with-the-x-xss-protection-http-header.aspx"
* >X-XSS-Protection header</a>
* </p>
* @return the {@link XXssConfig} for additional customizations
*/
public XXssConfig xssProtection() {
return this.xssProtection.enable();
}
/**
* <strong>Note this is not comprehensive XSS protection!</strong>
*
* <p>
* Allows customizing the {@link XXssProtectionHeaderWriter} which adds the <a href=
* "https://blogs.msdn.com/b/ieinternals/archive/2011/01/31/controlling-the-internet-explorer-xss-filter-with-the-x-xss-protection-http-header.aspx"
* >X-XSS-Protection header</a>
* </p>
* @param xssCustomizer the {@link Customizer} to provide more options for the
* {@link XXssConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> xssProtection(Customizer<XXssConfig> xssCustomizer) {
xssCustomizer.customize(this.xssProtection.enable());
return HeadersConfigurer.this;
}
/**
* Allows customizing the {@link CacheControlHeadersWriter}. Specifically it adds the
* following headers:
* <ul>
* <li>Cache-Control: no-cache, no-store, max-age=0, must-revalidate</li>
* <li>Pragma: no-cache</li>
* <li>Expires: 0</li>
* </ul>
* @return the {@link CacheControlConfig} for additional customizations
*/
public CacheControlConfig cacheControl() {
return this.cacheControl.enable();
}
/**
* Allows customizing the {@link CacheControlHeadersWriter}. Specifically it adds the
* following headers:
* <ul>
* <li>Cache-Control: no-cache, no-store, max-age=0, must-revalidate</li>
* <li>Pragma: no-cache</li>
* <li>Expires: 0</li>
* </ul>
* @param cacheControlCustomizer the {@link Customizer} to provide more options for
* the {@link CacheControlConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> cacheControl(Customizer<CacheControlConfig> cacheControlCustomizer) {
cacheControlCustomizer.customize(this.cacheControl.enable());
return HeadersConfigurer.this;
}
/**
* Allows customizing the {@link HstsHeaderWriter} which provides support for
* <a href="https://tools.ietf.org/html/rfc6797">HTTP Strict Transport Security
* (HSTS)</a>.
* @return the {@link HstsConfig} for additional customizations
*/
public HstsConfig httpStrictTransportSecurity() {
return this.hsts.enable();
}
/**
* Allows customizing the {@link HstsHeaderWriter} which provides support for
* <a href="https://tools.ietf.org/html/rfc6797">HTTP Strict Transport Security
* (HSTS)</a>.
* @param hstsCustomizer the {@link Customizer} to provide more options for the
* {@link HstsConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> httpStrictTransportSecurity(Customizer<HstsConfig> hstsCustomizer) {
hstsCustomizer.customize(this.hsts.enable());
return HeadersConfigurer.this;
}
/**
* Allows customizing the {@link XFrameOptionsHeaderWriter}.
* @return the {@link FrameOptionsConfig} for additional customizations
*/
public FrameOptionsConfig frameOptions() {
return this.frameOptions.enable();
}
/**
* Allows customizing the {@link XFrameOptionsHeaderWriter}.
* @param frameOptionsCustomizer the {@link Customizer} to provide more options for
* the {@link FrameOptionsConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> frameOptions(Customizer<FrameOptionsConfig> frameOptionsCustomizer) {
frameOptionsCustomizer.customize(this.frameOptions.enable());
return HeadersConfigurer.this;
}
/**
* Allows customizing the {@link HpkpHeaderWriter} which provides support for
* <a href="https://tools.ietf.org/html/rfc7469">HTTP Public Key Pinning (HPKP)</a>.
* @return the {@link HpkpConfig} for additional customizations
*
* @since 4.1
*/
public HpkpConfig httpPublicKeyPinning() {
return this.hpkp.enable();
}
/**
* Allows customizing the {@link HpkpHeaderWriter} which provides support for
* <a href="https://tools.ietf.org/html/rfc7469">HTTP Public Key Pinning (HPKP)</a>.
* @param hpkpCustomizer the {@link Customizer} to provide more options for the
* {@link HpkpConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> httpPublicKeyPinning(Customizer<HpkpConfig> hpkpCustomizer) {
hpkpCustomizer.customize(this.hpkp.enable());
return HeadersConfigurer.this;
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/CSP2/">Content Security
* Policy (CSP) Level 2</a>.
* </p>
*
* <p>
* Calling this method automatically enables (includes) the Content-Security-Policy
* header in the response using the supplied security policy directive(s).
* </p>
*
* <p>
* Configuration is provided to the {@link ContentSecurityPolicyHeaderWriter} which
* supports the writing of the two headers as detailed in the W3C Candidate
* Recommendation:
* </p>
* <ul>
* <li>Content-Security-Policy</li>
* <li>Content-Security-Policy-Report-Only</li>
* </ul>
* @return the {@link ContentSecurityPolicyConfig} for additional configuration
* @throws IllegalArgumentException if policyDirectives is null or empty
* @since 4.1
* @see ContentSecurityPolicyHeaderWriter
*/
public ContentSecurityPolicyConfig contentSecurityPolicy(String policyDirectives) {
this.contentSecurityPolicy.writer = new ContentSecurityPolicyHeaderWriter(policyDirectives);
return this.contentSecurityPolicy;
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/CSP2/">Content Security
* Policy (CSP) Level 2</a>.
* </p>
*
* <p>
* Calling this method automatically enables (includes) the Content-Security-Policy
* header in the response using the supplied security policy directive(s).
* </p>
*
* <p>
* Configuration is provided to the {@link ContentSecurityPolicyHeaderWriter} which
* supports the writing of the two headers as detailed in the W3C Candidate
* Recommendation:
* </p>
* <ul>
* <li>Content-Security-Policy</li>
* <li>Content-Security-Policy-Report-Only</li>
* </ul>
* @param contentSecurityCustomizer the {@link Customizer} to provide more options for
* the {@link ContentSecurityPolicyConfig}
* @return the {@link HeadersConfigurer} for additional customizations
* @see ContentSecurityPolicyHeaderWriter
*/
public HeadersConfigurer<H> contentSecurityPolicy(
Customizer<ContentSecurityPolicyConfig> contentSecurityCustomizer) {
this.contentSecurityPolicy.writer = new ContentSecurityPolicyHeaderWriter();
contentSecurityCustomizer.customize(this.contentSecurityPolicy);
return HeadersConfigurer.this;
}
/**
* Clears all of the default headers from the response. After doing so, one can add
* headers back. For example, if you only want to use Spring Security's cache control
* you can use the following:
*
* <pre>
* http.headers().defaultsDisabled().cacheControl();
* </pre>
* @return the {@link HeadersConfigurer} for additional customization
*/
public HeadersConfigurer<H> defaultsDisabled() {
this.contentTypeOptions.disable();
this.xssProtection.disable();
this.cacheControl.disable();
this.hsts.disable();
this.frameOptions.disable();
return this;
}
@Override
public void configure(H http) {
HeaderWriterFilter headersFilter = createHeaderWriterFilter();
http.addFilter(headersFilter);
}
/**
* Creates the {@link HeaderWriter}
* @return the {@link HeaderWriter}
*/
private HeaderWriterFilter createHeaderWriterFilter() {
List<HeaderWriter> writers = getHeaderWriters();
if (writers.isEmpty()) {
throw new IllegalStateException(
"Headers security is enabled, but no headers will be added. Either add headers or disable headers security");
}
HeaderWriterFilter headersFilter = new HeaderWriterFilter(writers);
headersFilter = postProcess(headersFilter);
return headersFilter;
}
/**
* Gets the {@link HeaderWriter} instances and possibly initializes with the defaults.
* @return
*/
private List<HeaderWriter> getHeaderWriters() {
List<HeaderWriter> writers = new ArrayList<>();
addIfNotNull(writers, this.contentTypeOptions.writer);
addIfNotNull(writers, this.xssProtection.writer);
addIfNotNull(writers, this.cacheControl.writer);
addIfNotNull(writers, this.hsts.writer);
addIfNotNull(writers, this.frameOptions.writer);
addIfNotNull(writers, this.hpkp.writer);
addIfNotNull(writers, this.contentSecurityPolicy.writer);
addIfNotNull(writers, this.referrerPolicy.writer);
addIfNotNull(writers, this.featurePolicy.writer);
writers.addAll(this.headerWriters);
return writers;
}
private <T> void addIfNotNull(List<T> values, T value) {
if (value != null) {
values.add(value);
}
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/referrer-policy/">Referrer
* Policy</a>.
* </p>
*
* <p>
* Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support
* the writing of the header as detailed in the W3C Technical Report:
* </p>
* <ul>
* <li>Referrer-Policy</li>
* </ul>
*
* <p>
* Default value is:
* </p>
*
* <pre>
* Referrer-Policy: no-referrer
* </pre>
* @return the {@link ReferrerPolicyConfig} for additional configuration
* @since 4.2
* @see ReferrerPolicyHeaderWriter
*/
public ReferrerPolicyConfig referrerPolicy() {
this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter();
return this.referrerPolicy;
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/referrer-policy/">Referrer
* Policy</a>.
* </p>
*
* <p>
* Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support
* the writing of the header as detailed in the W3C Technical Report:
* </p>
* <ul>
* <li>Referrer-Policy</li>
* </ul>
* @return the {@link ReferrerPolicyConfig} for additional configuration
* @throws IllegalArgumentException if policy is null or empty
* @since 4.2
* @see ReferrerPolicyHeaderWriter
*/
public ReferrerPolicyConfig referrerPolicy(ReferrerPolicy policy) {
this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter(policy);
return this.referrerPolicy;
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/referrer-policy/">Referrer
* Policy</a>.
* </p>
*
* <p>
* Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support
* the writing of the header as detailed in the W3C Technical Report:
* </p>
* <ul>
* <li>Referrer-Policy</li>
* </ul>
* @param referrerPolicyCustomizer the {@link Customizer} to provide more options for
* the {@link ReferrerPolicyConfig}
* @return the {@link HeadersConfigurer} for additional customizations
* @see ReferrerPolicyHeaderWriter
*/
public HeadersConfigurer<H> referrerPolicy(Customizer<ReferrerPolicyConfig> referrerPolicyCustomizer) {
this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter();
referrerPolicyCustomizer.customize(this.referrerPolicy);
return HeadersConfigurer.this;
}
/**
* Allows configuration for <a href="https://wicg.github.io/feature-policy/">Feature
* Policy</a>.
* <p>
* Calling this method automatically enables (includes) the {@code Feature-Policy}
* header in the response using the supplied policy directive(s).
* <p>
* Configuration is provided to the {@link FeaturePolicyHeaderWriter} which is
* responsible for writing the header.
* @return the {@link FeaturePolicyConfig} for additional configuration
* @throws IllegalArgumentException if policyDirectives is {@code null} or empty
* @since 5.1
* @see FeaturePolicyHeaderWriter
*/
public FeaturePolicyConfig featurePolicy(String policyDirectives) {
this.featurePolicy.writer = new FeaturePolicyHeaderWriter(policyDirectives);
return this.featurePolicy;
}
public final class ContentTypeOptionsConfig {
private XContentTypeOptionsHeaderWriter writer;
@ -183,37 +534,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
/**
* <strong>Note this is not comprehensive XSS protection!</strong>
*
* <p>
* Allows customizing the {@link XXssProtectionHeaderWriter} which adds the <a href=
* "https://blogs.msdn.com/b/ieinternals/archive/2011/01/31/controlling-the-internet-explorer-xss-filter-with-the-x-xss-protection-http-header.aspx"
* >X-XSS-Protection header</a>
* </p>
* @return the {@link XXssConfig} for additional customizations
*/
public XXssConfig xssProtection() {
return this.xssProtection.enable();
}
/**
* <strong>Note this is not comprehensive XSS protection!</strong>
*
* <p>
* Allows customizing the {@link XXssProtectionHeaderWriter} which adds the <a href=
* "https://blogs.msdn.com/b/ieinternals/archive/2011/01/31/controlling-the-internet-explorer-xss-filter-with-the-x-xss-protection-http-header.aspx"
* >X-XSS-Protection header</a>
* </p>
* @param xssCustomizer the {@link Customizer} to provide more options for the
* {@link XXssConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> xssProtection(Customizer<XXssConfig> xssCustomizer) {
xssCustomizer.customize(this.xssProtection.enable());
return HeadersConfigurer.this;
}
public final class XXssConfig {
private XXssProtectionHeaderWriter writer;
@ -291,37 +611,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
/**
* Allows customizing the {@link CacheControlHeadersWriter}. Specifically it adds the
* following headers:
* <ul>
* <li>Cache-Control: no-cache, no-store, max-age=0, must-revalidate</li>
* <li>Pragma: no-cache</li>
* <li>Expires: 0</li>
* </ul>
* @return the {@link CacheControlConfig} for additional customizations
*/
public CacheControlConfig cacheControl() {
return this.cacheControl.enable();
}
/**
* Allows customizing the {@link CacheControlHeadersWriter}. Specifically it adds the
* following headers:
* <ul>
* <li>Cache-Control: no-cache, no-store, max-age=0, must-revalidate</li>
* <li>Pragma: no-cache</li>
* <li>Expires: 0</li>
* </ul>
* @param cacheControlCustomizer the {@link Customizer} to provide more options for
* the {@link CacheControlConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> cacheControl(Customizer<CacheControlConfig> cacheControlCustomizer) {
cacheControlCustomizer.customize(this.cacheControl.enable());
return HeadersConfigurer.this;
}
public final class CacheControlConfig {
private CacheControlHeadersWriter writer;
@ -361,29 +650,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
/**
* Allows customizing the {@link HstsHeaderWriter} which provides support for
* <a href="https://tools.ietf.org/html/rfc6797">HTTP Strict Transport Security
* (HSTS)</a>.
* @return the {@link HstsConfig} for additional customizations
*/
public HstsConfig httpStrictTransportSecurity() {
return this.hsts.enable();
}
/**
* Allows customizing the {@link HstsHeaderWriter} which provides support for
* <a href="https://tools.ietf.org/html/rfc6797">HTTP Strict Transport Security
* (HSTS)</a>.
* @param hstsCustomizer the {@link Customizer} to provide more options for the
* {@link HstsConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> httpStrictTransportSecurity(Customizer<HstsConfig> hstsCustomizer) {
hstsCustomizer.customize(this.hsts.enable());
return HeadersConfigurer.this;
}
public final class HstsConfig {
private HstsHeaderWriter writer;
@ -491,25 +757,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
/**
* Allows customizing the {@link XFrameOptionsHeaderWriter}.
* @return the {@link FrameOptionsConfig} for additional customizations
*/
public FrameOptionsConfig frameOptions() {
return this.frameOptions.enable();
}
/**
* Allows customizing the {@link XFrameOptionsHeaderWriter}.
* @param frameOptionsCustomizer the {@link Customizer} to provide more options for
* the {@link FrameOptionsConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> frameOptions(Customizer<FrameOptionsConfig> frameOptionsCustomizer) {
frameOptionsCustomizer.customize(this.frameOptions.enable());
return HeadersConfigurer.this;
}
public final class FrameOptionsConfig {
private XFrameOptionsHeaderWriter writer;
@ -571,29 +818,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
/**
* Allows customizing the {@link HpkpHeaderWriter} which provides support for
* <a href="https://tools.ietf.org/html/rfc7469">HTTP Public Key Pinning (HPKP)</a>.
* @return the {@link HpkpConfig} for additional customizations
*
* @since 4.1
*/
public HpkpConfig httpPublicKeyPinning() {
return this.hpkp.enable();
}
/**
* Allows customizing the {@link HpkpHeaderWriter} which provides support for
* <a href="https://tools.ietf.org/html/rfc7469">HTTP Public Key Pinning (HPKP)</a>.
* @param hpkpCustomizer the {@link Customizer} to provide more options for the
* {@link HpkpConfig}
* @return the {@link HeadersConfigurer} for additional customizations
*/
public HeadersConfigurer<H> httpPublicKeyPinning(Customizer<HpkpConfig> hpkpCustomizer) {
hpkpCustomizer.customize(this.hpkp.enable());
return HeadersConfigurer.this;
}
public final class HpkpConfig {
private HpkpHeaderWriter writer;
@ -761,69 +985,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/CSP2/">Content Security
* Policy (CSP) Level 2</a>.
* </p>
*
* <p>
* Calling this method automatically enables (includes) the Content-Security-Policy
* header in the response using the supplied security policy directive(s).
* </p>
*
* <p>
* Configuration is provided to the {@link ContentSecurityPolicyHeaderWriter} which
* supports the writing of the two headers as detailed in the W3C Candidate
* Recommendation:
* </p>
* <ul>
* <li>Content-Security-Policy</li>
* <li>Content-Security-Policy-Report-Only</li>
* </ul>
* @return the {@link ContentSecurityPolicyConfig} for additional configuration
* @throws IllegalArgumentException if policyDirectives is null or empty
* @since 4.1
* @see ContentSecurityPolicyHeaderWriter
*/
public ContentSecurityPolicyConfig contentSecurityPolicy(String policyDirectives) {
this.contentSecurityPolicy.writer = new ContentSecurityPolicyHeaderWriter(policyDirectives);
return this.contentSecurityPolicy;
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/CSP2/">Content Security
* Policy (CSP) Level 2</a>.
* </p>
*
* <p>
* Calling this method automatically enables (includes) the Content-Security-Policy
* header in the response using the supplied security policy directive(s).
* </p>
*
* <p>
* Configuration is provided to the {@link ContentSecurityPolicyHeaderWriter} which
* supports the writing of the two headers as detailed in the W3C Candidate
* Recommendation:
* </p>
* <ul>
* <li>Content-Security-Policy</li>
* <li>Content-Security-Policy-Report-Only</li>
* </ul>
* @param contentSecurityCustomizer the {@link Customizer} to provide more options for
* the {@link ContentSecurityPolicyConfig}
* @return the {@link HeadersConfigurer} for additional customizations
* @see ContentSecurityPolicyHeaderWriter
*/
public HeadersConfigurer<H> contentSecurityPolicy(
Customizer<ContentSecurityPolicyConfig> contentSecurityCustomizer) {
this.contentSecurityPolicy.writer = new ContentSecurityPolicyHeaderWriter();
contentSecurityCustomizer.customize(this.contentSecurityPolicy);
return HeadersConfigurer.this;
}
public final class ContentSecurityPolicyConfig {
private ContentSecurityPolicyHeaderWriter writer;
@ -863,148 +1024,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
/**
* Clears all of the default headers from the response. After doing so, one can add
* headers back. For example, if you only want to use Spring Security's cache control
* you can use the following:
*
* <pre>
* http.headers().defaultsDisabled().cacheControl();
* </pre>
* @return the {@link HeadersConfigurer} for additional customization
*/
public HeadersConfigurer<H> defaultsDisabled() {
this.contentTypeOptions.disable();
this.xssProtection.disable();
this.cacheControl.disable();
this.hsts.disable();
this.frameOptions.disable();
return this;
}
@Override
public void configure(H http) {
HeaderWriterFilter headersFilter = createHeaderWriterFilter();
http.addFilter(headersFilter);
}
/**
* Creates the {@link HeaderWriter}
* @return the {@link HeaderWriter}
*/
private HeaderWriterFilter createHeaderWriterFilter() {
List<HeaderWriter> writers = getHeaderWriters();
if (writers.isEmpty()) {
throw new IllegalStateException(
"Headers security is enabled, but no headers will be added. Either add headers or disable headers security");
}
HeaderWriterFilter headersFilter = new HeaderWriterFilter(writers);
headersFilter = postProcess(headersFilter);
return headersFilter;
}
/**
* Gets the {@link HeaderWriter} instances and possibly initializes with the defaults.
* @return
*/
private List<HeaderWriter> getHeaderWriters() {
List<HeaderWriter> writers = new ArrayList<>();
addIfNotNull(writers, this.contentTypeOptions.writer);
addIfNotNull(writers, this.xssProtection.writer);
addIfNotNull(writers, this.cacheControl.writer);
addIfNotNull(writers, this.hsts.writer);
addIfNotNull(writers, this.frameOptions.writer);
addIfNotNull(writers, this.hpkp.writer);
addIfNotNull(writers, this.contentSecurityPolicy.writer);
addIfNotNull(writers, this.referrerPolicy.writer);
addIfNotNull(writers, this.featurePolicy.writer);
writers.addAll(this.headerWriters);
return writers;
}
private <T> void addIfNotNull(List<T> values, T value) {
if (value != null) {
values.add(value);
}
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/referrer-policy/">Referrer
* Policy</a>.
* </p>
*
* <p>
* Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support
* the writing of the header as detailed in the W3C Technical Report:
* </p>
* <ul>
* <li>Referrer-Policy</li>
* </ul>
*
* <p>
* Default value is:
* </p>
*
* <pre>
* Referrer-Policy: no-referrer
* </pre>
* @return the {@link ReferrerPolicyConfig} for additional configuration
* @since 4.2
* @see ReferrerPolicyHeaderWriter
*/
public ReferrerPolicyConfig referrerPolicy() {
this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter();
return this.referrerPolicy;
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/referrer-policy/">Referrer
* Policy</a>.
* </p>
*
* <p>
* Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support
* the writing of the header as detailed in the W3C Technical Report:
* </p>
* <ul>
* <li>Referrer-Policy</li>
* </ul>
* @return the {@link ReferrerPolicyConfig} for additional configuration
* @throws IllegalArgumentException if policy is null or empty
* @since 4.2
* @see ReferrerPolicyHeaderWriter
*/
public ReferrerPolicyConfig referrerPolicy(ReferrerPolicy policy) {
this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter(policy);
return this.referrerPolicy;
}
/**
* <p>
* Allows configuration for <a href="https://www.w3.org/TR/referrer-policy/">Referrer
* Policy</a>.
* </p>
*
* <p>
* Configuration is provided to the {@link ReferrerPolicyHeaderWriter} which support
* the writing of the header as detailed in the W3C Technical Report:
* </p>
* <ul>
* <li>Referrer-Policy</li>
* </ul>
* @param referrerPolicyCustomizer the {@link Customizer} to provide more options for
* the {@link ReferrerPolicyConfig}
* @return the {@link HeadersConfigurer} for additional customizations
* @see ReferrerPolicyHeaderWriter
*/
public HeadersConfigurer<H> referrerPolicy(Customizer<ReferrerPolicyConfig> referrerPolicyCustomizer) {
this.referrerPolicy.writer = new ReferrerPolicyHeaderWriter();
referrerPolicyCustomizer.customize(this.referrerPolicy);
return HeadersConfigurer.this;
}
public final class ReferrerPolicyConfig {
private ReferrerPolicyHeaderWriter writer;
@ -1029,25 +1048,6 @@ public class HeadersConfigurer<H extends HttpSecurityBuilder<H>>
}
/**
* Allows configuration for <a href="https://wicg.github.io/feature-policy/">Feature
* Policy</a>.
* <p>
* Calling this method automatically enables (includes) the {@code Feature-Policy}
* header in the response using the supplied policy directive(s).
* <p>
* Configuration is provided to the {@link FeaturePolicyHeaderWriter} which is
* responsible for writing the header.
* @return the {@link FeaturePolicyConfig} for additional configuration
* @throws IllegalArgumentException if policyDirectives is {@code null} or empty
* @since 5.1
* @see FeaturePolicyHeaderWriter
*/
public FeaturePolicyConfig featurePolicy(String policyDirectives) {
this.featurePolicy.writer = new FeaturePolicyHeaderWriter(policyDirectives);
return this.featurePolicy;
}
public final class FeaturePolicyConfig {
private FeaturePolicyHeaderWriter writer;

View File

@ -311,144 +311,6 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
this.sessionFixationAuthenticationStrategy = postProcess(sessionFixationAuthenticationStrategy);
}
/**
* Allows configuring SessionFixation protection
*
* @author Rob Winch
*/
public final class SessionFixationConfigurer {
/**
* Specifies that a new session should be created, but the session attributes from
* the original {@link HttpSession} should not be retained.
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> newSession() {
SessionFixationProtectionStrategy sessionFixationProtectionStrategy = new SessionFixationProtectionStrategy();
sessionFixationProtectionStrategy.setMigrateSessionAttributes(false);
setSessionFixationAuthenticationStrategy(sessionFixationProtectionStrategy);
return SessionManagementConfigurer.this;
}
/**
* Specifies that a new session should be created and the session attributes from
* the original {@link HttpSession} should be retained.
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> migrateSession() {
setSessionFixationAuthenticationStrategy(new SessionFixationProtectionStrategy());
return SessionManagementConfigurer.this;
}
/**
* Specifies that the Servlet container-provided session fixation protection
* should be used. When a session authenticates, the Servlet method
* {@code HttpServletRequest#changeSessionId()} is called to change the session ID
* and retain all session attributes.
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> changeSessionId() {
setSessionFixationAuthenticationStrategy(new ChangeSessionIdAuthenticationStrategy());
return SessionManagementConfigurer.this;
}
/**
* Specifies that no session fixation protection should be enabled. This may be
* useful when utilizing other mechanisms for protecting against session fixation.
* For example, if application container session fixation protection is already in
* use. Otherwise, this option is not recommended.
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> none() {
setSessionFixationAuthenticationStrategy(new NullAuthenticatedSessionStrategy());
return SessionManagementConfigurer.this;
}
}
/**
* Allows configuring controlling of multiple sessions.
*
* @author Rob Winch
*/
public final class ConcurrencyControlConfigurer {
/**
* Controls the maximum number of sessions for a user. The default is to allow any
* number of users.
* @param maximumSessions the maximum number of sessions for a user
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer maximumSessions(int maximumSessions) {
SessionManagementConfigurer.this.maximumSessions = maximumSessions;
return this;
}
/**
* The URL to redirect to if a user tries to access a resource and their session
* has been expired due to too many sessions for the current user. The default is
* to write a simple error message to the response.
* @param expiredUrl the URL to redirect to
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer expiredUrl(String expiredUrl) {
SessionManagementConfigurer.this.expiredUrl = expiredUrl;
return this;
}
/**
* Determines the behaviour when an expired session is detected.
* @param expiredSessionStrategy the {@link SessionInformationExpiredStrategy} to
* use when an expired session is detected.
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer expiredSessionStrategy(
SessionInformationExpiredStrategy expiredSessionStrategy) {
SessionManagementConfigurer.this.expiredSessionStrategy = expiredSessionStrategy;
return this;
}
/**
* If true, prevents a user from authenticating when the
* {@link #maximumSessions(int)} has been reached. Otherwise (default), the user
* who authenticates is allowed access and an existing user's session is expired.
* The user's who's session is forcibly expired is sent to
* {@link #expiredUrl(String)}. The advantage of this approach is if a user
* accidentally does not log out, there is no need for an administrator to
* intervene or wait till their session expires.
* @param maxSessionsPreventsLogin true to have an error at time of
* authentication, else false (default)
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer maxSessionsPreventsLogin(boolean maxSessionsPreventsLogin) {
SessionManagementConfigurer.this.maxSessionsPreventsLogin = maxSessionsPreventsLogin;
return this;
}
/**
* Controls the {@link SessionRegistry} implementation used. The default is
* {@link SessionRegistryImpl} which is an in memory implementation.
* @param sessionRegistry the {@link SessionRegistry} to use
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer sessionRegistry(SessionRegistry sessionRegistry) {
SessionManagementConfigurer.this.sessionRegistry = sessionRegistry;
return this;
}
/**
* Used to chain back to the {@link SessionManagementConfigurer}
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> and() {
return SessionManagementConfigurer.this;
}
private ConcurrencyControlConfigurer() {
}
}
@Override
public void init(H http) {
SecurityContextRepository securityContextRepository = http.getSharedObject(SecurityContextRepository.class);
@ -703,4 +565,142 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
}
}
/**
* Allows configuring SessionFixation protection
*
* @author Rob Winch
*/
public final class SessionFixationConfigurer {
/**
* Specifies that a new session should be created, but the session attributes from
* the original {@link HttpSession} should not be retained.
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> newSession() {
SessionFixationProtectionStrategy sessionFixationProtectionStrategy = new SessionFixationProtectionStrategy();
sessionFixationProtectionStrategy.setMigrateSessionAttributes(false);
setSessionFixationAuthenticationStrategy(sessionFixationProtectionStrategy);
return SessionManagementConfigurer.this;
}
/**
* Specifies that a new session should be created and the session attributes from
* the original {@link HttpSession} should be retained.
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> migrateSession() {
setSessionFixationAuthenticationStrategy(new SessionFixationProtectionStrategy());
return SessionManagementConfigurer.this;
}
/**
* Specifies that the Servlet container-provided session fixation protection
* should be used. When a session authenticates, the Servlet method
* {@code HttpServletRequest#changeSessionId()} is called to change the session ID
* and retain all session attributes.
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> changeSessionId() {
setSessionFixationAuthenticationStrategy(new ChangeSessionIdAuthenticationStrategy());
return SessionManagementConfigurer.this;
}
/**
* Specifies that no session fixation protection should be enabled. This may be
* useful when utilizing other mechanisms for protecting against session fixation.
* For example, if application container session fixation protection is already in
* use. Otherwise, this option is not recommended.
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> none() {
setSessionFixationAuthenticationStrategy(new NullAuthenticatedSessionStrategy());
return SessionManagementConfigurer.this;
}
}
/**
* Allows configuring controlling of multiple sessions.
*
* @author Rob Winch
*/
public final class ConcurrencyControlConfigurer {
/**
* Controls the maximum number of sessions for a user. The default is to allow any
* number of users.
* @param maximumSessions the maximum number of sessions for a user
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer maximumSessions(int maximumSessions) {
SessionManagementConfigurer.this.maximumSessions = maximumSessions;
return this;
}
/**
* The URL to redirect to if a user tries to access a resource and their session
* has been expired due to too many sessions for the current user. The default is
* to write a simple error message to the response.
* @param expiredUrl the URL to redirect to
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer expiredUrl(String expiredUrl) {
SessionManagementConfigurer.this.expiredUrl = expiredUrl;
return this;
}
/**
* Determines the behaviour when an expired session is detected.
* @param expiredSessionStrategy the {@link SessionInformationExpiredStrategy} to
* use when an expired session is detected.
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer expiredSessionStrategy(
SessionInformationExpiredStrategy expiredSessionStrategy) {
SessionManagementConfigurer.this.expiredSessionStrategy = expiredSessionStrategy;
return this;
}
/**
* If true, prevents a user from authenticating when the
* {@link #maximumSessions(int)} has been reached. Otherwise (default), the user
* who authenticates is allowed access and an existing user's session is expired.
* The user's who's session is forcibly expired is sent to
* {@link #expiredUrl(String)}. The advantage of this approach is if a user
* accidentally does not log out, there is no need for an administrator to
* intervene or wait till their session expires.
* @param maxSessionsPreventsLogin true to have an error at time of
* authentication, else false (default)
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer maxSessionsPreventsLogin(boolean maxSessionsPreventsLogin) {
SessionManagementConfigurer.this.maxSessionsPreventsLogin = maxSessionsPreventsLogin;
return this;
}
/**
* Controls the {@link SessionRegistry} implementation used. The default is
* {@link SessionRegistryImpl} which is an in memory implementation.
* @param sessionRegistry the {@link SessionRegistry} to use
* @return the {@link ConcurrencyControlConfigurer} for further customizations
*/
public ConcurrencyControlConfigurer sessionRegistry(SessionRegistry sessionRegistry) {
SessionManagementConfigurer.this.sessionRegistry = sessionRegistry;
return this;
}
/**
* Used to chain back to the {@link SessionManagementConfigurer}
* @return the {@link SessionManagementConfigurer} for further customizations
*/
public SessionManagementConfigurer<H> and() {
return SessionManagementConfigurer.this;
}
private ConcurrencyControlConfigurer() {
}
}
}

View File

@ -114,48 +114,6 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
return this;
}
public final class StandardInterceptUrlRegistry extends
ExpressionUrlAuthorizationConfigurer<H>.AbstractInterceptUrlRegistry<StandardInterceptUrlRegistry, AuthorizedUrl> {
/**
* @param context
*/
private StandardInterceptUrlRegistry(ApplicationContext context) {
setApplicationContext(context);
}
@Override
public MvcMatchersAuthorizedUrl mvcMatchers(HttpMethod method, String... mvcPatterns) {
return new MvcMatchersAuthorizedUrl(createMvcMatchers(method, mvcPatterns));
}
@Override
public MvcMatchersAuthorizedUrl mvcMatchers(String... patterns) {
return mvcMatchers(null, patterns);
}
@Override
protected AuthorizedUrl chainRequestMatchersInternal(List<RequestMatcher> requestMatchers) {
return new AuthorizedUrl(requestMatchers);
}
/**
* Adds an {@link ObjectPostProcessor} for this class.
* @param objectPostProcessor
* @return the {@link ExpressionUrlAuthorizationConfigurer} for further
* customizations
*/
public StandardInterceptUrlRegistry withObjectPostProcessor(ObjectPostProcessor<?> objectPostProcessor) {
addObjectPostProcessor(objectPostProcessor);
return this;
}
public H and() {
return UrlAuthorizationConfigurer.this.and();
}
}
/**
* Creates the default {@link AccessDecisionVoter} instances used if an
* {@link AccessDecisionManager} was not specified.
@ -234,6 +192,48 @@ public final class UrlAuthorizationConfigurer<H extends HttpSecurityBuilder<H>>
return authorities;
}
public final class StandardInterceptUrlRegistry extends
ExpressionUrlAuthorizationConfigurer<H>.AbstractInterceptUrlRegistry<StandardInterceptUrlRegistry, AuthorizedUrl> {
/**
* @param context
*/
private StandardInterceptUrlRegistry(ApplicationContext context) {
setApplicationContext(context);
}
@Override
public MvcMatchersAuthorizedUrl mvcMatchers(HttpMethod method, String... mvcPatterns) {
return new MvcMatchersAuthorizedUrl(createMvcMatchers(method, mvcPatterns));
}
@Override
public MvcMatchersAuthorizedUrl mvcMatchers(String... patterns) {
return mvcMatchers(null, patterns);
}
@Override
protected AuthorizedUrl chainRequestMatchersInternal(List<RequestMatcher> requestMatchers) {
return new AuthorizedUrl(requestMatchers);
}
/**
* Adds an {@link ObjectPostProcessor} for this class.
* @param objectPostProcessor
* @return the {@link ExpressionUrlAuthorizationConfigurer} for further
* customizations
*/
public StandardInterceptUrlRegistry withObjectPostProcessor(ObjectPostProcessor<?> objectPostProcessor) {
addObjectPostProcessor(objectPostProcessor);
return this;
}
public H and() {
return UrlAuthorizationConfigurer.this.and();
}
}
/**
* An {@link AuthorizedUrl} that allows optionally configuring the
* {@link MvcRequestMatcher#setMethod(HttpMethod)}

View File

@ -151,6 +151,16 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
return this;
}
@Override
public void init(B builder) {
this.authorizationCodeGrantConfigurer.init(builder);
}
@Override
public void configure(B builder) {
this.authorizationCodeGrantConfigurer.configure(builder);
}
/**
* Configuration options for the OAuth 2.0 Authorization Code Grant.
*/
@ -281,14 +291,4 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
}
@Override
public void init(B builder) {
this.authorizationCodeGrantConfigurer.init(builder);
}
@Override
public void configure(B builder) {
this.authorizationCodeGrantConfigurer.configure(builder);
}
}

View File

@ -221,69 +221,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return this;
}
/**
* Configuration options for the Authorization Server's Authorization Endpoint.
*/
public final class AuthorizationEndpointConfig {
private String authorizationRequestBaseUri;
private OAuth2AuthorizationRequestResolver authorizationRequestResolver;
private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository;
private AuthorizationEndpointConfig() {
}
/**
* Sets the base {@code URI} used for authorization requests.
* @param authorizationRequestBaseUri the base {@code URI} used for authorization
* requests
* @return the {@link AuthorizationEndpointConfig} for further configuration
*/
public AuthorizationEndpointConfig baseUri(String authorizationRequestBaseUri) {
Assert.hasText(authorizationRequestBaseUri, "authorizationRequestBaseUri cannot be empty");
this.authorizationRequestBaseUri = authorizationRequestBaseUri;
return this;
}
/**
* Sets the resolver used for resolving {@link OAuth2AuthorizationRequest}'s.
* @param authorizationRequestResolver the resolver used for resolving
* {@link OAuth2AuthorizationRequest}'s
* @return the {@link AuthorizationEndpointConfig} for further configuration
* @since 5.1
*/
public AuthorizationEndpointConfig authorizationRequestResolver(
OAuth2AuthorizationRequestResolver authorizationRequestResolver) {
Assert.notNull(authorizationRequestResolver, "authorizationRequestResolver cannot be null");
this.authorizationRequestResolver = authorizationRequestResolver;
return this;
}
/**
* Sets the repository used for storing {@link OAuth2AuthorizationRequest}'s.
* @param authorizationRequestRepository the repository used for storing
* {@link OAuth2AuthorizationRequest}'s
* @return the {@link AuthorizationEndpointConfig} for further configuration
*/
public AuthorizationEndpointConfig authorizationRequestRepository(
AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
this.authorizationRequestRepository = authorizationRequestRepository;
return this;
}
/**
* Returns the {@link OAuth2LoginConfigurer} for further configuration.
* @return the {@link OAuth2LoginConfigurer}
*/
public OAuth2LoginConfigurer<B> and() {
return OAuth2LoginConfigurer.this;
}
}
/**
* Returns the {@link TokenEndpointConfig} for configuring the Authorization Server's
* Token Endpoint.
@ -305,41 +242,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return this;
}
/**
* Configuration options for the Authorization Server's Token Endpoint.
*/
public final class TokenEndpointConfig {
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient;
private TokenEndpointConfig() {
}
/**
* Sets the client used for requesting the access token credential from the Token
* Endpoint.
* @param accessTokenResponseClient the client used for requesting the access
* token credential from the Token Endpoint
* @return the {@link TokenEndpointConfig} for further configuration
*/
public TokenEndpointConfig accessTokenResponseClient(
OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient) {
Assert.notNull(accessTokenResponseClient, "accessTokenResponseClient cannot be null");
this.accessTokenResponseClient = accessTokenResponseClient;
return this;
}
/**
* Returns the {@link OAuth2LoginConfigurer} for further configuration.
* @return the {@link OAuth2LoginConfigurer}
*/
public OAuth2LoginConfigurer<B> and() {
return OAuth2LoginConfigurer.this;
}
}
/**
* Returns the {@link RedirectionEndpointConfig} for configuring the Client's
* Redirection Endpoint.
@ -361,38 +263,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return this;
}
/**
* Configuration options for the Client's Redirection Endpoint.
*/
public final class RedirectionEndpointConfig {
private String authorizationResponseBaseUri;
private RedirectionEndpointConfig() {
}
/**
* Sets the {@code URI} where the authorization response will be processed.
* @param authorizationResponseBaseUri the {@code URI} where the authorization
* response will be processed
* @return the {@link RedirectionEndpointConfig} for further configuration
*/
public RedirectionEndpointConfig baseUri(String authorizationResponseBaseUri) {
Assert.hasText(authorizationResponseBaseUri, "authorizationResponseBaseUri cannot be empty");
this.authorizationResponseBaseUri = authorizationResponseBaseUri;
return this;
}
/**
* Returns the {@link OAuth2LoginConfigurer} for further configuration.
* @return the {@link OAuth2LoginConfigurer}
*/
public OAuth2LoginConfigurer<B> and() {
return OAuth2LoginConfigurer.this;
}
}
/**
* Returns the {@link UserInfoEndpointConfig} for configuring the Authorization
* Server's UserInfo Endpoint.
@ -413,87 +283,6 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return this;
}
/**
* Configuration options for the Authorization Server's UserInfo Endpoint.
*/
public final class UserInfoEndpointConfig {
private OAuth2UserService<OAuth2UserRequest, OAuth2User> userService;
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
private Map<String, Class<? extends OAuth2User>> customUserTypes = new HashMap<>();
private UserInfoEndpointConfig() {
}
/**
* Sets the OAuth 2.0 service used for obtaining the user attributes of the
* End-User from the UserInfo Endpoint.
* @param userService the OAuth 2.0 service used for obtaining the user attributes
* of the End-User from the UserInfo Endpoint
* @return the {@link UserInfoEndpointConfig} for further configuration
*/
public UserInfoEndpointConfig userService(OAuth2UserService<OAuth2UserRequest, OAuth2User> userService) {
Assert.notNull(userService, "userService cannot be null");
this.userService = userService;
return this;
}
/**
* Sets the OpenID Connect 1.0 service used for obtaining the user attributes of
* the End-User from the UserInfo Endpoint.
* @param oidcUserService the OpenID Connect 1.0 service used for obtaining the
* user attributes of the End-User from the UserInfo Endpoint
* @return the {@link UserInfoEndpointConfig} for further configuration
*/
public UserInfoEndpointConfig oidcUserService(OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService) {
Assert.notNull(oidcUserService, "oidcUserService cannot be null");
this.oidcUserService = oidcUserService;
return this;
}
/**
* Sets a custom {@link OAuth2User} type and associates it to the provided client
* {@link ClientRegistration#getRegistrationId() registration identifier}.
* @deprecated See {@link CustomUserTypesOAuth2UserService} for alternative usage.
* @param customUserType a custom {@link OAuth2User} type
* @param clientRegistrationId the client registration identifier
* @return the {@link UserInfoEndpointConfig} for further configuration
*/
@Deprecated
public UserInfoEndpointConfig customUserType(Class<? extends OAuth2User> customUserType,
String clientRegistrationId) {
Assert.notNull(customUserType, "customUserType cannot be null");
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
this.customUserTypes.put(clientRegistrationId, customUserType);
return this;
}
/**
* Sets the {@link GrantedAuthoritiesMapper} used for mapping
* {@link OAuth2User#getAuthorities()}.
* @param userAuthoritiesMapper the {@link GrantedAuthoritiesMapper} used for
* mapping the user's authorities
* @return the {@link UserInfoEndpointConfig} for further configuration
*/
public UserInfoEndpointConfig userAuthoritiesMapper(GrantedAuthoritiesMapper userAuthoritiesMapper) {
Assert.notNull(userAuthoritiesMapper, "userAuthoritiesMapper cannot be null");
OAuth2LoginConfigurer.this.getBuilder().setSharedObject(GrantedAuthoritiesMapper.class,
userAuthoritiesMapper);
return this;
}
/**
* Returns the {@link OAuth2LoginConfigurer} for further configuration.
* @return the {@link OAuth2LoginConfigurer}
*/
public OAuth2LoginConfigurer<B> and() {
return OAuth2LoginConfigurer.this;
}
}
@Override
public void init(B http) throws Exception {
OAuth2LoginAuthenticationFilter authenticationFilter = new OAuth2LoginAuthenticationFilter(
@ -740,6 +529,217 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
return loginEntryPoint;
}
/**
* Configuration options for the Authorization Server's Authorization Endpoint.
*/
public final class AuthorizationEndpointConfig {
private String authorizationRequestBaseUri;
private OAuth2AuthorizationRequestResolver authorizationRequestResolver;
private AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository;
private AuthorizationEndpointConfig() {
}
/**
* Sets the base {@code URI} used for authorization requests.
* @param authorizationRequestBaseUri the base {@code URI} used for authorization
* requests
* @return the {@link AuthorizationEndpointConfig} for further configuration
*/
public AuthorizationEndpointConfig baseUri(String authorizationRequestBaseUri) {
Assert.hasText(authorizationRequestBaseUri, "authorizationRequestBaseUri cannot be empty");
this.authorizationRequestBaseUri = authorizationRequestBaseUri;
return this;
}
/**
* Sets the resolver used for resolving {@link OAuth2AuthorizationRequest}'s.
* @param authorizationRequestResolver the resolver used for resolving
* {@link OAuth2AuthorizationRequest}'s
* @return the {@link AuthorizationEndpointConfig} for further configuration
* @since 5.1
*/
public AuthorizationEndpointConfig authorizationRequestResolver(
OAuth2AuthorizationRequestResolver authorizationRequestResolver) {
Assert.notNull(authorizationRequestResolver, "authorizationRequestResolver cannot be null");
this.authorizationRequestResolver = authorizationRequestResolver;
return this;
}
/**
* Sets the repository used for storing {@link OAuth2AuthorizationRequest}'s.
* @param authorizationRequestRepository the repository used for storing
* {@link OAuth2AuthorizationRequest}'s
* @return the {@link AuthorizationEndpointConfig} for further configuration
*/
public AuthorizationEndpointConfig authorizationRequestRepository(
AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) {
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
this.authorizationRequestRepository = authorizationRequestRepository;
return this;
}
/**
* Returns the {@link OAuth2LoginConfigurer} for further configuration.
* @return the {@link OAuth2LoginConfigurer}
*/
public OAuth2LoginConfigurer<B> and() {
return OAuth2LoginConfigurer.this;
}
}
/**
* Configuration options for the Authorization Server's Token Endpoint.
*/
public final class TokenEndpointConfig {
private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient;
private TokenEndpointConfig() {
}
/**
* Sets the client used for requesting the access token credential from the Token
* Endpoint.
* @param accessTokenResponseClient the client used for requesting the access
* token credential from the Token Endpoint
* @return the {@link TokenEndpointConfig} for further configuration
*/
public TokenEndpointConfig accessTokenResponseClient(
OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient) {
Assert.notNull(accessTokenResponseClient, "accessTokenResponseClient cannot be null");
this.accessTokenResponseClient = accessTokenResponseClient;
return this;
}
/**
* Returns the {@link OAuth2LoginConfigurer} for further configuration.
* @return the {@link OAuth2LoginConfigurer}
*/
public OAuth2LoginConfigurer<B> and() {
return OAuth2LoginConfigurer.this;
}
}
/**
* Configuration options for the Client's Redirection Endpoint.
*/
public final class RedirectionEndpointConfig {
private String authorizationResponseBaseUri;
private RedirectionEndpointConfig() {
}
/**
* Sets the {@code URI} where the authorization response will be processed.
* @param authorizationResponseBaseUri the {@code URI} where the authorization
* response will be processed
* @return the {@link RedirectionEndpointConfig} for further configuration
*/
public RedirectionEndpointConfig baseUri(String authorizationResponseBaseUri) {
Assert.hasText(authorizationResponseBaseUri, "authorizationResponseBaseUri cannot be empty");
this.authorizationResponseBaseUri = authorizationResponseBaseUri;
return this;
}
/**
* Returns the {@link OAuth2LoginConfigurer} for further configuration.
* @return the {@link OAuth2LoginConfigurer}
*/
public OAuth2LoginConfigurer<B> and() {
return OAuth2LoginConfigurer.this;
}
}
/**
* Configuration options for the Authorization Server's UserInfo Endpoint.
*/
public final class UserInfoEndpointConfig {
private OAuth2UserService<OAuth2UserRequest, OAuth2User> userService;
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;
private Map<String, Class<? extends OAuth2User>> customUserTypes = new HashMap<>();
private UserInfoEndpointConfig() {
}
/**
* Sets the OAuth 2.0 service used for obtaining the user attributes of the
* End-User from the UserInfo Endpoint.
* @param userService the OAuth 2.0 service used for obtaining the user attributes
* of the End-User from the UserInfo Endpoint
* @return the {@link UserInfoEndpointConfig} for further configuration
*/
public UserInfoEndpointConfig userService(OAuth2UserService<OAuth2UserRequest, OAuth2User> userService) {
Assert.notNull(userService, "userService cannot be null");
this.userService = userService;
return this;
}
/**
* Sets the OpenID Connect 1.0 service used for obtaining the user attributes of
* the End-User from the UserInfo Endpoint.
* @param oidcUserService the OpenID Connect 1.0 service used for obtaining the
* user attributes of the End-User from the UserInfo Endpoint
* @return the {@link UserInfoEndpointConfig} for further configuration
*/
public UserInfoEndpointConfig oidcUserService(OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService) {
Assert.notNull(oidcUserService, "oidcUserService cannot be null");
this.oidcUserService = oidcUserService;
return this;
}
/**
* Sets a custom {@link OAuth2User} type and associates it to the provided client
* {@link ClientRegistration#getRegistrationId() registration identifier}.
* @deprecated See {@link CustomUserTypesOAuth2UserService} for alternative usage.
* @param customUserType a custom {@link OAuth2User} type
* @param clientRegistrationId the client registration identifier
* @return the {@link UserInfoEndpointConfig} for further configuration
*/
@Deprecated
public UserInfoEndpointConfig customUserType(Class<? extends OAuth2User> customUserType,
String clientRegistrationId) {
Assert.notNull(customUserType, "customUserType cannot be null");
Assert.hasText(clientRegistrationId, "clientRegistrationId cannot be empty");
this.customUserTypes.put(clientRegistrationId, customUserType);
return this;
}
/**
* Sets the {@link GrantedAuthoritiesMapper} used for mapping
* {@link OAuth2User#getAuthorities()}.
* @param userAuthoritiesMapper the {@link GrantedAuthoritiesMapper} used for
* mapping the user's authorities
* @return the {@link UserInfoEndpointConfig} for further configuration
*/
public UserInfoEndpointConfig userAuthoritiesMapper(GrantedAuthoritiesMapper userAuthoritiesMapper) {
Assert.notNull(userAuthoritiesMapper, "userAuthoritiesMapper cannot be null");
OAuth2LoginConfigurer.this.getBuilder().setSharedObject(GrantedAuthoritiesMapper.class,
userAuthoritiesMapper);
return this;
}
/**
* Returns the {@link OAuth2LoginConfigurer} for further configuration.
* @return the {@link OAuth2LoginConfigurer}
*/
public OAuth2LoginConfigurer<B> and() {
return OAuth2LoginConfigurer.this;
}
}
private static class OidcAuthenticationRequestChecker implements AuthenticationProvider {
@Override

View File

@ -277,6 +277,70 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
}
}
private void registerDefaultAccessDeniedHandler(H http) {
ExceptionHandlingConfigurer<H> exceptionHandling = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptionHandling == null) {
return;
}
exceptionHandling.defaultAccessDeniedHandlerFor(this.accessDeniedHandler, this.requestMatcher);
}
private void registerDefaultEntryPoint(H http) {
ExceptionHandlingConfigurer<H> exceptionHandling = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptionHandling == null) {
return;
}
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, this.requestMatcher);
}
private void registerDefaultCsrfOverride(H http) {
CsrfConfigurer<H> csrf = http.getConfigurer(CsrfConfigurer.class);
if (csrf == null) {
return;
}
csrf.ignoringRequestMatchers(this.requestMatcher);
}
AuthenticationProvider getAuthenticationProvider() {
if (this.jwtConfigurer != null) {
return this.jwtConfigurer.getAuthenticationProvider();
}
if (this.opaqueTokenConfigurer != null) {
return this.opaqueTokenConfigurer.getAuthenticationProvider();
}
return null;
}
AuthenticationManager getAuthenticationManager(H http) {
if (this.jwtConfigurer != null) {
return this.jwtConfigurer.getAuthenticationManager(http);
}
if (this.opaqueTokenConfigurer != null) {
return this.opaqueTokenConfigurer.getAuthenticationManager(http);
}
return http.getSharedObject(AuthenticationManager.class);
}
BearerTokenResolver getBearerTokenResolver() {
if (this.bearerTokenResolver == null) {
if (this.context.getBeanNamesForType(BearerTokenResolver.class).length > 0) {
this.bearerTokenResolver = this.context.getBean(BearerTokenResolver.class);
}
else {
this.bearerTokenResolver = new DefaultBearerTokenResolver();
}
}
return this.bearerTokenResolver;
}
public class JwtConfigurer {
private final ApplicationContext context;
@ -435,70 +499,6 @@ public final class OAuth2ResourceServerConfigurer<H extends HttpSecurityBuilder<
}
private void registerDefaultAccessDeniedHandler(H http) {
ExceptionHandlingConfigurer<H> exceptionHandling = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptionHandling == null) {
return;
}
exceptionHandling.defaultAccessDeniedHandlerFor(this.accessDeniedHandler, this.requestMatcher);
}
private void registerDefaultEntryPoint(H http) {
ExceptionHandlingConfigurer<H> exceptionHandling = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptionHandling == null) {
return;
}
exceptionHandling.defaultAuthenticationEntryPointFor(this.authenticationEntryPoint, this.requestMatcher);
}
private void registerDefaultCsrfOverride(H http) {
CsrfConfigurer<H> csrf = http.getConfigurer(CsrfConfigurer.class);
if (csrf == null) {
return;
}
csrf.ignoringRequestMatchers(this.requestMatcher);
}
AuthenticationProvider getAuthenticationProvider() {
if (this.jwtConfigurer != null) {
return this.jwtConfigurer.getAuthenticationProvider();
}
if (this.opaqueTokenConfigurer != null) {
return this.opaqueTokenConfigurer.getAuthenticationProvider();
}
return null;
}
AuthenticationManager getAuthenticationManager(H http) {
if (this.jwtConfigurer != null) {
return this.jwtConfigurer.getAuthenticationManager(http);
}
if (this.opaqueTokenConfigurer != null) {
return this.opaqueTokenConfigurer.getAuthenticationManager(http);
}
return http.getSharedObject(AuthenticationManager.class);
}
BearerTokenResolver getBearerTokenResolver() {
if (this.bearerTokenResolver == null) {
if (this.context.getBeanNamesForType(BearerTokenResolver.class).length > 0) {
this.bearerTokenResolver = this.context.getBean(BearerTokenResolver.class);
}
else {
this.bearerTokenResolver = new DefaultBearerTokenResolver();
}
}
return this.bearerTokenResolver;
}
private static final class BearerTokenRequestMatcher implements RequestMatcher {
private BearerTokenResolver bearerTokenResolver;

View File

@ -247,6 +247,29 @@ public class MessageSecurityMetadataSourceRegistry {
return !this.matcherToExpression.isEmpty();
}
private static String hasAnyRole(String... authorities) {
String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','ROLE_");
return "hasAnyRole('ROLE_" + anyAuthorities + "')";
}
private static String hasRole(String role) {
Assert.notNull(role, "role cannot be null");
if (role.startsWith("ROLE_")) {
throw new IllegalArgumentException(
"role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
}
return "hasRole('ROLE_" + role + "')";
}
private static String hasAuthority(String authority) {
return "hasAuthority('" + authority + "')";
}
private static String hasAnyAuthority(String... authorities) {
String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','");
return "hasAnyAuthority('" + anyAuthorities + "')";
}
/**
* Represents the security constraint to be applied to the {@link MessageMatcher}
* instances.
@ -386,29 +409,6 @@ public class MessageSecurityMetadataSourceRegistry {
}
private static String hasAnyRole(String... authorities) {
String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','ROLE_");
return "hasAnyRole('ROLE_" + anyAuthorities + "')";
}
private static String hasRole(String role) {
Assert.notNull(role, "role cannot be null");
if (role.startsWith("ROLE_")) {
throw new IllegalArgumentException(
"role should not start with 'ROLE_' since it is automatically inserted. Got '" + role + "'");
}
return "hasRole('ROLE_" + role + "')";
}
private static String hasAuthority(String authority) {
return "hasAuthority('" + authority + "')";
}
private static String hasAnyAuthority(String... authorities) {
String anyAuthorities = StringUtils.arrayToDelimitedString(authorities, "','");
return "hasAnyAuthority('" + anyAuthorities + "')";
}
private final static class PreBuiltMatcherBuilder implements MatcherBuilder {
private MessageMatcher<?> matcher;

View File

@ -186,25 +186,6 @@ public abstract class AbstractSecurityWebSocketMessageBrokerConfigurer extends A
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
}
private static class WebSocketMessageSecurityMetadataSourceRegistry extends MessageSecurityMetadataSourceRegistry {
@Override
public MessageSecurityMetadataSource createMetadataSource() {
return super.createMetadataSource();
}
@Override
protected boolean containsMapping() {
return super.containsMapping();
}
@Override
protected boolean isSimpDestPathMatcherConfigured() {
return super.isSimpDestPathMatcherConfigured();
}
}
@Autowired
public void setApplicationContext(ApplicationContext context) {
this.context = context;
@ -283,4 +264,23 @@ public abstract class AbstractSecurityWebSocketMessageBrokerConfigurer extends A
}
}
private static class WebSocketMessageSecurityMetadataSourceRegistry extends MessageSecurityMetadataSourceRegistry {
@Override
public MessageSecurityMetadataSource createMetadataSource() {
return super.createMetadataSource();
}
@Override
protected boolean containsMapping() {
return super.containsMapping();
}
@Override
protected boolean isSimpDestPathMatcherConfigured() {
return super.isSimpDestPathMatcherConfigured();
}
}
}

View File

@ -68,6 +68,9 @@ public class AuthenticationManagerBuilderTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Autowired(required = false)
MockMvc mockMvc;
@Test
public void buildWhenAddAuthenticationProviderThenDoesNotPerformRegistration() throws Exception {
ObjectPostProcessor<Object> opp = mock(ObjectPostProcessor.class);
@ -110,25 +113,6 @@ public class AuthenticationManagerBuilderTests {
assertThat(auth.getAuthorities()).extracting(GrantedAuthority::getAuthority).containsOnly("ROLE_USER");
}
@EnableWebSecurity
static class PasswordEncoderGlobalConfig extends WebSecurityConfigurerAdapter {
@Autowired
void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
// @formatter:on
}
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
@Test
public void getAuthenticationManagerWhenProtectedPasswordEncoderBeanThenUsed() throws Exception {
this.spring.register(PasswordEncoderGlobalConfig.class).autowire();
@ -141,28 +125,6 @@ public class AuthenticationManagerBuilderTests {
assertThat(auth.getAuthorities()).extracting(GrantedAuthority::getAuthority).containsOnly("ROLE_USER");
}
@EnableWebSecurity
static class PasswordEncoderConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
// @formatter:on
}
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
@Autowired(required = false)
MockMvc mockMvc;
@Test
public void authenticationManagerWhenMultipleProvidersThenWorks() throws Exception {
this.spring.register(MultiAuthenticationProvidersConfig.class).autowire();
@ -173,17 +135,6 @@ public class AuthenticationManagerBuilderTests {
.andExpect(authenticated().withUsername("admin").withRoles("USER", "ADMIN"));
}
@EnableWebSecurity
static class MultiAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user()).and().inMemoryAuthentication()
.withUser(PasswordEncodedUser.admin());
}
}
@Test
public void buildWhenAuthenticationProviderThenIsConfigured() throws Exception {
ObjectPostProcessor<Object> opp = mock(ObjectPostProcessor.class);
@ -225,6 +176,55 @@ public class AuthenticationManagerBuilderTests {
.andExpect(authenticated().withUsername("joe").withRoles("USER"));
}
@EnableWebSecurity
static class MultiAuthenticationProvidersConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user()).and().inMemoryAuthentication()
.withUser(PasswordEncodedUser.admin());
}
}
@EnableWebSecurity
static class PasswordEncoderGlobalConfig extends WebSecurityConfigurerAdapter {
@Autowired
void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
// @formatter:on
}
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
@EnableWebSecurity
static class PasswordEncoderConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
// @formatter:on
}
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
@Configuration
@EnableGlobalAuthentication
@Import(ObjectPostProcessorConfiguration.class)

View File

@ -53,6 +53,27 @@ public class NamespaceAuthenticationManagerTests {
// no exception due to username being cleared out
}
@Test
public void authenticationMangerWhenEraseCredentialsIsFalseThenCredentialsNotNull() throws Exception {
this.spring.register(EraseCredentialsFalseConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
// no exception due to username being cleared out
}
@Test
// SEC-2533
public void authenticationManagerWhenGlobalAndEraseCredentialsIsFalseThenCredentialsNotNull() throws Exception {
this.spring.register(GlobalEraseCredentialsFalseConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
}
@EnableWebSecurity
static class EraseCredentialsTrueDefaultConfig extends WebSecurityConfigurerAdapter {
@ -67,18 +88,6 @@ public class NamespaceAuthenticationManagerTests {
}
@Test
public void authenticationMangerWhenEraseCredentialsIsFalseThenCredentialsNotNull() throws Exception {
this.spring.register(EraseCredentialsFalseConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
// no exception due to username being cleared out
}
@EnableWebSecurity
static class EraseCredentialsFalseConfig extends WebSecurityConfigurerAdapter {
@ -94,15 +103,6 @@ public class NamespaceAuthenticationManagerTests {
}
@Test
// SEC-2533
public void authenticationManagerWhenGlobalAndEraseCredentialsIsFalseThenCredentialsNotNull() throws Exception {
this.spring.register(GlobalEraseCredentialsFalseConfig.class).autowire();
this.mockMvc.perform(formLogin())
.andExpect(authenticated().withAuthentication(a -> assertThat(a.getCredentials()).isNotNull()));
}
@EnableWebSecurity
static class GlobalEraseCredentialsFalseConfig extends WebSecurityConfigurerAdapter {

View File

@ -53,6 +53,14 @@ public class NamespaceAuthenticationProviderTests {
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user"));
}
@Test
// authentication-provider@user-service-ref
public void authenticationProviderUserServiceRef() throws Exception {
this.spring.register(AuthenticationProviderRefConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user"));
}
@EnableWebSecurity
static class AuthenticationProviderRefConfig extends WebSecurityConfigurerAdapter {
@ -73,14 +81,6 @@ public class NamespaceAuthenticationProviderTests {
}
@Test
// authentication-provider@user-service-ref
public void authenticationProviderUserServiceRef() throws Exception {
this.spring.register(AuthenticationProviderRefConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user"));
}
@EnableWebSecurity
static class UserServiceRefConfig extends WebSecurityConfigurerAdapter {

View File

@ -57,6 +57,13 @@ public class NamespaceJdbcUserServiceTests {
this.mockMvc.perform(formLogin()).andExpect(authenticated().withUsername("user"));
}
@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"));
}
@EnableWebSecurity
static class JdbcUserServiceConfig extends WebSecurityConfigurerAdapter {
@ -87,13 +94,6 @@ public class NamespaceJdbcUserServiceTests {
}
@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"));
}
@EnableWebSecurity
static class CustomJdbcUserServiceSampleConfig extends WebSecurityConfigurerAdapter {

View File

@ -56,6 +56,20 @@ public class NamespacePasswordEncoderTests {
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@Test
public void passwordEncoderRefWithJdbc() throws Exception {
this.spring.register(PasswordEncoderWithJdbcConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@Test
public void passwordEncoderRefWithUserDetailsService() throws Exception {
this.spring.register(PasswordEncoderWithUserDetailsServiceConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderWithInMemoryConfig extends WebSecurityConfigurerAdapter {
@ -72,13 +86,6 @@ public class NamespacePasswordEncoderTests {
}
@Test
public void passwordEncoderRefWithJdbc() throws Exception {
this.spring.register(PasswordEncoderWithJdbcConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderWithJdbcConfig extends WebSecurityConfigurerAdapter {
@ -104,13 +111,6 @@ public class NamespacePasswordEncoderTests {
}
@Test
public void passwordEncoderRefWithUserDetailsService() throws Exception {
this.spring.register(PasswordEncoderWithUserDetailsServiceConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderWithUserDetailsServiceConfig extends WebSecurityConfigurerAdapter {

View File

@ -48,6 +48,13 @@ public class PasswordEncoderConfigurerTests {
this.spring.register(PasswordEncoderConfig.class).autowire();
}
@Test
public void passwordEncoderRefWhenAuthenticationManagerBuilderThenAuthenticationSuccess() throws Exception {
this.spring.register(PasswordEncoderNoAuthManagerLoadsConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderConfig extends WebSecurityConfigurerAdapter {
@ -73,13 +80,6 @@ public class PasswordEncoderConfigurerTests {
}
@Test
public void passwordEncoderRefWhenAuthenticationManagerBuilderThenAuthenticationSuccess() throws Exception {
this.spring.register(PasswordEncoderNoAuthManagerLoadsConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(authenticated());
}
@EnableWebSecurity
static class PasswordEncoderNoAuthManagerLoadsConfig extends WebSecurityConfigurerAdapter {

View File

@ -93,11 +93,6 @@ public class AuthenticationConfigurationTests {
this.service.run();
}
@EnableGlobalMethodSecurity(securedEnabled = true)
static class GlobalMethodSecurityAutowiredConfig {
}
@Test
public void orderingAutowiredOnEnableWebSecurity() {
this.spring.register(AuthenticationTestConfiguration.class, WebSecurityConfig.class,
@ -108,11 +103,6 @@ public class AuthenticationConfigurationTests {
this.service.run();
}
@EnableWebSecurity
static class WebSecurityConfig {
}
@Test
public void orderingAutowiredOnEnableWebMvcSecurity() {
this.spring.register(AuthenticationTestConfiguration.class, WebMvcSecurityConfig.class,
@ -123,11 +113,6 @@ public class AuthenticationConfigurationTests {
this.service.run();
}
@EnableWebMvcSecurity
static class WebMvcSecurityConfig {
}
@Test
public void getAuthenticationManagerWhenNoAuthenticationThenNull() throws Exception {
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class).autowire();
@ -145,11 +130,6 @@ public class AuthenticationConfigurationTests {
.isNull();
}
@Configuration
static class NoOpGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
}
@Test
public void getAuthenticationWhenGlobalAuthenticationConfigurerAdapterThenAuthenticates() throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
@ -162,16 +142,6 @@ public class AuthenticationConfigurationTests {
assertThat(authentication.authenticate(token).getName()).isEqualTo(token.getName());
}
@Configuration
static class UserGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user());
}
}
@Test
public void getAuthenticationWhenAuthenticationManagerBeanThenAuthenticates() throws Exception {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken("user", "password");
@ -185,6 +155,200 @@ public class AuthenticationConfigurationTests {
assertThat(authentication.authenticate(token).getName()).isEqualTo(token.getName());
}
@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()));
}
@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()));
AuthenticationManager authenticationManager = config.getAuthenticationManager();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
assertThatThrownBy(
() -> authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot", "password")))
.isInstanceOf(AuthenticationException.class);
}
@Test
public void getAuthenticationWhenNotConfiguredThenBootTrigger() throws Exception {
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class).autowire();
AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
config.setGlobalAuthenticationConfigurers(Arrays.asList(new BootGlobalAuthenticationConfigurerAdapter()));
AuthenticationManager authenticationManager = config.getAuthenticationManager();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot", "password"));
}
// gh-2531
@Test
public void getAuthenticationManagerWhenPostProcessThenUsesBeanClassLoaderOnProxyFactoryBean() throws Exception {
this.spring.register(Sec2531Config.class).autowire();
ObjectPostProcessor<Object> opp = this.spring.getContext().getBean(ObjectPostProcessor.class);
when(opp.postProcess(any())).thenAnswer(a -> a.getArgument(0));
AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
config.getAuthenticationManager();
verify(opp).postProcess(any(ProxyFactoryBean.class));
}
@Test
public void getAuthenticationManagerWhenSec2822ThenCannotForceAuthenticationAlreadyBuilt() throws Exception {
this.spring.register(Sec2822WebSecurity.class, Sec2822UseAuth.class, Sec2822Config.class).autowire();
this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
// no exception
}
// sec-2868
@Test
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();
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);
}
@Test
public void getAuthenticationWhenUserDetailsServiceAndPasswordEncoderBeanThenEncoderUsed() throws Exception {
UserDetails user = new User("user", "$2a$10$FBAKClV1zBIOOC9XMXf3AO8RoGXYVYsfvUdoLxGkd/BnXEn4tqT3u",
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());
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
assertThatThrownBy(() -> am.authenticate(new UsernamePasswordAuthenticationToken("user", "invalid")))
.isInstanceOf(AuthenticationException.class);
}
@Test
public void getAuthenticationWhenUserDetailsServiceAndPasswordManagerThenManagerUsed() throws Exception {
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());
when(manager.updatePassword(any(), any())).thenReturn(user);
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
verify(manager).updatePassword(eq(user), startsWith("{bcrypt}"));
}
@Test
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();
when(ap.supports(any())).thenReturn(true);
when(ap.authenticate(any())).thenReturn(TestAuthentication.authenticatedUser());
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
}
// 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();
when(ap.supports(any())).thenReturn(true);
when(ap.authenticate(any())).thenReturn(TestAuthentication.authenticatedUser());
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
}
@Test
public void enableGlobalMethodSecurityWhenPreAuthorizeThenNoException() {
this.spring.register(UsesPreAuthorizeMethodSecurityConfig.class, AuthenticationManagerBeanConfig.class)
.autowire();
// no exception
}
@Test
public void enableGlobalMethodSecurityWhenPreAuthorizeThenUsesMethodSecurityService() {
this.spring.register(ServicesConfig.class, UsesPreAuthorizeMethodSecurityConfig.class,
AuthenticationManagerBeanConfig.class).autowire();
// no exception
}
@Test
public void getAuthenticationManagerBeanWhenMultipleDefinedAndOnePrimaryThenNoException() throws Exception {
this.spring.register(MultipleAuthenticationManagerBeanConfig.class).autowire();
this.spring.getContext().getBeanFactory().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
}
@Test
public void getAuthenticationManagerWhenAuthenticationConfigurationSubclassedThenBuildsUsingBean()
throws Exception {
this.spring.register(AuthenticationConfigurationSubclass.class).autowire();
AuthenticationManagerBuilder ap = this.spring.getContext().getBean(AuthenticationManagerBuilder.class);
this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
assertThatThrownBy(ap::build).isInstanceOf(AlreadyBuiltException.class);
}
@EnableGlobalMethodSecurity(securedEnabled = true)
static class GlobalMethodSecurityAutowiredConfig {
}
@EnableWebSecurity
static class WebSecurityConfig {
}
@EnableWebMvcSecurity
static class WebMvcSecurityConfig {
}
@Configuration
static class NoOpGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
}
@Configuration
static class UserGlobalAuthenticationConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
@Override
public void init(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser(PasswordEncodedUser.user());
}
}
@Configuration
static class AuthenticationManagerBeanConfig {
@ -197,9 +361,6 @@ public class AuthenticationConfigurationTests {
}
//
// //
//
@Configuration
static class ServicesConfig {
@ -225,16 +386,6 @@ public class AuthenticationConfigurationTests {
}
@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<>();
@ -264,32 +415,6 @@ public class AuthenticationConfigurationTests {
}
@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()));
AuthenticationManager authenticationManager = config.getAuthenticationManager();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
assertThatThrownBy(
() -> authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot", "password")))
.isInstanceOf(AuthenticationException.class);
}
@Test
public void getAuthenticationWhenNotConfiguredThenBootTrigger() throws Exception {
this.spring.register(AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class).autowire();
AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
config.setGlobalAuthenticationConfigurers(Arrays.asList(new BootGlobalAuthenticationConfigurerAdapter()));
AuthenticationManager authenticationManager = config.getAuthenticationManager();
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken("boot", "password"));
}
static class ConfiguresInMemoryConfigurerAdapter extends GlobalAuthenticationConfigurerAdapter {
@Override
@ -335,19 +460,6 @@ public class AuthenticationConfigurationTests {
}
// gh-2531
@Test
public void getAuthenticationManagerWhenPostProcessThenUsesBeanClassLoaderOnProxyFactoryBean() throws Exception {
this.spring.register(Sec2531Config.class).autowire();
ObjectPostProcessor<Object> opp = this.spring.getContext().getBean(ObjectPostProcessor.class);
when(opp.postProcess(any())).thenAnswer(a -> a.getArgument(0));
AuthenticationConfiguration config = this.spring.getContext().getBean(AuthenticationConfiguration.class);
config.getAuthenticationManager();
verify(opp).postProcess(any(ProxyFactoryBean.class));
}
@Configuration
@Import(AuthenticationConfiguration.class)
static class Sec2531Config {
@ -364,14 +476,6 @@ public class AuthenticationConfigurationTests {
}
@Test
public void getAuthenticationManagerWhenSec2822ThenCannotForceAuthenticationAlreadyBuilt() throws Exception {
this.spring.register(Sec2822WebSecurity.class, Sec2822UseAuth.class, Sec2822Config.class).autowire();
this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
// no exception
}
@Configuration
@Import(AuthenticationConfiguration.class)
static class Sec2822Config {
@ -410,22 +514,6 @@ public class AuthenticationConfigurationTests {
}
// sec-2868
@Test
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();
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);
}
@Configuration
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class UserDetailsServiceBeanConfig {
@ -439,23 +527,6 @@ public class AuthenticationConfigurationTests {
}
@Test
public void getAuthenticationWhenUserDetailsServiceAndPasswordEncoderBeanThenEncoderUsed() throws Exception {
UserDetails user = new User("user", "$2a$10$FBAKClV1zBIOOC9XMXf3AO8RoGXYVYsfvUdoLxGkd/BnXEn4tqT3u",
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());
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
assertThatThrownBy(() -> am.authenticate(new UsernamePasswordAuthenticationToken("user", "invalid")))
.isInstanceOf(AuthenticationException.class);
}
@Configuration
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class UserDetailsServiceBeanWithPasswordEncoderConfig {
@ -474,23 +545,6 @@ public class AuthenticationConfigurationTests {
}
@Test
public void getAuthenticationWhenUserDetailsServiceAndPasswordManagerThenManagerUsed() throws Exception {
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());
when(manager.updatePassword(any(), any())).thenReturn(user);
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
verify(manager).updatePassword(eq(user), startsWith("{bcrypt}"));
}
@Configuration
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class UserDetailsPasswordManagerBeanConfig {
@ -508,19 +562,6 @@ public class AuthenticationConfigurationTests {
}
// 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();
when(ap.supports(any())).thenReturn(true);
when(ap.authenticate(any())).thenReturn(TestAuthentication.authenticatedUser());
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
}
@Configuration
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class AuthenticationProviderBeanConfig {
@ -534,19 +575,6 @@ public class AuthenticationConfigurationTests {
}
@Test
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();
when(ap.supports(any())).thenReturn(true);
when(ap.authenticate(any())).thenReturn(TestAuthentication.authenticatedUser());
am.authenticate(new UsernamePasswordAuthenticationToken("user", "password"));
}
@Configuration
@Import({ AuthenticationConfiguration.class, ObjectPostProcessorConfiguration.class })
static class AuthenticationProviderBeanAndUserDetailsServiceConfig {
@ -567,14 +595,6 @@ public class AuthenticationConfigurationTests {
}
@Test
public void enableGlobalMethodSecurityWhenPreAuthorizeThenNoException() {
this.spring.register(UsesPreAuthorizeMethodSecurityConfig.class, AuthenticationManagerBeanConfig.class)
.autowire();
// no exception
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class UsesPreAuthorizeMethodSecurityConfig {
@ -585,14 +605,6 @@ public class AuthenticationConfigurationTests {
}
@Test
public void enableGlobalMethodSecurityWhenPreAuthorizeThenUsesMethodSecurityService() {
this.spring.register(ServicesConfig.class, UsesPreAuthorizeMethodSecurityConfig.class,
AuthenticationManagerBeanConfig.class).autowire();
// no exception
}
@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
static class UsesServiceMethodSecurityConfig {
@ -602,12 +614,6 @@ public class AuthenticationConfigurationTests {
}
@Test
public void getAuthenticationManagerBeanWhenMultipleDefinedAndOnePrimaryThenNoException() throws Exception {
this.spring.register(MultipleAuthenticationManagerBeanConfig.class).autowire();
this.spring.getContext().getBeanFactory().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
}
@Configuration
@Import(AuthenticationConfiguration.class)
static class MultipleAuthenticationManagerBeanConfig {
@ -625,17 +631,6 @@ public class AuthenticationConfigurationTests {
}
@Test
public void getAuthenticationManagerWhenAuthenticationConfigurationSubclassedThenBuildsUsingBean()
throws Exception {
this.spring.register(AuthenticationConfigurationSubclass.class).autowire();
AuthenticationManagerBuilder ap = this.spring.getContext().getBean(AuthenticationManagerBuilder.class);
this.spring.getContext().getBean(AuthenticationConfiguration.class).getAuthenticationManager();
assertThatThrownBy(ap::build).isInstanceOf(AlreadyBuiltException.class);
}
@Configuration
static class AuthenticationConfigurationSubclass extends AuthenticationConfiguration {

View File

@ -45,6 +45,26 @@ public class EnableGlobalAuthenticationTests {
assertThat(auth.getAuthenticationManager()).isNotNull();
}
@Test
public void enableGlobalAuthenticationWhenNoConfigurationAnnotationThenBeanProxyingEnabled() {
this.spring.register(BeanProxyEnabledByDefaultConfig.class).autowire();
Child childBean = this.spring.getContext().getBean(Child.class);
Parent parentBean = this.spring.getContext().getBean(Parent.class);
assertThat(parentBean.getChild()).isSameAs(childBean);
}
@Test
public void enableGlobalAuthenticationWhenProxyBeanMethodsFalseThenBeanProxyingDisabled() {
this.spring.register(BeanProxyDisabledConfig.class).autowire();
Child childBean = this.spring.getContext().getBean(Child.class);
Parent parentBean = this.spring.getContext().getBean(Parent.class);
assertThat(parentBean.getChild()).isNotSameAs(childBean);
}
@Configuration
@EnableGlobalAuthentication
static class Config {
@ -56,16 +76,6 @@ public class EnableGlobalAuthenticationTests {
}
@Test
public void enableGlobalAuthenticationWhenNoConfigurationAnnotationThenBeanProxyingEnabled() {
this.spring.register(BeanProxyEnabledByDefaultConfig.class).autowire();
Child childBean = this.spring.getContext().getBean(Child.class);
Parent parentBean = this.spring.getContext().getBean(Parent.class);
assertThat(parentBean.getChild()).isSameAs(childBean);
}
@EnableGlobalAuthentication
static class BeanProxyEnabledByDefaultConfig {
@ -81,16 +91,6 @@ public class EnableGlobalAuthenticationTests {
}
@Test
public void enableGlobalAuthenticationWhenProxyBeanMethodsFalseThenBeanProxyingDisabled() {
this.spring.register(BeanProxyDisabledConfig.class).autowire();
Child childBean = this.spring.getContext().getBean(Child.class);
Parent parentBean = this.spring.getContext().getBean(Parent.class);
assertThat(parentBean.getChild()).isNotSameAs(childBean);
}
@Configuration(proxyBeanMethods = false)
@EnableGlobalAuthentication
static class BeanProxyDisabledConfig {

View File

@ -126,6 +126,25 @@ public class AutowireBeanFactoryObjectPostProcessorTests {
verify(toPostProcess).destroy();
}
@Test
public void postProcessWhenSmartInitializingSingletonThenAwareInvoked() {
this.spring.register(Config.class, SmartConfig.class).autowire();
SmartConfig config = this.spring.getContext().getBean(SmartConfig.class);
verify(config.toTest).afterSingletonsInstantiated();
}
@Test
// SEC-2382
public void autowireBeanFactoryWhenBeanNameAutoProxyCreatorThenWorks() {
this.spring.testConfigLocations("AutowireBeanFactoryObjectPostProcessorTests-aopconfig.xml").autowire();
MyAdvisedBean bean = this.spring.getContext().getBean(MyAdvisedBean.class);
assertThat(bean.doStuff()).isEqualTo("null");
}
@Configuration
static class Config {
@ -136,15 +155,6 @@ public class AutowireBeanFactoryObjectPostProcessorTests {
}
@Test
public void postProcessWhenSmartInitializingSingletonThenAwareInvoked() {
this.spring.register(Config.class, SmartConfig.class).autowire();
SmartConfig config = this.spring.getContext().getBean(SmartConfig.class);
verify(config.toTest).afterSingletonsInstantiated();
}
@Configuration
static class SmartConfig {
@ -157,16 +167,6 @@ public class AutowireBeanFactoryObjectPostProcessorTests {
}
@Test
// SEC-2382
public void autowireBeanFactoryWhenBeanNameAutoProxyCreatorThenWorks() {
this.spring.testConfigLocations("AutowireBeanFactoryObjectPostProcessorTests-aopconfig.xml").autowire();
MyAdvisedBean bean = this.spring.getContext().getBean(MyAdvisedBean.class);
assertThat(bean.doStuff()).isEqualTo("null");
}
@Configuration
static class WithBeanNameAutoProxyCreatorConfig {

View File

@ -101,27 +101,11 @@ public class GlobalMethodSecurityConfigurationTests {
this.spring.register(IllegalStateGlobalMethodSecurityConfig.class).autowire();
}
@EnableGlobalMethodSecurity
public static class IllegalStateGlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}
@Test
public void configureWhenGlobalMethodSecurityHasCustomMetadataSourceThenNoEnablingAttributeIsNeeded() {
this.spring.register(CustomMetadataSourceConfig.class).autowire();
}
@EnableGlobalMethodSecurity
public static class CustomMetadataSourceConfig extends GlobalMethodSecurityConfiguration {
@Bean
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return mock(MethodSecurityMetadataSource.class);
}
}
@Test
public void methodSecurityAuthenticationManagerPublishesEvent() {
this.spring.register(InMemoryAuthWithGlobalMethodSecurityConfig.class).autowire();
@ -136,6 +120,202 @@ public class GlobalMethodSecurityConfigurationTests {
.containsOnly((Class) AuthenticationFailureBadCredentialsEvent.class);
}
@Test
@WithMockUser
public void methodSecurityWhenAuthenticationTrustResolverIsBeanThenAutowires() {
this.spring.register(CustomTrustResolverConfig.class).autowire();
AuthenticationTrustResolver trustResolver = this.spring.getContext().getBean(AuthenticationTrustResolver.class);
when(trustResolver.isAnonymous(any())).thenReturn(true, false);
assertThatThrownBy(() -> this.service.preAuthorizeNotAnonymous()).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeNotAnonymous();
verify(trustResolver, atLeastOnce()).isAnonymous(any());
}
// SEC-2301
@Test
@WithMockUser
public void defaultWebSecurityExpressionHandlerHasBeanResolverSet() {
this.spring.register(ExpressionHandlerHasBeanResolverSetConfig.class).autowire();
Authz authz = this.spring.getContext().getBean(Authz.class);
assertThatThrownBy(() -> this.service.preAuthorizeBean(false)).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeBean(true);
}
@Test
@WithMockUser
public void methodSecuritySupportsAnnotaitonsOnInterfaceParamerNames() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.postAnnotation("deny")).isInstanceOf(AccessDeniedException.class);
this.service.postAnnotation("grant");
// no exception
}
@Test
@WithMockUser
public void globalMethodSecurityConfigurationAutowiresPermissionEvaluator() {
this.spring.register(AutowirePermissionEvaluatorConfig.class).autowire();
PermissionEvaluator permission = this.spring.getContext().getBean(PermissionEvaluator.class);
when(permission.hasPermission(any(), eq("something"), eq("read"))).thenReturn(true, false);
this.service.hasPermission("something");
// no exception
assertThatThrownBy(() -> this.service.hasPermission("something")).isInstanceOf(AccessDeniedException.class);
}
@Test
public void multiPermissionEvaluatorConfig() {
this.spring.register(MultiPermissionEvaluatorConfig.class).autowire();
// no exception
}
// SEC-2425
@Test
@WithMockUser
public void enableGlobalMethodSecurityWorksOnSuperclass() {
this.spring.register(ChildConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
// SEC-2479
@Test
@WithMockUser
public void supportAuthenticationManagerInParent() {
try (AnnotationConfigWebApplicationContext parent = new AnnotationConfigWebApplicationContext()) {
parent.register(Sec2479ParentConfig.class);
parent.refresh();
try (AnnotationConfigWebApplicationContext child = new AnnotationConfigWebApplicationContext()) {
child.setParent(parent);
child.register(Sec2479ChildConfig.class);
child.refresh();
this.spring.context(child).autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
}
}
@Test
public void enableGlobalMethodSecurityDoesNotTriggerEagerInitializationOfBeansInGlobalAuthenticationConfigurer() {
this.spring.register(Sec2815Config.class).autowire();
MockBeanPostProcessor pp = this.spring.getContext().getBean(MockBeanPostProcessor.class);
assertThat(pp.beforeInit).containsKeys("dataSource");
assertThat(pp.afterInit).containsKeys("dataSource");
}
// SEC-3045
@Test
public void globalSecurityProxiesSecurity() {
this.spring.register(Sec3005Config.class).autowire();
assertThat(this.service.getClass()).matches(c -> !Proxy.isProxyClass(c), "is not proxy class");
}
//
// // 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
@WithMockUser
public void preAuthorizeBeanSpel() {
this.spring.register(PreAuthorizeBeanSpelConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorizeBean(false)).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeBean(true);
}
// gh-3394
@Test
@WithMockUser
public void roleHierarchy() {
this.spring.register(RoleHierarchyConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeAdmin();
}
@Test
@WithMockUser(authorities = "ROLE:USER")
public void grantedAuthorityDefaultsAutowires() {
this.spring.register(CustomGrantedAuthorityConfig.class).autowire();
CustomGrantedAuthorityConfig.CustomAuthorityService customService = this.spring.getContext()
.getBean(CustomGrantedAuthorityConfig.CustomAuthorityService.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
customService.customPrefixRoleUser();
// no exception
}
@Test
@WithMockUser(authorities = "USER")
public void grantedAuthorityDefaultsWithEmptyRolePrefix() {
this.spring.register(EmptyRolePrefixGrantedAuthorityConfig.class).autowire();
EmptyRolePrefixGrantedAuthorityConfig.CustomAuthorityService customService = this.spring.getContext()
.getBean(EmptyRolePrefixGrantedAuthorityConfig.CustomAuthorityService.class);
assertThatThrownBy(() -> this.service.securedUser()).isInstanceOf(AccessDeniedException.class);
customService.emptyPrefixRoleUser();
// no exception
}
@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);
assertThat(methodInterceptor.getSecurityMetadataSource()).isSameAs(methodSecurityMetadataSource);
}
@EnableGlobalMethodSecurity
public static class IllegalStateGlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}
@EnableGlobalMethodSecurity
public static class CustomMetadataSourceConfig extends GlobalMethodSecurityConfiguration {
@Bean
@Override
protected MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
return mock(MethodSecurityMetadataSource.class);
}
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class InMemoryAuthWithGlobalMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@ -155,21 +335,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
@Test
@WithMockUser
public void methodSecurityWhenAuthenticationTrustResolverIsBeanThenAutowires() {
this.spring.register(CustomTrustResolverConfig.class).autowire();
AuthenticationTrustResolver trustResolver = this.spring.getContext().getBean(AuthenticationTrustResolver.class);
when(trustResolver.isAnonymous(any())).thenReturn(true, false);
assertThatThrownBy(() -> this.service.preAuthorizeNotAnonymous()).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeNotAnonymous();
verify(trustResolver, atLeastOnce()).isAnonymous(any());
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class CustomTrustResolverConfig {
@ -185,18 +350,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
// SEC-2301
@Test
@WithMockUser
public void defaultWebSecurityExpressionHandlerHasBeanResolverSet() {
this.spring.register(ExpressionHandlerHasBeanResolverSetConfig.class).autowire();
Authz authz = this.spring.getContext().getBean(Authz.class);
assertThatThrownBy(() -> this.service.preAuthorizeBean(false)).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeBean(true);
}
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
static class ExpressionHandlerHasBeanResolverSetConfig {
@ -212,17 +365,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
@Test
@WithMockUser
public void methodSecuritySupportsAnnotaitonsOnInterfaceParamerNames() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.postAnnotation("deny")).isInstanceOf(AccessDeniedException.class);
this.service.postAnnotation("grant");
// no exception
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class MethodSecurityServiceConfig {
@ -233,19 +375,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
@Test
@WithMockUser
public void globalMethodSecurityConfigurationAutowiresPermissionEvaluator() {
this.spring.register(AutowirePermissionEvaluatorConfig.class).autowire();
PermissionEvaluator permission = this.spring.getContext().getBean(PermissionEvaluator.class);
when(permission.hasPermission(any(), eq("something"), eq("read"))).thenReturn(true, false);
this.service.hasPermission("something");
// no exception
assertThatThrownBy(() -> this.service.hasPermission("something")).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class AutowirePermissionEvaluatorConfig {
@ -261,13 +390,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
@Test
public void multiPermissionEvaluatorConfig() {
this.spring.register(MultiPermissionEvaluatorConfig.class).autowire();
// no exception
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class MultiPermissionEvaluatorConfig {
@ -283,15 +405,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
// SEC-2425
@Test
@WithMockUser
public void enableGlobalMethodSecurityWorksOnSuperclass() {
this.spring.register(ChildConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Configuration
static class ChildConfig extends ParentConfig {
@ -307,24 +420,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
// SEC-2479
@Test
@WithMockUser
public void supportAuthenticationManagerInParent() {
try (AnnotationConfigWebApplicationContext parent = new AnnotationConfigWebApplicationContext()) {
parent.register(Sec2479ParentConfig.class);
parent.refresh();
try (AnnotationConfigWebApplicationContext child = new AnnotationConfigWebApplicationContext()) {
child.setParent(parent);
child.register(Sec2479ChildConfig.class);
child.refresh();
this.spring.context(child).autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
}
}
@Configuration
static class Sec2479ParentConfig {
@ -345,16 +440,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
@Test
public void enableGlobalMethodSecurityDoesNotTriggerEagerInitializationOfBeansInGlobalAuthenticationConfigurer() {
this.spring.register(Sec2815Config.class).autowire();
MockBeanPostProcessor pp = this.spring.getContext().getBean(MockBeanPostProcessor.class);
assertThat(pp.beforeInit).containsKeys("dataSource");
assertThat(pp.afterInit).containsKeys("dataSource");
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class Sec2815Config {
@ -408,14 +493,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
// SEC-3045
@Test
public void globalSecurityProxiesSecurity() {
this.spring.register(Sec3005Config.class).autowire();
assertThat(this.service.getClass()).matches(c -> !Proxy.isProxyClass(c), "is not proxy class");
}
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ)
@EnableTransactionManagement
static class Sec3005Config {
@ -432,35 +509,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
//
// // 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
@WithMockUser
public void preAuthorizeBeanSpel() {
this.spring.register(PreAuthorizeBeanSpelConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorizeBean(false)).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeBean(true);
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class PreAuthorizeBeanSpelConfig {
@ -477,16 +525,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
// gh-3394
@Test
@WithMockUser
public void roleHierarchy() {
this.spring.register(RoleHierarchyConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
this.service.preAuthorizeAdmin();
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public static class RoleHierarchyConfig {
@ -505,20 +543,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
@Test
@WithMockUser(authorities = "ROLE:USER")
public void grantedAuthorityDefaultsAutowires() {
this.spring.register(CustomGrantedAuthorityConfig.class).autowire();
CustomGrantedAuthorityConfig.CustomAuthorityService customService = this.spring.getContext()
.getBean(CustomGrantedAuthorityConfig.CustomAuthorityService.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
customService.customPrefixRoleUser();
// no exception
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class CustomGrantedAuthorityConfig {
@ -547,20 +571,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
@Test
@WithMockUser(authorities = "USER")
public void grantedAuthorityDefaultsWithEmptyRolePrefix() {
this.spring.register(EmptyRolePrefixGrantedAuthorityConfig.class).autowire();
EmptyRolePrefixGrantedAuthorityConfig.CustomAuthorityService customService = this.spring.getContext()
.getBean(EmptyRolePrefixGrantedAuthorityConfig.CustomAuthorityService.class);
assertThatThrownBy(() -> this.service.securedUser()).isInstanceOf(AccessDeniedException.class);
customService.emptyPrefixRoleUser();
// no exception
}
@EnableGlobalMethodSecurity(securedEnabled = true)
static class EmptyRolePrefixGrantedAuthorityConfig {
@ -589,17 +599,6 @@ public class GlobalMethodSecurityConfigurationTests {
}
@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);
assertThat(methodInterceptor.getSecurityMetadataSource()).isSameAs(methodSecurityMetadataSource);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public static class CustomMetadataSourceBeanProxyEnabledConfig extends GlobalMethodSecurityConfiguration {

View File

@ -73,8 +73,6 @@ public class NamespaceGlobalMethodSecurityTests {
@Autowired(required = false)
private MethodSecurityService service;
// --- access-decision-manager-ref ---
@Test
@WithMockUser
public void methodSecurityWhenCustomAccessDecisionManagerThenAuthorizes() {
@ -86,6 +84,198 @@ public class NamespaceGlobalMethodSecurityTests {
}
@Test
@WithMockUser
public void methodSecurityWhenCustomAfterInvocationManagerThenAuthorizes() {
this.spring.register(CustomAfterInvocationManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorizePermitAll()).isInstanceOf(AccessDeniedException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenCustomAuthenticationManagerThenAuthorizes() {
this.spring.register(CustomAuthenticationConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(UnsupportedOperationException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenJsr250EnabledThenAuthorizes() {
this.spring.register(Jsr250Config.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.preAuthorize()).doesNotThrowAnyException();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
assertThatCode(() -> this.service.jsr250PermitAll()).doesNotThrowAnyException();
}
@Test
@WithMockUser
public void methodSecurityWhenCustomMethodSecurityMetadataSourceThenAuthorizes() {
this.spring.register(CustomMethodSecurityMetadataSourceConfig.class, MethodSecurityServiceConfig.class)
.autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.secured()).isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
}
@Test
@WithMockUser
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(AspectJMethodSecurityInterceptor.class)).isNotNull();
// TODO diagnose why aspectj isn't weaving method security advice around
// MethodSecurityServiceImpl
}
@Test
public void contextRefreshWhenUsingAspectJAndCustomGlobalMethodSecurityConfigurationThenAutowire()
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(AspectJMethodSecurityInterceptor.class)).isNotNull();
}
@Test
@WithMockUser
public void methodSecurityWhenOrderSpecifiedThenConfigured() {
this.spring.register(CustomOrderConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(-135);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenOrderUnspecifiedThenConfiguredToLowestPrecedence() {
this.spring.register(DefaultOrderConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(UnsupportedOperationException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenOrderUnspecifiedAndCustomGlobalMethodSecurityConfigurationThenConfiguredToLowestPrecedence() {
this.spring.register(DefaultOrderExtendsMethodSecurityConfig.class, MethodSecurityServiceConfig.class)
.autowire();
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(UnsupportedOperationException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenPrePostEnabledThenPreAuthorizes() {
this.spring.register(PreAuthorizeConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenPrePostEnabledAndCustomGlobalMethodSecurityConfigurationThenPreAuthorizes() {
this.spring.register(PreAuthorizeExtendsGMSCConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenProxyTargetClassThenDoesNotWireToInterface() {
this.spring.register(ProxyTargetClassConfig.class, MethodSecurityServiceConfig.class).autowire();
// make sure service was actually proxied
assertThat(this.service.getClass().getInterfaces()).doesNotContain(MethodSecurityService.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenDefaultProxyThenWiresToInterface() {
this.spring.register(DefaultProxyConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.service.getClass().getInterfaces()).contains(MethodSecurityService.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Test
@WithMockUser
public void methodSecurityWhenCustomRunAsManagerThenRunAsWrapsAuthentication() {
this.spring.register(CustomRunAsManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.service.runAs().getAuthorities())
.anyMatch(authority -> "ROLE_RUN_AS_SUPER".equals(authority.getAuthority()));
}
@Test
@WithMockUser
public void methodSecurityWhenSecuredEnabledThenSecures() {
this.spring.register(SecuredConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.secured()).isInstanceOf(AccessDeniedException.class);
assertThatCode(() -> this.service.securedUser()).doesNotThrowAnyException();
assertThatCode(() -> this.service.preAuthorize()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
}
@Test
@WithMockUser
public void methodSecurityWhenMissingEnableAnnotationThenShowsHelpfulError() {
assertThatThrownBy(() -> this.spring.register(ExtendsNoEnableAnntotationConfig.class).autowire())
.hasStackTraceContaining(EnableGlobalMethodSecurity.class.getName() + " is required");
}
@Test
@WithMockUser
public void methodSecurityWhenImportingGlobalMethodSecurityConfigurationSubclassThenAuthorizes() {
this.spring.register(ImportSubclassGMSCConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public static class CustomAccessDecisionManagerConfig extends GlobalMethodSecurityConfiguration {
@ -116,16 +306,6 @@ public class NamespaceGlobalMethodSecurityTests {
}
// --- after-invocation-provider
@Test
@WithMockUser
public void methodSecurityWhenCustomAfterInvocationManagerThenAuthorizes() {
this.spring.register(CustomAfterInvocationManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorizePermitAll()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class CustomAfterInvocationManagerConfig extends GlobalMethodSecurityConfiguration {
@ -157,16 +337,6 @@ public class NamespaceGlobalMethodSecurityTests {
}
// --- authentication-manager-ref ---
@Test
@WithMockUser
public void methodSecurityWhenCustomAuthenticationManagerThenAuthorizes() {
this.spring.register(CustomAuthenticationConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(UnsupportedOperationException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class CustomAuthenticationConfig extends GlobalMethodSecurityConfiguration {
@ -186,44 +356,12 @@ public class NamespaceGlobalMethodSecurityTests {
}
// --- jsr250-annotations ---
@Test
@WithMockUser
public void methodSecurityWhenJsr250EnabledThenAuthorizes() {
this.spring.register(Jsr250Config.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.preAuthorize()).doesNotThrowAnyException();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
assertThatCode(() -> this.service.jsr250PermitAll()).doesNotThrowAnyException();
}
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@Configuration
public static class Jsr250Config {
}
// --- metadata-source-ref ---
@Test
@WithMockUser
public void methodSecurityWhenCustomMethodSecurityMetadataSourceThenAuthorizes() {
this.spring.register(CustomMethodSecurityMetadataSourceConfig.class, MethodSecurityServiceConfig.class)
.autowire();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.secured()).isInstanceOf(AccessDeniedException.class);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity
public static class CustomMethodSecurityMetadataSourceConfig extends GlobalMethodSecurityConfiguration {
@ -247,58 +385,18 @@ public class NamespaceGlobalMethodSecurityTests {
}
// --- mode ---
@Test
@WithMockUser
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(AspectJMethodSecurityInterceptor.class)).isNotNull();
// TODO diagnose why aspectj isn't weaving method security advice around
// MethodSecurityServiceImpl
}
@EnableGlobalMethodSecurity(mode = AdviceMode.ASPECTJ, securedEnabled = true)
public static class AspectJModeConfig {
}
@Test
public void contextRefreshWhenUsingAspectJAndCustomGlobalMethodSecurityConfigurationThenAutowire()
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(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 ExceptingInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) {
throw new UnsupportedOperationException("Deny All");
}
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
@ -315,17 +413,15 @@ public class NamespaceGlobalMethodSecurityTests {
registry.registerBeanDefinition("exceptingAdvisor", advisor.getBeanDefinition());
}
private static class ExceptingInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) {
throw new UnsupportedOperationException("Deny All");
}
@Test
@WithMockUser
public void methodSecurityWhenOrderSpecifiedThenConfigured() {
this.spring.register(CustomOrderConfig.class, MethodSecurityServiceConfig.class).autowire();
}
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(-135);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(order = -135, jsr250Enabled = true)
@ -334,121 +430,38 @@ public class NamespaceGlobalMethodSecurityTests {
}
@Test
@WithMockUser
public void methodSecurityWhenOrderUnspecifiedThenConfiguredToLowestPrecedence() {
this.spring.register(DefaultOrderConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE);
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();
assertThat(this.spring.getContext().getBean("metaDataSourceAdvisor", MethodSecurityMetadataSourceAdvisor.class)
.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE);
assertThatThrownBy(() -> this.service.jsr250()).isInstanceOf(UnsupportedOperationException.class);
}
@EnableGlobalMethodSecurity(jsr250Enabled = true)
@Import(AdvisorOrderConfig.class)
public static class DefaultOrderExtendsMethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}
// --- pre-post-annotations ---
@Test
@WithMockUser
public void methodSecurityWhenPrePostEnabledThenPreAuthorizes() {
this.spring.register(PreAuthorizeConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class PreAuthorizeConfig {
}
@Test
@WithMockUser
public void methodSecurityWhenPrePostEnabledAndCustomGlobalMethodSecurityConfigurationThenPreAuthorizes() {
this.spring.register(PreAuthorizeExtendsGMSCConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class PreAuthorizeExtendsGMSCConfig extends GlobalMethodSecurityConfiguration {
}
// --- proxy-target-class ---
@Test
@WithMockUser
public void methodSecurityWhenProxyTargetClassThenDoesNotWireToInterface() {
this.spring.register(ProxyTargetClassConfig.class, MethodSecurityServiceConfig.class).autowire();
// make sure service was actually proxied
assertThat(this.service.getClass().getInterfaces()).doesNotContain(MethodSecurityService.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(proxyTargetClass = true, prePostEnabled = true)
public static class ProxyTargetClassConfig {
}
@Test
@WithMockUser
public void methodSecurityWhenDefaultProxyThenWiresToInterface() {
this.spring.register(DefaultProxyConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.service.getClass().getInterfaces()).contains(MethodSecurityService.class);
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class DefaultProxyConfig {
}
// --- run-as-manager-ref ---
@Test
@WithMockUser
public void methodSecurityWhenCustomRunAsManagerThenRunAsWrapsAuthentication() {
this.spring.register(CustomRunAsManagerConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThat(this.service.runAs().getAuthorities())
.anyMatch(authority -> "ROLE_RUN_AS_SUPER".equals(authority.getAuthority()));
}
@EnableGlobalMethodSecurity(securedEnabled = true)
public static class CustomRunAsManagerConfig extends GlobalMethodSecurityConfiguration {
@ -461,53 +474,16 @@ public class NamespaceGlobalMethodSecurityTests {
}
// --- secured-annotation ---
@Test
@WithMockUser
public void methodSecurityWhenSecuredEnabledThenSecures() {
this.spring.register(SecuredConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatThrownBy(() -> this.service.secured()).isInstanceOf(AccessDeniedException.class);
assertThatCode(() -> this.service.securedUser()).doesNotThrowAnyException();
assertThatCode(() -> this.service.preAuthorize()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
}
@EnableGlobalMethodSecurity(securedEnabled = true)
public static class SecuredConfig {
}
// --- unsorted ---
@Test
@WithMockUser
public void methodSecurityWhenMissingEnableAnnotationThenShowsHelpfulError() {
assertThatThrownBy(() -> this.spring.register(ExtendsNoEnableAnntotationConfig.class).autowire())
.hasStackTraceContaining(EnableGlobalMethodSecurity.class.getName() + " is required");
}
@Configuration
public static class ExtendsNoEnableAnntotationConfig extends GlobalMethodSecurityConfiguration {
}
@Test
@WithMockUser
public void methodSecurityWhenImportingGlobalMethodSecurityConfigurationSubclassThenAuthorizes() {
this.spring.register(ImportSubclassGMSCConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatCode(() -> this.service.secured()).doesNotThrowAnyException();
assertThatCode(() -> this.service.jsr250()).doesNotThrowAnyException();
assertThatThrownBy(() -> this.service.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Configuration
@Import(PreAuthorizeExtendsGMSCConfig.class)
public static class ImportSubclassGMSCConfig {

View File

@ -77,17 +77,6 @@ public class ReactiveMethodSecurityConfigurationTests {
assertThat(root.hasRole("ABC")).isTrue();
}
@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();
@ -104,6 +93,17 @@ public class ReactiveMethodSecurityConfigurationTests {
assertThat(root.hasRole("ABC")).isTrue();
}
@Configuration
@EnableReactiveMethodSecurity // this imports ReactiveMethodSecurityConfiguration
static class WithRolePrefixConfiguration {
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults("CUSTOM_");
}
}
@Configuration
static class SubclassConfig extends ReactiveMethodSecurityConfiguration {

View File

@ -66,6 +66,16 @@ public class SampleEnableGlobalMethodSecurityTests {
assertThatThrownBy(() -> this.methodSecurityService.preAuthorize()).isInstanceOf(AccessDeniedException.class);
}
@Test
public void customPermissionHandler() {
this.spring.register(CustomPermissionEvaluatorWebSecurityConfig.class).autowire();
assertThat(this.methodSecurityService.hasPermission("allowed")).isNull();
assertThatThrownBy(() -> this.methodSecurityService.hasPermission("denied"))
.isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class SampleWebSecurityConfig {
@ -86,16 +96,6 @@ public class SampleEnableGlobalMethodSecurityTests {
}
@Test
public void customPermissionHandler() {
this.spring.register(CustomPermissionEvaluatorWebSecurityConfig.class).autowire();
assertThat(this.methodSecurityService.hasPermission("allowed")).isNull();
assertThatThrownBy(() -> this.methodSecurityService.hasPermission("denied"))
.isInstanceOf(AccessDeniedException.class);
}
@EnableGlobalMethodSecurity(prePostEnabled = true)
public static class CustomPermissionEvaluatorWebSecurityConfig extends GlobalMethodSecurityConfiguration {

View File

@ -88,16 +88,6 @@ public class Sec2758Tests {
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true)
static class SecurityConfig extends WebSecurityConfigurerAdapter {
@RestController
static class RootController {
@GetMapping("/")
public String ok() {
return "ok";
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
@ -117,6 +107,16 @@ public class Sec2758Tests {
return new DefaultRolesPrefixPostProcessor();
}
@RestController
static class RootController {
@GetMapping("/")
public String ok() {
return "ok";
}
}
}
static class Service {

View File

@ -32,6 +32,39 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
*/
public class AbstractRequestMatcherRegistryAnyMatcherTests {
@Test(expected = BeanCreationException.class)
public void antMatchersCanNotWorkAfterAnyRequest() {
loadConfig(AntMatchersAfterAnyRequestConfig.class);
}
@Test(expected = BeanCreationException.class)
public void mvcMatchersCanNotWorkAfterAnyRequest() {
loadConfig(MvcMatchersAfterAnyRequestConfig.class);
}
@Test(expected = BeanCreationException.class)
public void regexMatchersCanNotWorkAfterAnyRequest() {
loadConfig(RegexMatchersAfterAnyRequestConfig.class);
}
@Test(expected = BeanCreationException.class)
public void anyRequestCanNotWorkAfterItself() {
loadConfig(AnyRequestAfterItselfConfig.class);
}
@Test(expected = BeanCreationException.class)
public void requestMatchersCanNotWorkAfterAnyRequest() {
loadConfig(RequestMatchersAfterAnyRequestConfig.class);
}
private void loadConfig(Class<?>... configs) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setAllowCircularReferences(false);
context.register(configs);
context.setServletContext(new MockServletContext());
context.refresh();
}
@EnableWebSecurity
static class AntMatchersAfterAnyRequestConfig extends WebSecurityConfigurerAdapter {
@ -48,11 +81,6 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests {
}
@Test(expected = BeanCreationException.class)
public void antMatchersCanNotWorkAfterAnyRequest() {
loadConfig(AntMatchersAfterAnyRequestConfig.class);
}
@EnableWebSecurity
static class MvcMatchersAfterAnyRequestConfig extends WebSecurityConfigurerAdapter {
@ -69,11 +97,6 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests {
}
@Test(expected = BeanCreationException.class)
public void mvcMatchersCanNotWorkAfterAnyRequest() {
loadConfig(MvcMatchersAfterAnyRequestConfig.class);
}
@EnableWebSecurity
static class RegexMatchersAfterAnyRequestConfig extends WebSecurityConfigurerAdapter {
@ -90,11 +113,6 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests {
}
@Test(expected = BeanCreationException.class)
public void regexMatchersCanNotWorkAfterAnyRequest() {
loadConfig(RegexMatchersAfterAnyRequestConfig.class);
}
@EnableWebSecurity
static class AnyRequestAfterItselfConfig extends WebSecurityConfigurerAdapter {
@ -111,11 +129,6 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests {
}
@Test(expected = BeanCreationException.class)
public void anyRequestCanNotWorkAfterItself() {
loadConfig(AnyRequestAfterItselfConfig.class);
}
@EnableWebSecurity
static class RequestMatchersAfterAnyRequestConfig extends WebSecurityConfigurerAdapter {
@ -132,17 +145,4 @@ public class AbstractRequestMatcherRegistryAnyMatcherTests {
}
@Test(expected = BeanCreationException.class)
public void requestMatchersCanNotWorkAfterAnyRequest() {
loadConfig(RequestMatchersAfterAnyRequestConfig.class);
}
private void loadConfig(Class<?>... configs) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setAllowCircularReferences(false);
context.register(configs);
context.setServletContext(new MockServletContext());
context.refresh();
}
}

View File

@ -110,6 +110,106 @@ public class SampleWebSecurityConfigurerAdapterTests {
assertThat(this.response.getRedirectedUrl()).isEqualTo("/");
}
@Test
public void readmeSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception {
this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire();
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("http://localhost/login");
}
@Test
public void readmeSampleWhenRequestLoginWithoutCredentialsThenRedirectToLogin() throws Exception {
this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire();
this.request.setServletPath("/login");
this.request.setMethod("POST");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("/login?error");
}
@Test
public void readmeSampleWhenRequestLoginWithValidCredentialsThenRedirectToIndex() throws Exception {
this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire();
this.request.setServletPath("/login");
this.request.setMethod("POST");
this.request.addParameter("username", "user");
this.request.addParameter("password", "password");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("/");
}
@Test
public void multiHttpSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("http://localhost/login");
}
@Test
public void multiHttpSampleWhenRequestLoginWithoutCredentialsThenRedirectToLogin() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/login");
this.request.setMethod("POST");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("/login?error");
}
@Test
public void multiHttpSampleWhenRequestLoginWithValidCredentialsThenRedirectToIndex() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/login");
this.request.setMethod("POST");
this.request.addParameter("username", "user");
this.request.addParameter("password", "password");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("/");
}
@Test
public void multiHttpSampleWhenRequestProtectedResourceThenStatusUnauthorized() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/api/admin/test");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@Test
public void multiHttpSampleWhenRequestAdminResourceWithRegularUserThenStatusForbidden() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/api/admin/test");
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);
}
@Test
public void multiHttpSampleWhenRequestAdminResourceWithAdminUserThenStatusOk() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/api/admin/test");
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);
}
/**
* <pre>
* &lt;http&gt;
@ -151,39 +251,6 @@ public class SampleWebSecurityConfigurerAdapterTests {
}
@Test
public void readmeSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception {
this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire();
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("http://localhost/login");
}
@Test
public void readmeSampleWhenRequestLoginWithoutCredentialsThenRedirectToLogin() throws Exception {
this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire();
this.request.setServletPath("/login");
this.request.setMethod("POST");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("/login?error");
}
@Test
public void readmeSampleWhenRequestLoginWithValidCredentialsThenRedirectToIndex() throws Exception {
this.spring.register(SampleWebSecurityConfigurerAdapter.class).autowire();
this.request.setServletPath("/login");
this.request.setMethod("POST");
this.request.addParameter("username", "user");
this.request.addParameter("password", "password");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("/");
}
/**
* <pre>
* &lt;http security="none" pattern="/resources/**"/&gt;
@ -252,73 +319,6 @@ public class SampleWebSecurityConfigurerAdapterTests {
}
@Test
public void multiHttpSampleWhenRequestSecureResourceThenRedirectToLogin() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("http://localhost/login");
}
@Test
public void multiHttpSampleWhenRequestLoginWithoutCredentialsThenRedirectToLogin() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/login");
this.request.setMethod("POST");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("/login?error");
}
@Test
public void multiHttpSampleWhenRequestLoginWithValidCredentialsThenRedirectToIndex() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/login");
this.request.setMethod("POST");
this.request.addParameter("username", "user");
this.request.addParameter("password", "password");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getRedirectedUrl()).isEqualTo("/");
}
@Test
public void multiHttpSampleWhenRequestProtectedResourceThenStatusUnauthorized() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/api/admin/test");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@Test
public void multiHttpSampleWhenRequestAdminResourceWithRegularUserThenStatusForbidden() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/api/admin/test");
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);
}
@Test
public void multiHttpSampleWhenRequestAdminResourceWithAdminUserThenStatusOk() throws Exception {
this.spring.register(SampleMultiHttpSecurityConfig.class).autowire();
this.request.setServletPath("/api/admin/test");
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);
}
/**
* <code>
* &lt;http security="none" pattern="/resources/**"/&gt;

View File

@ -90,6 +90,27 @@ public class WebSecurityConfigurerAdapterPowermockTests {
assertThat(configurer.configure).isTrue();
}
@Test
public void loadConfigWhenDefaultConfigThenWebAsyncManagerIntegrationFilterAdded() throws Exception {
this.spring.register(WebAsyncPopulatedByDefaultConfig.class).autowire();
WebAsyncManager webAsyncManager = mock(WebAsyncManager.class);
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());
CallableProcessingInterceptor callableProcessingInterceptor = callableProcessingInterceptorArgCaptor
.getAllValues().stream()
.filter(e -> SecurityContextCallableProcessingInterceptor.class.isAssignableFrom(e.getClass()))
.findFirst().orElse(null);
assertThat(callableProcessingInterceptor).isNotNull();
}
private void loadConfig(Class<?>... classes) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setClassLoader(getClass().getClassLoader());
@ -125,27 +146,6 @@ public class WebSecurityConfigurerAdapterPowermockTests {
}
@Test
public void loadConfigWhenDefaultConfigThenWebAsyncManagerIntegrationFilterAdded() throws Exception {
this.spring.register(WebAsyncPopulatedByDefaultConfig.class).autowire();
WebAsyncManager webAsyncManager = mock(WebAsyncManager.class);
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());
CallableProcessingInterceptor callableProcessingInterceptor = callableProcessingInterceptorArgCaptor
.getAllValues().stream()
.filter(e -> SecurityContextCallableProcessingInterceptor.class.isAssignableFrom(e.getClass()))
.findFirst().orElse(null);
assertThat(callableProcessingInterceptor).isNotNull();
}
@EnableWebSecurity
static class WebAsyncPopulatedByDefaultConfig extends WebSecurityConfigurerAdapter {

View File

@ -91,6 +91,135 @@ public class WebSecurityConfigurerAdapterTests {
.andExpect(header().string("X-XSS-Protection", "1; mode=block"));
}
@Test
public void loadConfigWhenRequestAuthenticateThenAuthenticationEventPublished() throws Exception {
this.spring.register(InMemoryAuthWithWebSecurityConfigurerAdapter.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
assertThat(InMemoryAuthWithWebSecurityConfigurerAdapter.EVENTS).isNotEmpty();
assertThat(InMemoryAuthWithWebSecurityConfigurerAdapter.EVENTS).hasSize(1);
}
@Test
public void loadConfigWhenInMemoryConfigureProtectedThenPasswordUpgraded() throws Exception {
this.spring.register(InMemoryConfigureProtectedConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
assertThat(uds.loadUserByUsername("user").getPassword()).startsWith("{bcrypt}");
}
@Test
public void loadConfigWhenInMemoryConfigureGlobalThenPasswordUpgraded() throws Exception {
this.spring.register(InMemoryConfigureGlobalConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
assertThat(uds.loadUserByUsername("user").getPassword()).startsWith("{bcrypt}");
}
@Test
public void loadConfigWhenCustomContentNegotiationStrategyBeanThenOverridesDefault() {
OverrideContentNegotiationStrategySharedObjectConfig.CONTENT_NEGOTIATION_STRATEGY_BEAN = mock(
ContentNegotiationStrategy.class);
this.spring.register(OverrideContentNegotiationStrategySharedObjectConfig.class).autowire();
OverrideContentNegotiationStrategySharedObjectConfig securityConfig = this.spring.getContext()
.getBean(OverrideContentNegotiationStrategySharedObjectConfig.class);
assertThat(securityConfig.contentNegotiationStrategySharedObject).isNotNull();
assertThat(securityConfig.contentNegotiationStrategySharedObject)
.isSameAs(OverrideContentNegotiationStrategySharedObjectConfig.CONTENT_NEGOTIATION_STRATEGY_BEAN);
}
@Test
public void loadConfigWhenDefaultContentNegotiationStrategyThenHeaderContentNegotiationStrategy() {
this.spring.register(ContentNegotiationStrategyDefaultSharedObjectConfig.class).autowire();
ContentNegotiationStrategyDefaultSharedObjectConfig securityConfig = this.spring.getContext()
.getBean(ContentNegotiationStrategyDefaultSharedObjectConfig.class);
assertThat(securityConfig.contentNegotiationStrategySharedObject).isNotNull();
assertThat(securityConfig.contentNegotiationStrategySharedObject)
.isInstanceOf(HeaderContentNegotiationStrategy.class);
}
@Test
public void loadConfigWhenUserDetailsServiceHasCircularReferenceThenStillLoads() {
this.spring.register(RequiresUserDetailsServiceConfig.class, UserDetailsServiceConfig.class).autowire();
MyFilter myFilter = this.spring.getContext().getBean(MyFilter.class);
Throwable thrown = catchThrowable(() -> myFilter.userDetailsService.loadUserByUsername("user"));
assertThat(thrown).isNull();
thrown = catchThrowable(() -> myFilter.userDetailsService.loadUserByUsername("admin"));
assertThat(thrown).isInstanceOf(UsernameNotFoundException.class);
}
// SEC-2274: WebSecurityConfigurer adds ApplicationContext as a shared object
@Test
public void loadConfigWhenSharedObjectsCreatedThenApplicationContextAdded() {
this.spring.register(ApplicationContextSharedObjectConfig.class).autowire();
ApplicationContextSharedObjectConfig securityConfig = this.spring.getContext()
.getBean(ApplicationContextSharedObjectConfig.class);
assertThat(securityConfig.applicationContextSharedObject).isNotNull();
assertThat(securityConfig.applicationContextSharedObject).isSameAs(this.spring.getContext());
}
@Test
public void loadConfigWhenCustomAuthenticationTrustResolverBeanThenOverridesDefault() {
CustomTrustResolverConfig.AUTHENTICATION_TRUST_RESOLVER_BEAN = mock(AuthenticationTrustResolver.class);
this.spring.register(CustomTrustResolverConfig.class).autowire();
CustomTrustResolverConfig securityConfig = this.spring.getContext().getBean(CustomTrustResolverConfig.class);
assertThat(securityConfig.authenticationTrustResolverSharedObject).isNotNull();
assertThat(securityConfig.authenticationTrustResolverSharedObject)
.isSameAs(CustomTrustResolverConfig.AUTHENTICATION_TRUST_RESOLVER_BEAN);
}
@Test
public void compareOrderWebSecurityConfigurerAdapterWhenLowestOrderToDefaultOrderThenGreaterThanZero() {
AnnotationAwareOrderComparator comparator = new AnnotationAwareOrderComparator();
assertThat(comparator.compare(new LowestPriorityWebSecurityConfig(), new DefaultOrderWebSecurityConfig()))
.isGreaterThan(0);
}
// gh-7515
@Test
public void performWhenUsingAuthenticationEventPublisherBeanThenUses() throws Exception {
this.spring.register(CustomAuthenticationEventPublisherBean.class).autowire();
AuthenticationEventPublisher authenticationEventPublisher = this.spring.getContext()
.getBean(AuthenticationEventPublisher.class);
this.mockMvc.perform(get("/").with(httpBasic("user", "password")));
verify(authenticationEventPublisher).publishAuthenticationSuccess(any(Authentication.class));
}
// gh-4400
@Test
public void performWhenUsingAuthenticationEventPublisherInDslThenUses() throws Exception {
this.spring.register(CustomAuthenticationEventPublisherDsl.class).autowire();
AuthenticationEventPublisher authenticationEventPublisher = CustomAuthenticationEventPublisherDsl.EVENT_PUBLISHER;
this.mockMvc.perform(get("/").with(httpBasic("user", "password"))); // fails since
// no
// providers
// configured
verify(authenticationEventPublisher).publishAuthenticationFailure(any(AuthenticationException.class),
any(Authentication.class));
}
@EnableWebSecurity
static class HeadersArePopulatedByDefaultConfig extends WebSecurityConfigurerAdapter {
@ -109,16 +238,6 @@ public class WebSecurityConfigurerAdapterTests {
}
@Test
public void loadConfigWhenRequestAuthenticateThenAuthenticationEventPublished() throws Exception {
this.spring.register(InMemoryAuthWithWebSecurityConfigurerAdapter.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
assertThat(InMemoryAuthWithWebSecurityConfigurerAdapter.EVENTS).isNotEmpty();
assertThat(InMemoryAuthWithWebSecurityConfigurerAdapter.EVENTS).hasSize(1);
}
@EnableWebSecurity
static class InMemoryAuthWithWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter
implements ApplicationListener<AuthenticationSuccessEvent> {
@ -141,16 +260,6 @@ public class WebSecurityConfigurerAdapterTests {
}
@Test
public void loadConfigWhenInMemoryConfigureProtectedThenPasswordUpgraded() throws Exception {
this.spring.register(InMemoryConfigureProtectedConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
assertThat(uds.loadUserByUsername("user").getPassword()).startsWith("{bcrypt}");
}
@EnableWebSecurity
static class InMemoryConfigureProtectedConfig extends WebSecurityConfigurerAdapter {
@ -171,16 +280,6 @@ public class WebSecurityConfigurerAdapterTests {
}
@Test
public void loadConfigWhenInMemoryConfigureGlobalThenPasswordUpgraded() throws Exception {
this.spring.register(InMemoryConfigureGlobalConfig.class).autowire();
this.mockMvc.perform(formLogin()).andExpect(status().is3xxRedirection());
UserDetailsService uds = this.spring.getContext().getBean(UserDetailsService.class);
assertThat(uds.loadUserByUsername("user").getPassword()).startsWith("{bcrypt}");
}
@EnableWebSecurity
static class InMemoryConfigureGlobalConfig extends WebSecurityConfigurerAdapter {
@ -201,20 +300,6 @@ public class WebSecurityConfigurerAdapterTests {
}
@Test
public void loadConfigWhenCustomContentNegotiationStrategyBeanThenOverridesDefault() {
OverrideContentNegotiationStrategySharedObjectConfig.CONTENT_NEGOTIATION_STRATEGY_BEAN = mock(
ContentNegotiationStrategy.class);
this.spring.register(OverrideContentNegotiationStrategySharedObjectConfig.class).autowire();
OverrideContentNegotiationStrategySharedObjectConfig securityConfig = this.spring.getContext()
.getBean(OverrideContentNegotiationStrategySharedObjectConfig.class);
assertThat(securityConfig.contentNegotiationStrategySharedObject).isNotNull();
assertThat(securityConfig.contentNegotiationStrategySharedObject)
.isSameAs(OverrideContentNegotiationStrategySharedObjectConfig.CONTENT_NEGOTIATION_STRATEGY_BEAN);
}
@EnableWebSecurity
static class OverrideContentNegotiationStrategySharedObjectConfig extends WebSecurityConfigurerAdapter {
@ -235,18 +320,6 @@ public class WebSecurityConfigurerAdapterTests {
}
@Test
public void loadConfigWhenDefaultContentNegotiationStrategyThenHeaderContentNegotiationStrategy() {
this.spring.register(ContentNegotiationStrategyDefaultSharedObjectConfig.class).autowire();
ContentNegotiationStrategyDefaultSharedObjectConfig securityConfig = this.spring.getContext()
.getBean(ContentNegotiationStrategyDefaultSharedObjectConfig.class);
assertThat(securityConfig.contentNegotiationStrategySharedObject).isNotNull();
assertThat(securityConfig.contentNegotiationStrategySharedObject)
.isInstanceOf(HeaderContentNegotiationStrategy.class);
}
@EnableWebSecurity
static class ContentNegotiationStrategyDefaultSharedObjectConfig extends WebSecurityConfigurerAdapter {
@ -260,19 +333,6 @@ public class WebSecurityConfigurerAdapterTests {
}
@Test
public void loadConfigWhenUserDetailsServiceHasCircularReferenceThenStillLoads() {
this.spring.register(RequiresUserDetailsServiceConfig.class, UserDetailsServiceConfig.class).autowire();
MyFilter myFilter = this.spring.getContext().getBean(MyFilter.class);
Throwable thrown = catchThrowable(() -> myFilter.userDetailsService.loadUserByUsername("user"));
assertThat(thrown).isNull();
thrown = catchThrowable(() -> myFilter.userDetailsService.loadUserByUsername("admin"));
assertThat(thrown).isInstanceOf(UsernameNotFoundException.class);
}
@Configuration
static class RequiresUserDetailsServiceConfig {
@ -327,18 +387,6 @@ public class WebSecurityConfigurerAdapterTests {
}
// SEC-2274: WebSecurityConfigurer adds ApplicationContext as a shared object
@Test
public void loadConfigWhenSharedObjectsCreatedThenApplicationContextAdded() {
this.spring.register(ApplicationContextSharedObjectConfig.class).autowire();
ApplicationContextSharedObjectConfig securityConfig = this.spring.getContext()
.getBean(ApplicationContextSharedObjectConfig.class);
assertThat(securityConfig.applicationContextSharedObject).isNotNull();
assertThat(securityConfig.applicationContextSharedObject).isSameAs(this.spring.getContext());
}
@EnableWebSecurity
static class ApplicationContextSharedObjectConfig extends WebSecurityConfigurerAdapter {
@ -352,18 +400,6 @@ public class WebSecurityConfigurerAdapterTests {
}
@Test
public void loadConfigWhenCustomAuthenticationTrustResolverBeanThenOverridesDefault() {
CustomTrustResolverConfig.AUTHENTICATION_TRUST_RESOLVER_BEAN = mock(AuthenticationTrustResolver.class);
this.spring.register(CustomTrustResolverConfig.class).autowire();
CustomTrustResolverConfig securityConfig = this.spring.getContext().getBean(CustomTrustResolverConfig.class);
assertThat(securityConfig.authenticationTrustResolverSharedObject).isNotNull();
assertThat(securityConfig.authenticationTrustResolverSharedObject)
.isSameAs(CustomTrustResolverConfig.AUTHENTICATION_TRUST_RESOLVER_BEAN);
}
@EnableWebSecurity
static class CustomTrustResolverConfig extends WebSecurityConfigurerAdapter {
@ -384,13 +420,6 @@ public class WebSecurityConfigurerAdapterTests {
}
@Test
public void compareOrderWebSecurityConfigurerAdapterWhenLowestOrderToDefaultOrderThenGreaterThanZero() {
AnnotationAwareOrderComparator comparator = new AnnotationAwareOrderComparator();
assertThat(comparator.compare(new LowestPriorityWebSecurityConfig(), new DefaultOrderWebSecurityConfig()))
.isGreaterThan(0);
}
static class DefaultOrderWebSecurityConfig extends WebSecurityConfigurerAdapter {
}
@ -400,19 +429,6 @@ public class WebSecurityConfigurerAdapterTests {
}
// gh-7515
@Test
public void performWhenUsingAuthenticationEventPublisherBeanThenUses() throws Exception {
this.spring.register(CustomAuthenticationEventPublisherBean.class).autowire();
AuthenticationEventPublisher authenticationEventPublisher = this.spring.getContext()
.getBean(AuthenticationEventPublisher.class);
this.mockMvc.perform(get("/").with(httpBasic("user", "password")));
verify(authenticationEventPublisher).publishAuthenticationSuccess(any(Authentication.class));
}
@EnableWebSecurity
static class CustomAuthenticationEventPublisherBean extends WebSecurityConfigurerAdapter {
@ -429,22 +445,6 @@ public class WebSecurityConfigurerAdapterTests {
}
// gh-4400
@Test
public void performWhenUsingAuthenticationEventPublisherInDslThenUses() throws Exception {
this.spring.register(CustomAuthenticationEventPublisherDsl.class).autowire();
AuthenticationEventPublisher authenticationEventPublisher = CustomAuthenticationEventPublisherDsl.EVENT_PUBLISHER;
this.mockMvc.perform(get("/").with(httpBasic("user", "password"))); // fails since
// no
// providers
// configured
verify(authenticationEventPublisher).publishAuthenticationFailure(any(AuthenticationException.class),
any(Authentication.class));
}
@EnableWebSecurity
static class CustomAuthenticationEventPublisherDsl extends WebSecurityConfigurerAdapter {

View File

@ -69,6 +69,28 @@ public class HttpConfigurationTests {
+ " Consider using addFilterBefore or addFilterAfter instead.");
}
// https://github.com/spring-projects/spring-security-javaconfig/issues/104
@Test
public void configureWhenAddFilterCasAuthenticationFilterThenFilterAdded() throws Exception {
CasAuthenticationFilterConfig.CAS_AUTHENTICATION_FILTER = spy(new CasAuthenticationFilter());
this.spring.register(CasAuthenticationFilterConfig.class).autowire();
this.mockMvc.perform(get("/"));
verify(CasAuthenticationFilterConfig.CAS_AUTHENTICATION_FILTER).doFilter(any(ServletRequest.class),
any(ServletResponse.class), any(FilterChain.class));
}
@Test
public void configureWhenConfigIsRequestMatchersJavadocThenAuthorizationApplied() throws Exception {
this.spring.register(RequestMatcherRegistryConfigs.class).autowire();
this.mockMvc.perform(get("/oauth/a")).andExpect(status().isUnauthorized());
this.mockMvc.perform(get("/oauth/b")).andExpect(status().isUnauthorized());
this.mockMvc.perform(get("/api/a")).andExpect(status().isUnauthorized());
this.mockMvc.perform(get("/api/b")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class UnregisteredFilterConfig extends WebSecurityConfigurerAdapter {
@ -101,18 +123,6 @@ public class HttpConfigurationTests {
}
// https://github.com/spring-projects/spring-security-javaconfig/issues/104
@Test
public void configureWhenAddFilterCasAuthenticationFilterThenFilterAdded() throws Exception {
CasAuthenticationFilterConfig.CAS_AUTHENTICATION_FILTER = spy(new CasAuthenticationFilter());
this.spring.register(CasAuthenticationFilterConfig.class).autowire();
this.mockMvc.perform(get("/"));
verify(CasAuthenticationFilterConfig.CAS_AUTHENTICATION_FILTER).doFilter(any(ServletRequest.class),
any(ServletResponse.class), any(FilterChain.class));
}
@EnableWebSecurity
static class CasAuthenticationFilterConfig extends WebSecurityConfigurerAdapter {
@ -128,16 +138,6 @@ public class HttpConfigurationTests {
}
@Test
public void configureWhenConfigIsRequestMatchersJavadocThenAuthorizationApplied() throws Exception {
this.spring.register(RequestMatcherRegistryConfigs.class).autowire();
this.mockMvc.perform(get("/oauth/a")).andExpect(status().isUnauthorized());
this.mockMvc.perform(get("/oauth/b")).andExpect(status().isUnauthorized());
this.mockMvc.perform(get("/api/a")).andExpect(status().isUnauthorized());
this.mockMvc.perform(get("/api/b")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class RequestMatcherRegistryConfigs extends WebSecurityConfigurerAdapter {

View File

@ -101,6 +101,212 @@ public class NamespaceHttpTests {
any(), anyCollection());
}
@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"));
}
@Test // http@authentication-manager-ref
public void configureWhenAuthenticationManagerProvidedThenVerifyUse() throws Exception {
AuthenticationManagerRefConfig.AUTHENTICATION_MANAGER = mock(AuthenticationManager.class);
this.spring.register(AuthenticationManagerRefConfig.class).autowire();
this.mockMvc.perform(formLogin());
verify(AuthenticationManagerRefConfig.AUTHENTICATION_MANAGER, times(1)).authenticate(any(Authentication.class));
}
@Test // http@create-session=always
public void configureWhenSessionCreationPolicyAlwaysThenSessionCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionAlwaysConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/")).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNotNull();
assertThat(session.isNew()).isTrue();
}
@Test // http@create-session=stateless
public void configureWhenSessionCreationPolicyStatelessThenSessionNotCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionStatelessConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/")).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@Test // http@create-session=ifRequired
public void configureWhenSessionCreationPolicyIfRequiredThenSessionCreatedWhenRequiredOnRequest() throws Exception {
this.spring.register(IfRequiredConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/unsecure")).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
mvcResult = this.mockMvc.perform(formLogin()).andReturn();
session = mvcResult.getRequest().getSession(false);
assertThat(session).isNotNull();
assertThat(session.isNew()).isTrue();
}
@Test // http@create-session=never
public void configureWhenSessionCreationPolicyNeverThenSessionNotCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionNeverConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/")).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@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"));
}
@Test // http@jaas-api-provision
public void configureWhenJaasApiIntegrationFilterAddedThenJaasSubjectObtained() throws Exception {
LoginContext loginContext = mock(LoginContext.class);
when(loginContext.getSubject()).thenReturn(new Subject());
JaasAuthenticationToken authenticationToken = mock(JaasAuthenticationToken.class);
when(authenticationToken.isAuthenticated()).thenReturn(true);
when(authenticationToken.getLoginContext()).thenReturn(loginContext);
this.spring.register(JaasApiProvisionConfig.class).autowire();
this.mockMvc.perform(get("/").with(authentication(authenticationToken)));
verify(loginContext, times(1)).getSubject();
}
@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\""));
}
@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);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
}
@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);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(RegexRequestMatcher.class);
}
@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);
}
@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);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
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(securityFilterChain.getFilters()).isEmpty();
}
@Test // http@security-context-repository-ref
public void configureWhenNullSecurityContextRepositoryThenSecurityContextNotSavedInSession() throws Exception {
this.spring.register(SecurityContextRepoConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(formLogin()).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@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);
}
@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);
}
@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);
}
@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);
}
@EnableWebSecurity
static class AccessDecisionManagerRefConfig extends WebSecurityConfigurerAdapter {
@ -118,14 +324,6 @@ public class NamespaceHttpTests {
}
@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"));
}
@EnableWebSecurity
static class AccessDeniedPageConfig extends WebSecurityConfigurerAdapter {
@ -144,16 +342,6 @@ public class NamespaceHttpTests {
}
@Test // http@authentication-manager-ref
public void configureWhenAuthenticationManagerProvidedThenVerifyUse() throws Exception {
AuthenticationManagerRefConfig.AUTHENTICATION_MANAGER = mock(AuthenticationManager.class);
this.spring.register(AuthenticationManagerRefConfig.class).autowire();
this.mockMvc.perform(formLogin());
verify(AuthenticationManagerRefConfig.AUTHENTICATION_MANAGER, times(1)).authenticate(any(Authentication.class));
}
@EnableWebSecurity
static class AuthenticationManagerRefConfig extends WebSecurityConfigurerAdapter {
@ -177,17 +365,6 @@ public class NamespaceHttpTests {
}
@Test // http@create-session=always
public void configureWhenSessionCreationPolicyAlwaysThenSessionCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionAlwaysConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/")).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNotNull();
assertThat(session.isNew()).isTrue();
}
@EnableWebSecurity
static class CreateSessionAlwaysConfig extends WebSecurityConfigurerAdapter {
@ -205,16 +382,6 @@ public class NamespaceHttpTests {
}
@Test // http@create-session=stateless
public void configureWhenSessionCreationPolicyStatelessThenSessionNotCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionStatelessConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/")).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@EnableWebSecurity
static class CreateSessionStatelessConfig extends WebSecurityConfigurerAdapter {
@ -232,22 +399,6 @@ public class NamespaceHttpTests {
}
@Test // http@create-session=ifRequired
public void configureWhenSessionCreationPolicyIfRequiredThenSessionCreatedWhenRequiredOnRequest() throws Exception {
this.spring.register(IfRequiredConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/unsecure")).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
mvcResult = this.mockMvc.perform(formLogin()).andReturn();
session = mvcResult.getRequest().getSession(false);
assertThat(session).isNotNull();
assertThat(session.isNew()).isTrue();
}
@EnableWebSecurity
static class IfRequiredConfig extends WebSecurityConfigurerAdapter {
@ -268,16 +419,6 @@ public class NamespaceHttpTests {
}
@Test // http@create-session=never
public void configureWhenSessionCreationPolicyNeverThenSessionNotCreatedOnRequest() throws Exception {
this.spring.register(CreateSessionNeverConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(get("/")).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@EnableWebSecurity
static class CreateSessionNeverConfig extends WebSecurityConfigurerAdapter {
@ -295,15 +436,6 @@ public class NamespaceHttpTests {
}
@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"));
}
@EnableWebSecurity
static class EntryPointRefConfig extends WebSecurityConfigurerAdapter {
@ -323,22 +455,6 @@ public class NamespaceHttpTests {
}
@Test // http@jaas-api-provision
public void configureWhenJaasApiIntegrationFilterAddedThenJaasSubjectObtained() throws Exception {
LoginContext loginContext = mock(LoginContext.class);
when(loginContext.getSubject()).thenReturn(new Subject());
JaasAuthenticationToken authenticationToken = mock(JaasAuthenticationToken.class);
when(authenticationToken.isAuthenticated()).thenReturn(true);
when(authenticationToken.getLoginContext()).thenReturn(loginContext);
this.spring.register(JaasApiProvisionConfig.class).autowire();
this.mockMvc.perform(get("/").with(authentication(authenticationToken)));
verify(loginContext, times(1)).getSubject();
}
@EnableWebSecurity
static class JaasApiProvisionConfig extends WebSecurityConfigurerAdapter {
@ -352,14 +468,6 @@ public class NamespaceHttpTests {
}
@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\""));
}
@EnableWebSecurity
static class RealmConfig extends WebSecurityConfigurerAdapter {
@ -377,18 +485,6 @@ public class NamespaceHttpTests {
}
@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);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
}
@EnableWebSecurity
static class RequestMatcherAntConfig extends WebSecurityConfigurerAdapter {
@ -402,18 +498,6 @@ public class NamespaceHttpTests {
}
@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);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(RegexRequestMatcher.class);
}
@EnableWebSecurity
static class RequestMatcherRegexConfig extends WebSecurityConfigurerAdapter {
@ -427,19 +511,6 @@ public class NamespaceHttpTests {
}
@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);
}
@EnableWebSecurity
static class RequestMatcherRefConfig extends WebSecurityConfigurerAdapter {
@ -462,28 +533,6 @@ public class NamespaceHttpTests {
}
@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);
assertThat(securityFilterChain.getRequestMatcher()).isInstanceOf(AntPathRequestMatcher.class);
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(securityFilterChain.getFilters()).isEmpty();
}
@EnableWebSecurity
static class SecurityNoneConfig extends WebSecurityConfigurerAdapter {
@ -498,15 +547,6 @@ public class NamespaceHttpTests {
}
@Test // http@security-context-repository-ref
public void configureWhenNullSecurityContextRepositoryThenSecurityContextNotSavedInSession() throws Exception {
this.spring.register(SecurityContextRepoConfig.class).autowire();
MvcResult mvcResult = this.mockMvc.perform(formLogin()).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@EnableWebSecurity
static class SecurityContextRepoConfig extends WebSecurityConfigurerAdapter {
@ -535,16 +575,6 @@ public class NamespaceHttpTests {
}
@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);
}
@EnableWebSecurity
static class ServletApiProvisionConfig extends WebSecurityConfigurerAdapter {
@ -562,16 +592,6 @@ public class NamespaceHttpTests {
}
@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);
}
@EnableWebSecurity
static class ServletApiProvisionDefaultsConfig extends WebSecurityConfigurerAdapter {
@ -599,16 +619,6 @@ public class NamespaceHttpTests {
}
@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);
}
@EnableWebSecurity
static class UseExpressionsConfig extends WebSecurityConfigurerAdapter {
@ -638,16 +648,6 @@ public class NamespaceHttpTests {
}
@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);
}
@EnableWebSecurity
static class DisableUseExpressionsConfig extends WebSecurityConfigurerAdapter {

View File

@ -103,6 +103,50 @@ public class WebSecurityTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@Test
public void ignoringMvcMatcherServletPath() throws Exception {
loadConfig(MvcMatcherServletPathConfig.class, LegacyMvcMatchingConfig.class);
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/other");
this.request.setRequestURI("/other/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.setServletContext(new MockServletContext());
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -147,41 +191,6 @@ public class WebSecurityTests {
}
@Test
public void ignoringMvcMatcherServletPath() throws Exception {
loadConfig(MvcMatcherServletPathConfig.class, LegacyMvcMatchingConfig.class);
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/other");
this.request.setRequestURI("/other/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -237,13 +246,4 @@ public class WebSecurityTests {
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.setServletContext(new MockServletContext());
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@ -63,6 +63,48 @@ public class EnableWebSecurityTests {
assertThat(authentication.isAuthenticated()).isTrue();
}
@Test
public void loadConfigWhenChildConfigExtendsSecurityConfigThenSecurityConfigInherited() {
this.spring.register(ChildSecurityConfig.class).autowire();
this.spring.getContext().getBean("springSecurityFilterChain", DebugFilter.class);
}
@Test
public void configureWhenEnableWebMvcThenAuthenticationPrincipalResolvable() throws Exception {
this.spring.register(AuthenticationPrincipalConfig.class).autowire();
this.mockMvc.perform(get("/").with(authentication(new TestingAuthenticationToken("user1", "password"))))
.andExpect(content().string("user1"));
}
@Test
public void securityFilterChainWhenEnableWebMvcThenAuthenticationPrincipalResolvable() throws Exception {
this.spring.register(SecurityFilterChainAuthenticationPrincipalConfig.class).autowire();
this.mockMvc.perform(get("/").with(authentication(new TestingAuthenticationToken("user1", "password"))))
.andExpect(content().string("user1"));
}
@Test
public void enableWebSecurityWhenNoConfigurationAnnotationThenBeanProxyingEnabled() {
this.spring.register(BeanProxyEnabledByDefaultConfig.class).autowire();
Child childBean = this.spring.getContext().getBean(Child.class);
Parent parentBean = this.spring.getContext().getBean(Parent.class);
assertThat(parentBean.getChild()).isSameAs(childBean);
}
@Test
public void enableWebSecurityWhenProxyBeanMethodsFalseThenBeanProxyingDisabled() {
this.spring.register(BeanProxyDisabledConfig.class).autowire();
Child childBean = this.spring.getContext().getBean(Child.class);
Parent parentBean = this.spring.getContext().getBean(Parent.class);
assertThat(parentBean.getChild()).isNotSameAs(childBean);
}
@EnableWebSecurity
static class SecurityConfig extends WebSecurityConfigurerAdapter {
@ -94,12 +136,6 @@ public class EnableWebSecurityTests {
}
@Test
public void loadConfigWhenChildConfigExtendsSecurityConfigThenSecurityConfigInherited() {
this.spring.register(ChildSecurityConfig.class).autowire();
this.spring.getContext().getBean("springSecurityFilterChain", DebugFilter.class);
}
@Configuration
static class ChildSecurityConfig extends DebugSecurityConfig {
@ -110,14 +146,6 @@ public class EnableWebSecurityTests {
}
@Test
public void configureWhenEnableWebMvcThenAuthenticationPrincipalResolvable() throws Exception {
this.spring.register(AuthenticationPrincipalConfig.class).autowire();
this.mockMvc.perform(get("/").with(authentication(new TestingAuthenticationToken("user1", "password"))))
.andExpect(content().string("user1"));
}
@EnableWebSecurity
@EnableWebMvc
static class AuthenticationPrincipalConfig extends WebSecurityConfigurerAdapter {
@ -138,14 +166,6 @@ public class EnableWebSecurityTests {
}
@Test
public void securityFilterChainWhenEnableWebMvcThenAuthenticationPrincipalResolvable() throws Exception {
this.spring.register(SecurityFilterChainAuthenticationPrincipalConfig.class).autowire();
this.mockMvc.perform(get("/").with(authentication(new TestingAuthenticationToken("user1", "password"))))
.andExpect(content().string("user1"));
}
@EnableWebSecurity
@EnableWebMvc
static class SecurityFilterChainAuthenticationPrincipalConfig {
@ -167,16 +187,6 @@ public class EnableWebSecurityTests {
}
@Test
public void enableWebSecurityWhenNoConfigurationAnnotationThenBeanProxyingEnabled() {
this.spring.register(BeanProxyEnabledByDefaultConfig.class).autowire();
Child childBean = this.spring.getContext().getBean(Child.class);
Parent parentBean = this.spring.getContext().getBean(Parent.class);
assertThat(parentBean.getChild()).isSameAs(childBean);
}
@EnableWebSecurity
static class BeanProxyEnabledByDefaultConfig extends WebSecurityConfigurerAdapter {
@ -192,16 +202,6 @@ public class EnableWebSecurityTests {
}
@Test
public void enableWebSecurityWhenProxyBeanMethodsFalseThenBeanProxyingDisabled() {
this.spring.register(BeanProxyDisabledConfig.class).autowire();
Child childBean = this.spring.getContext().getBean(Child.class);
Parent parentBean = this.spring.getContext().getBean(Parent.class);
assertThat(parentBean.getChild()).isNotSameAs(childBean);
}
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
static class BeanProxyDisabledConfig extends WebSecurityConfigurerAdapter {

View File

@ -114,26 +114,6 @@ public class HttpSecurityConfigurationTests {
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();
@ -141,16 +121,6 @@ public class HttpSecurityConfigurationTests {
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();
}
}
@Test
public void authenticateWhenDefaultFilterChainBeanThenSessionIdChanges() throws Exception {
this.spring.register(SecurityEnabledConfig.class, UserDetailsConfig.class).autowire();
@ -194,6 +164,36 @@ public class HttpSecurityConfigurationTests {
this.mockMvc.perform(get("/login")).andExpect(status().isOk());
}
@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();
}
}
@EnableWebSecurity
static class AuthorizeRequestsConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeRequests(authorize -> authorize.anyRequest().permitAll()).build();
}
}
@EnableWebSecurity
static class SecurityEnabledConfig {

View File

@ -133,6 +133,68 @@ public class OAuth2ClientConfigurationTests {
verify(accessTokenResponseClient, times(1)).getTokenResponse(any(OAuth2ClientCredentialsGrantRequest.class));
}
// 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");
}
@Test
public void loadContextWhenClientRegistrationRepositoryNotRegisteredThenThrowNoSuchBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(ClientRegistrationRepositoryNotRegisteredConfig.class).autowire())
.hasRootCauseInstanceOf(NoSuchBeanDefinitionException.class).hasMessageContaining(
"No qualifying bean of type '" + ClientRegistrationRepository.class.getName() + "' available");
}
@Test
public void loadContextWhenClientRegistrationRepositoryRegisteredTwiceThenThrowNoUniqueBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(ClientRegistrationRepositoryRegisteredTwiceConfig.class)
.autowire()).hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class).hasMessageContaining(
"expected single matching bean but found 2: clientRegistrationRepository1,clientRegistrationRepository2");
}
@Test
public void loadContextWhenAccessTokenResponseClientRegisteredTwiceThenThrowNoUniqueBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(AccessTokenResponseClientRegisteredTwiceConfig.class).autowire())
.hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class).hasMessageContaining(
"expected single matching bean but found 2: accessTokenResponseClient1,accessTokenResponseClient2");
}
// gh-8700
@Test
public void requestWhenAuthorizedClientManagerConfiguredThenUsed() throws Exception {
String clientRegistrationId = "client1";
String principalName = "user1";
TestingAuthenticationToken authentication = new TestingAuthenticationToken(principalName, "password");
ClientRegistrationRepository clientRegistrationRepository = mock(ClientRegistrationRepository.class);
OAuth2AuthorizedClientRepository authorizedClientRepository = mock(OAuth2AuthorizedClientRepository.class);
OAuth2AuthorizedClientManager authorizedClientManager = mock(OAuth2AuthorizedClientManager.class);
ClientRegistration clientRegistration = clientRegistration().registrationId(clientRegistrationId).build();
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(clientRegistration, principalName,
TestOAuth2AccessTokens.noScopes());
when(authorizedClientManager.authorize(any())).thenReturn(authorizedClient);
OAuth2AuthorizedClientManagerRegisteredConfig.CLIENT_REGISTRATION_REPOSITORY = clientRegistrationRepository;
OAuth2AuthorizedClientManagerRegisteredConfig.AUTHORIZED_CLIENT_REPOSITORY = authorizedClientRepository;
OAuth2AuthorizedClientManagerRegisteredConfig.AUTHORIZED_CLIENT_MANAGER = authorizedClientManager;
this.spring.register(OAuth2AuthorizedClientManagerRegisteredConfig.class).autowire();
this.mockMvc.perform(get("/authorized-client").with(authentication(authentication))).andExpect(status().isOk())
.andExpect(content().string("resolved"));
verify(authorizedClientManager).authorize(any());
verifyNoInteractions(clientRegistrationRepository);
verifyNoInteractions(authorizedClientRepository);
}
@EnableWebMvc
@EnableWebSecurity
static class OAuth2AuthorizedClientArgumentResolverConfig extends WebSecurityConfigurerAdapter {
@ -145,17 +207,6 @@ public class OAuth2ClientConfigurationTests {
protected void configure(HttpSecurity http) {
}
@RestController
public class Controller {
@GetMapping("/authorized-client")
public String authorizedClient(
@RegisteredOAuth2AuthorizedClient("client1") OAuth2AuthorizedClient authorizedClient) {
return authorizedClient != null ? "resolved" : "not-resolved";
}
}
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return CLIENT_REGISTRATION_REPOSITORY;
@ -171,17 +222,17 @@ public class OAuth2ClientConfigurationTests {
return ACCESS_TOKEN_RESPONSE_CLIENT;
}
@RestController
public class Controller {
@GetMapping("/authorized-client")
public String authorizedClient(
@RegisteredOAuth2AuthorizedClient("client1") OAuth2AuthorizedClient authorizedClient) {
return authorizedClient != null ? "resolved" : "not-resolved";
}
}
// 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");
}
@EnableWebMvc
@ -221,13 +272,6 @@ public class OAuth2ClientConfigurationTests {
}
@Test
public void loadContextWhenClientRegistrationRepositoryNotRegisteredThenThrowNoSuchBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(ClientRegistrationRepositoryNotRegisteredConfig.class).autowire())
.hasRootCauseInstanceOf(NoSuchBeanDefinitionException.class).hasMessageContaining(
"No qualifying bean of type '" + ClientRegistrationRepository.class.getName() + "' available");
}
@EnableWebMvc
@EnableWebSecurity
static class ClientRegistrationRepositoryNotRegisteredConfig extends WebSecurityConfigurerAdapter {
@ -245,13 +289,6 @@ public class OAuth2ClientConfigurationTests {
}
@Test
public void loadContextWhenClientRegistrationRepositoryRegisteredTwiceThenThrowNoUniqueBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(ClientRegistrationRepositoryRegisteredTwiceConfig.class)
.autowire()).hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class).hasMessageContaining(
"expected single matching bean but found 2: clientRegistrationRepository1,clientRegistrationRepository2");
}
@EnableWebMvc
@EnableWebSecurity
static class ClientRegistrationRepositoryRegisteredTwiceConfig extends WebSecurityConfigurerAdapter {
@ -289,13 +326,6 @@ public class OAuth2ClientConfigurationTests {
}
@Test
public void loadContextWhenAccessTokenResponseClientRegisteredTwiceThenThrowNoUniqueBeanDefinitionException() {
assertThatThrownBy(() -> this.spring.register(AccessTokenResponseClientRegisteredTwiceConfig.class).autowire())
.hasRootCauseInstanceOf(NoUniqueBeanDefinitionException.class).hasMessageContaining(
"expected single matching bean but found 2: accessTokenResponseClient1,accessTokenResponseClient2");
}
@EnableWebMvc
@EnableWebSecurity
static class AccessTokenResponseClientRegisteredTwiceConfig extends WebSecurityConfigurerAdapter {
@ -333,36 +363,6 @@ public class OAuth2ClientConfigurationTests {
}
// gh-8700
@Test
public void requestWhenAuthorizedClientManagerConfiguredThenUsed() throws Exception {
String clientRegistrationId = "client1";
String principalName = "user1";
TestingAuthenticationToken authentication = new TestingAuthenticationToken(principalName, "password");
ClientRegistrationRepository clientRegistrationRepository = mock(ClientRegistrationRepository.class);
OAuth2AuthorizedClientRepository authorizedClientRepository = mock(OAuth2AuthorizedClientRepository.class);
OAuth2AuthorizedClientManager authorizedClientManager = mock(OAuth2AuthorizedClientManager.class);
ClientRegistration clientRegistration = clientRegistration().registrationId(clientRegistrationId).build();
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(clientRegistration, principalName,
TestOAuth2AccessTokens.noScopes());
when(authorizedClientManager.authorize(any())).thenReturn(authorizedClient);
OAuth2AuthorizedClientManagerRegisteredConfig.CLIENT_REGISTRATION_REPOSITORY = clientRegistrationRepository;
OAuth2AuthorizedClientManagerRegisteredConfig.AUTHORIZED_CLIENT_REPOSITORY = authorizedClientRepository;
OAuth2AuthorizedClientManagerRegisteredConfig.AUTHORIZED_CLIENT_MANAGER = authorizedClientManager;
this.spring.register(OAuth2AuthorizedClientManagerRegisteredConfig.class).autowire();
this.mockMvc.perform(get("/authorized-client").with(authentication(authentication))).andExpect(status().isOk())
.andExpect(content().string("resolved"));
verify(authorizedClientManager).authorize(any());
verifyNoInteractions(clientRegistrationRepository);
verifyNoInteractions(authorizedClientRepository);
}
@EnableWebMvc
@EnableWebSecurity
static class OAuth2AuthorizedClientManagerRegisteredConfig extends WebSecurityConfigurerAdapter {
@ -375,17 +375,6 @@ public class OAuth2ClientConfigurationTests {
protected void configure(HttpSecurity http) {
}
@RestController
public class Controller {
@GetMapping("/authorized-client")
public String authorizedClient(
@RegisteredOAuth2AuthorizedClient("client1") OAuth2AuthorizedClient authorizedClient) {
return authorizedClient != null ? "resolved" : "not-resolved";
}
}
@Bean
public ClientRegistrationRepository clientRegistrationRepository() {
return CLIENT_REGISTRATION_REPOSITORY;
@ -401,6 +390,17 @@ public class OAuth2ClientConfigurationTests {
return AUTHORIZED_CLIENT_MANAGER;
}
@RestController
public class Controller {
@GetMapping("/authorized-client")
public String authorizedClient(
@RegisteredOAuth2AuthorizedClient("client1") OAuth2AuthorizedClient authorizedClient) {
return authorizedClient != null ? "resolved" : "not-resolved";
}
}
}
}

View File

@ -45,33 +45,11 @@ public class Sec2515Tests {
this.spring.register(StackOverflowSecurityConfig.class).autowire();
}
@EnableWebSecurity
static class StackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@Test(expected = FatalBeanException.class)
public void loadConfigWhenAuthenticationManagerNotConfiguredAndRegisterBeanCustomNameThenThrowFatalBeanException() {
this.spring.register(CustomBeanNameStackOverflowSecurityConfig.class).autowire();
}
@EnableWebSecurity
static class CustomBeanNameStackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Bean(name = "custom")
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
// SEC-2549
@Test
public void loadConfigWhenChildClassLoaderSetThenContextLoads() {
@ -83,6 +61,33 @@ public class Sec2515Tests {
this.spring.autowire();
assertThat(this.spring.getContext().getBean(AuthenticationManager.class)).isNotNull();
} // SEC-2515
@Test
public void loadConfigWhenAuthenticationManagerConfiguredAndRegisterBeanThenContextLoads() {
this.spring.register(SecurityConfig.class).autowire();
}
@EnableWebSecurity
static class StackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@EnableWebSecurity
static class CustomBeanNameStackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@Bean(name = "custom")
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
@EnableWebSecurity
@ -98,12 +103,6 @@ public class Sec2515Tests {
}
// SEC-2515
@Test
public void loadConfigWhenAuthenticationManagerConfiguredAndRegisterBeanThenContextLoads() {
this.spring.register(SecurityConfig.class).autowire();
}
@EnableWebSecurity
static class SecurityConfig extends WebSecurityConfigurerAdapter {

View File

@ -79,6 +79,9 @@ public class WebSecurityConfigurationTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Rule
public SpringTestRule child = new SpringTestRule();
@Autowired
private MockMvc mockMvc;
@ -113,6 +116,177 @@ public class WebSecurityConfigurationTests {
assertThat(filterChains.get(5).matches(request)).isTrue();
}
@Test
public void loadConfigWhenSecurityFilterChainsHaveOrderThenFilterChainsOrdered() {
this.spring.register(SortedSecurityFilterChainConfig.class).autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
assertThat(filterChains).hasSize(4);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
request.setServletPath("/role1/**");
assertThat(filterChains.get(0).matches(request)).isTrue();
request.setServletPath("/role2/**");
assertThat(filterChains.get(1).matches(request)).isTrue();
request.setServletPath("/role3/**");
assertThat(filterChains.get(2).matches(request)).isTrue();
request.setServletPath("/**");
assertThat(filterChains.get(3).matches(request)).isTrue();
}
@Test
public void loadConfigWhenWebSecurityConfigurersHaveSameOrderThenThrowBeanCreationException() {
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());
}
@Test
public void loadConfigWhenWebInvocationPrivilegeEvaluatorSetThenIsRegistered() {
PrivilegeEvaluatorConfigurerAdapterConfig.PRIVILEGE_EVALUATOR = mock(WebInvocationPrivilegeEvaluator.class);
this.spring.register(PrivilegeEvaluatorConfigurerAdapterConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isSameAs(PrivilegeEvaluatorConfigurerAdapterConfig.PRIVILEGE_EVALUATOR);
}
@Test
public void loadConfigWhenSecurityExpressionHandlerSetThenIsRegistered() {
WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER = mock(SecurityExpressionHandler.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);
}
@Test
public void loadConfigWhenSecurityExpressionHandlerIsNullThenException() {
Throwable thrown = catchThrowable(
() -> this.spring.register(NullWebSecurityExpressionHandlerConfig.class).autowire());
assertThat(thrown).isInstanceOf(BeanCreationException.class);
assertThat(thrown).hasRootCauseExactlyInstanceOf(IllegalArgumentException.class);
}
@Test
public void loadConfigWhenDefaultSecurityExpressionHandlerThenDefaultIsRegistered() {
this.spring.register(WebSecurityExpressionHandlerDefaultsConfig.class).autowire();
assertThat(this.spring.getContext().getBean(SecurityExpressionHandler.class))
.isInstanceOf(DefaultWebSecurityExpressionHandler.class);
}
@Test
public void securityExpressionHandlerWhenRoleHierarchyBeanThenRoleHierarchyUsed() {
this.spring.register(WebSecurityExpressionHandlerRoleHierarchyBeanConfig.class).autowire();
TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "notused", "ROLE_ADMIN");
FilterInvocation invocation = new FilterInvocation(new MockHttpServletRequest("GET", ""),
new MockHttpServletResponse(), new MockFilterChain());
AbstractSecurityExpressionHandler handler = this.spring.getContext()
.getBean(AbstractSecurityExpressionHandler.class);
EvaluationContext evaluationContext = handler.createEvaluationContext(authentication, invocation);
Expression expression = handler.getExpressionParser().parseExpression("hasRole('ROLE_USER')");
boolean granted = expression.getValue(evaluationContext, Boolean.class);
assertThat(granted).isTrue();
}
@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());
AbstractSecurityExpressionHandler handler = this.spring.getContext()
.getBean(AbstractSecurityExpressionHandler.class);
EvaluationContext evaluationContext = handler.createEvaluationContext(authentication, invocation);
Expression expression = handler.getExpressionParser().parseExpression("hasPermission(#study,'DELETE')");
boolean granted = expression.getValue(evaluationContext, Boolean.class);
assertThat(granted).isTrue();
}
@Test
public void loadConfigWhenDefaultWebInvocationPrivilegeEvaluatorThenDefaultIsRegistered() {
this.spring.register(WebInvocationPrivilegeEvaluatorDefaultsConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
}
@Test
public void loadConfigWhenSecurityFilterChainBeanThenDefaultWebInvocationPrivilegeEvaluatorIsRegistered() {
this.spring.register(AuthorizeRequestsFilterChainConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
}
// SEC-2303
@Test
public void loadConfigWhenDefaultSecurityExpressionHandlerThenBeanResolverSet() throws Exception {
this.spring.register(DefaultExpressionHandlerSetsBeanResolverConfig.class).autowire();
this.mockMvc.perform(get("/")).andExpect(status().isOk());
this.mockMvc.perform(post("/")).andExpect(status().isForbidden());
}
// SEC-2461
@Test
public void loadConfigWhenMultipleWebSecurityConfigurationThenContextLoads() {
this.spring.register(ParentConfig.class).autowire();
this.child.register(ChildConfig.class);
this.child.getContext().setParent(this.spring.getContext());
this.child.autowire();
assertThat(this.spring.getContext().getBean("springSecurityFilterChain")).isNotNull();
assertThat(this.child.getContext().getBean("springSecurityFilterChain")).isNotNull();
assertThat(this.spring.getContext().containsBean("springSecurityFilterChain")).isTrue();
assertThat(this.child.getContext().containsBean("springSecurityFilterChain")).isTrue();
}
// SEC-2773
@Test
public void getMethodDelegatingApplicationListenerWhenWebSecurityConfigurationThenIsStatic() {
Method method = ClassUtils.getMethod(WebSecurityConfiguration.class, "delegatingApplicationListener", null);
assertThat(Modifier.isStatic(method.getModifiers())).isTrue();
}
@Test
public void loadConfigWhenBeanProxyingEnabledAndSubclassThenFilterChainsCreated() {
this.spring.register(GlobalAuthenticationWebSecurityConfigurerAdaptersConfig.class, SubclassConfig.class)
.autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
assertThat(filterChains).hasSize(4);
}
@Test
public void loadConfigWhenBothAdapterAndFilterChainConfiguredThenException() {
Throwable thrown = catchThrowable(() -> this.spring.register(AdapterAndFilterChainConfig.class).autowire());
assertThat(thrown).isInstanceOf(BeanCreationException.class)
.hasRootCauseExactlyInstanceOf(IllegalStateException.class)
.hasMessageContaining("Found WebSecurityConfigurerAdapter as well as SecurityFilterChain.");
}
@EnableWebSecurity
@Import(AuthenticationTestConfiguration.class)
static class SortedWebSecurityConfigurerAdaptersConfig {
@ -186,29 +360,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenSecurityFilterChainsHaveOrderThenFilterChainsOrdered() {
this.spring.register(SortedSecurityFilterChainConfig.class).autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
assertThat(filterChains).hasSize(4);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
request.setServletPath("/role1/**");
assertThat(filterChains.get(0).matches(request)).isTrue();
request.setServletPath("/role2/**");
assertThat(filterChains.get(1).matches(request)).isTrue();
request.setServletPath("/role3/**");
assertThat(filterChains.get(2).matches(request)).isTrue();
request.setServletPath("/**");
assertThat(filterChains.get(3).matches(request)).isTrue();
}
@EnableWebSecurity
@Import(AuthenticationTestConfiguration.class)
static class SortedSecurityFilterChainConfig {
@ -241,16 +392,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenWebSecurityConfigurersHaveSameOrderThenThrowBeanCreationException() {
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());
}
@EnableWebSecurity
@Import(AuthenticationTestConfiguration.class)
static class DuplicateOrderConfig {
@ -287,16 +428,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenWebInvocationPrivilegeEvaluatorSetThenIsRegistered() {
PrivilegeEvaluatorConfigurerAdapterConfig.PRIVILEGE_EVALUATOR = mock(WebInvocationPrivilegeEvaluator.class);
this.spring.register(PrivilegeEvaluatorConfigurerAdapterConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isSameAs(PrivilegeEvaluatorConfigurerAdapterConfig.PRIVILEGE_EVALUATOR);
}
@EnableWebSecurity
static class PrivilegeEvaluatorConfigurerAdapterConfig extends WebSecurityConfigurerAdapter {
@ -309,18 +440,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenSecurityExpressionHandlerSetThenIsRegistered() {
WebSecurityExpressionHandlerConfig.EXPRESSION_HANDLER = mock(SecurityExpressionHandler.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);
}
@EnableWebSecurity
static class WebSecurityExpressionHandlerConfig extends WebSecurityConfigurerAdapter {
@ -343,15 +462,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenSecurityExpressionHandlerIsNullThenException() {
Throwable thrown = catchThrowable(
() -> this.spring.register(NullWebSecurityExpressionHandlerConfig.class).autowire());
assertThat(thrown).isInstanceOf(BeanCreationException.class);
assertThat(thrown).hasRootCauseExactlyInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullWebSecurityExpressionHandlerConfig extends WebSecurityConfigurerAdapter {
@ -362,14 +472,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenDefaultSecurityExpressionHandlerThenDefaultIsRegistered() {
this.spring.register(WebSecurityExpressionHandlerDefaultsConfig.class).autowire();
assertThat(this.spring.getContext().getBean(SecurityExpressionHandler.class))
.isInstanceOf(DefaultWebSecurityExpressionHandler.class);
}
@EnableWebSecurity
static class WebSecurityExpressionHandlerDefaultsConfig extends WebSecurityConfigurerAdapter {
@ -384,21 +486,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void securityExpressionHandlerWhenRoleHierarchyBeanThenRoleHierarchyUsed() {
this.spring.register(WebSecurityExpressionHandlerRoleHierarchyBeanConfig.class).autowire();
TestingAuthenticationToken authentication = new TestingAuthenticationToken("user", "notused", "ROLE_ADMIN");
FilterInvocation invocation = new FilterInvocation(new MockHttpServletRequest("GET", ""),
new MockHttpServletResponse(), new MockFilterChain());
AbstractSecurityExpressionHandler handler = this.spring.getContext()
.getBean(AbstractSecurityExpressionHandler.class);
EvaluationContext evaluationContext = handler.createEvaluationContext(authentication, invocation);
Expression expression = handler.getExpressionParser().parseExpression("hasRole('ROLE_USER')");
boolean granted = expression.getValue(evaluationContext, Boolean.class);
assertThat(granted).isTrue();
}
@EnableWebSecurity
static class WebSecurityExpressionHandlerRoleHierarchyBeanConfig extends WebSecurityConfigurerAdapter {
@ -411,21 +498,6 @@ public class WebSecurityConfigurationTests {
}
@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());
AbstractSecurityExpressionHandler handler = this.spring.getContext()
.getBean(AbstractSecurityExpressionHandler.class);
EvaluationContext evaluationContext = handler.createEvaluationContext(authentication, invocation);
Expression expression = handler.getExpressionParser().parseExpression("hasPermission(#study,'DELETE')");
boolean granted = expression.getValue(evaluationContext, Boolean.class);
assertThat(granted).isTrue();
}
@EnableWebSecurity
static class WebSecurityExpressionHandlerPermissionEvaluatorBeanConfig extends WebSecurityConfigurerAdapter {
@ -449,14 +521,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenDefaultWebInvocationPrivilegeEvaluatorThenDefaultIsRegistered() {
this.spring.register(WebInvocationPrivilegeEvaluatorDefaultsConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
}
@EnableWebSecurity
static class WebInvocationPrivilegeEvaluatorDefaultsConfig extends WebSecurityConfigurerAdapter {
@ -471,14 +535,6 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenSecurityFilterChainBeanThenDefaultWebInvocationPrivilegeEvaluatorIsRegistered() {
this.spring.register(AuthorizeRequestsFilterChainConfig.class).autowire();
assertThat(this.spring.getContext().getBean(WebInvocationPrivilegeEvaluator.class))
.isInstanceOf(DefaultWebInvocationPrivilegeEvaluator.class);
}
@EnableWebSecurity
static class AuthorizeRequestsFilterChainConfig {
@ -489,15 +545,6 @@ public class WebSecurityConfigurationTests {
}
// SEC-2303
@Test
public void loadConfigWhenDefaultSecurityExpressionHandlerThenBeanResolverSet() throws Exception {
this.spring.register(DefaultExpressionHandlerSetsBeanResolverConfig.class).autowire();
this.mockMvc.perform(get("/")).andExpect(status().isOk());
this.mockMvc.perform(post("/")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class DefaultExpressionHandlerSetsBeanResolverConfig extends WebSecurityConfigurerAdapter {
@ -510,6 +557,11 @@ public class WebSecurityConfigurationTests {
// @formatter:on
}
@Bean
public MyBean b() {
return new MyBean();
}
@RestController
public class HomeController {
@ -520,11 +572,6 @@ public class WebSecurityConfigurationTests {
}
@Bean
public MyBean b() {
return new MyBean();
}
static class MyBean {
public boolean deny() {
@ -539,25 +586,6 @@ public class WebSecurityConfigurationTests {
}
@Rule
public SpringTestRule child = new SpringTestRule();
// SEC-2461
@Test
public void loadConfigWhenMultipleWebSecurityConfigurationThenContextLoads() {
this.spring.register(ParentConfig.class).autowire();
this.child.register(ChildConfig.class);
this.child.getContext().setParent(this.spring.getContext());
this.child.autowire();
assertThat(this.spring.getContext().getBean("springSecurityFilterChain")).isNotNull();
assertThat(this.child.getContext().getBean("springSecurityFilterChain")).isNotNull();
assertThat(this.spring.getContext().containsBean("springSecurityFilterChain")).isTrue();
assertThat(this.child.getContext().containsBean("springSecurityFilterChain")).isTrue();
}
@EnableWebSecurity
static class ParentConfig extends WebSecurityConfigurerAdapter {
@ -573,24 +601,6 @@ public class WebSecurityConfigurationTests {
}
// SEC-2773
@Test
public void getMethodDelegatingApplicationListenerWhenWebSecurityConfigurationThenIsStatic() {
Method method = ClassUtils.getMethod(WebSecurityConfiguration.class, "delegatingApplicationListener", null);
assertThat(Modifier.isStatic(method.getModifiers())).isTrue();
}
@Test
public void loadConfigWhenBeanProxyingEnabledAndSubclassThenFilterChainsCreated() {
this.spring.register(GlobalAuthenticationWebSecurityConfigurerAdaptersConfig.class, SubclassConfig.class)
.autowire();
FilterChainProxy filterChainProxy = this.spring.getContext().getBean(FilterChainProxy.class);
List<SecurityFilterChain> filterChains = filterChainProxy.getFilterChains();
assertThat(filterChains).hasSize(4);
}
@Configuration
static class SubclassConfig extends WebSecurityConfiguration {
@ -637,20 +647,17 @@ public class WebSecurityConfigurationTests {
}
@Test
public void loadConfigWhenBothAdapterAndFilterChainConfiguredThenException() {
Throwable thrown = catchThrowable(() -> this.spring.register(AdapterAndFilterChainConfig.class).autowire());
assertThat(thrown).isInstanceOf(BeanCreationException.class)
.hasRootCauseExactlyInstanceOf(IllegalStateException.class)
.hasMessageContaining("Found WebSecurityConfigurerAdapter as well as SecurityFilterChain.");
}
@EnableWebSecurity
@Import(AuthenticationTestConfiguration.class)
static class AdapterAndFilterChainConfig {
@Order(2)
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.antMatcher("/filter/**").authorizeRequests(authorize -> authorize.anyRequest().authenticated())
.build();
}
@Order(1)
@Configuration
static class WebConfigurer extends WebSecurityConfigurerAdapter {
@ -662,13 +669,6 @@ public class WebSecurityConfigurationTests {
}
@Order(2)
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.antMatcher("/filter/**").authorizeRequests(authorize -> authorize.anyRequest().authenticated())
.build();
}
}
}

View File

@ -55,6 +55,27 @@ public class AnonymousConfigurerTests {
this.mockMvc.perform(get("/")).andExpect(content().string("principal"));
}
@Test
public void requestWhenAnonymousPrincipalInLambdaThenPrincipalUsed() throws Exception {
this.spring.register(AnonymousPrincipalInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/")).andExpect(content().string("principal"));
}
@Test
public void requestWhenAnonymousDisabledInLambdaThenRespondsWithForbidden() throws Exception {
this.spring.register(AnonymousDisabledInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/")).andExpect(status().isForbidden());
}
@Test
public void requestWhenAnonymousWithDefaultsInLambdaThenRespondsWithOk() throws Exception {
this.spring.register(AnonymousWithDefaultsInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/")).andExpect(status().isOk());
}
@EnableWebSecurity
@EnableWebMvc
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
@ -73,13 +94,6 @@ public class AnonymousConfigurerTests {
}
@Test
public void requestWhenAnonymousPrincipalInLambdaThenPrincipalUsed() throws Exception {
this.spring.register(AnonymousPrincipalInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/")).andExpect(content().string("principal"));
}
@EnableWebSecurity
@EnableWebMvc
static class AnonymousPrincipalInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -97,13 +111,6 @@ public class AnonymousConfigurerTests {
}
@Test
public void requestWhenAnonymousDisabledInLambdaThenRespondsWithForbidden() throws Exception {
this.spring.register(AnonymousDisabledInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class AnonymousDisabledInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -130,13 +137,6 @@ public class AnonymousConfigurerTests {
}
@Test
public void requestWhenAnonymousWithDefaultsInLambdaThenRespondsWithOk() throws Exception {
this.spring.register(AnonymousWithDefaultsInLambdaConfig.class, PrincipalController.class).autowire();
this.mockMvc.perform(get("/")).andExpect(status().isOk());
}
@EnableWebSecurity
static class AnonymousWithDefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {

View File

@ -99,29 +99,6 @@ public class AuthorizeRequestsTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
}
@EnableWebSecurity
@Configuration
static class AntMatchersNoPatternsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers(HttpMethod.POST).denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
@Test
public void postWhenPostDenyAllInLambdaThenRespondsWithForbidden() throws Exception {
loadConfig(AntMatchersNoPatternsInLambdaConfig.class);
@ -132,31 +109,6 @@ public class AuthorizeRequestsTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
}
@EnableWebSecurity
@Configuration
static class AntMatchersNoPatternsInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers(HttpMethod.POST).denyAll()
);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
// SEC-2256
@Test
public void antMatchersPathVariables() throws Exception {
@ -195,30 +147,6 @@ public class AuthorizeRequestsTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
}
@EnableWebSecurity
@Configuration
static class AntPatchersPathVariables extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.requestMatchers(new AntPathRequestMatcher("/user/{user}", null, false)).access("#user == 'user'")
.anyRequest().denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
// gh-3786
@Test
public void antMatchersPathVariablesCaseInsensitiveCamelCaseVariables() throws Exception {
@ -238,30 +166,6 @@ public class AuthorizeRequestsTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
}
@EnableWebSecurity
@Configuration
static class AntMatchersPathVariablesCamelCaseVariables extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.requestMatchers(new AntPathRequestMatcher("/user/{userName}", null, false)).access("#userName == 'user'")
.anyRequest().denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
// gh-3394
@Test
public void roleHiearchy() throws Exception {
@ -278,36 +182,6 @@ public class AuthorizeRequestsTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
@EnableWebSecurity
@Configuration
static class RoleHiearchyConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("ADMIN");
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@Bean
public RoleHierarchy roleHiearchy() {
RoleHierarchyImpl result = new RoleHierarchyImpl();
result.setHierarchy("ROLE_USER > ROLE_ADMIN");
return result;
}
}
@Test
public void mvcMatcher() throws Exception {
loadConfig(MvcMatcherConfig.class, LegacyMvcMatchingConfig.class);
@ -332,41 +206,6 @@ public class AuthorizeRequestsTests {
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
http
.httpBasic().and()
.authorizeRequests()
.mvcMatchers("/path").denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
public void requestWhenMvcMatcherDenyAllThenRespondsWithUnauthorized() throws Exception {
loadConfig(MvcMatcherInLambdaConfig.class, LegacyMvcMatchingConfig.class);
@ -391,121 +230,6 @@ public class AuthorizeRequestsTests {
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
http
.httpBasic(withDefaults())
.authorizeRequests(authorizeRequests ->
authorizeRequests
.mvcMatchers("/path").denyAll()
);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
public void mvcMatcherServletPath() throws Exception {
loadConfig(MvcMatcherServletPathConfig.class, LegacyMvcMatchingConfig.class);
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/foo");
this.request.setRequestURI("/foo/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/");
this.request.setRequestURI("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherServletPathConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic().and()
.authorizeRequests()
.mvcMatchers("/path").servletPath("/spring").denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
public void requestWhenMvcMatcherServletPathDenyAllThenMatchesOnServletPath() throws Exception {
loadConfig(MvcMatcherServletPathInLambdaConfig.class, LegacyMvcMatchingConfig.class);
@ -549,6 +273,327 @@ public class AuthorizeRequestsTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
@Test
public void mvcMatcherPathVariables() throws Exception {
loadConfig(MvcMatcherPathVariablesConfig.class);
this.request.setRequestURI("/user/user");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
this.setup();
this.request.setRequestURI("/user/deny");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@Test
public void requestWhenMvcMatcherPathVariablesThenMatchesOnPathVariables() throws Exception {
loadConfig(MvcMatcherPathVariablesInLambdaConfig.class);
this.request.setRequestURI("/user/user");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
this.setup();
this.request.setRequestURI("/user/deny");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@Test
public void mvcMatcherServletPath() throws Exception {
loadConfig(MvcMatcherServletPathConfig.class, LegacyMvcMatchingConfig.class);
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path.html");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("/foo");
this.request.setRequestURI("/foo/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/");
this.request.setRequestURI("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.setServletContext(this.servletContext);
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
@EnableWebSecurity
@Configuration
static class AntMatchersNoPatternsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers(HttpMethod.POST).denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
@EnableWebSecurity
@Configuration
static class AntMatchersNoPatternsInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.antMatchers(HttpMethod.POST).denyAll()
);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
@EnableWebSecurity
@Configuration
static class AntPatchersPathVariables extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.requestMatchers(new AntPathRequestMatcher("/user/{user}", null, false)).access("#user == 'user'")
.anyRequest().denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
@EnableWebSecurity
@Configuration
static class AntMatchersPathVariablesCamelCaseVariables extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.requestMatchers(new AntPathRequestMatcher("/user/{userName}", null, false)).access("#userName == 'user'")
.anyRequest().denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
@EnableWebSecurity
@Configuration
static class RoleHiearchyConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("ADMIN");
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@Bean
public RoleHierarchy roleHiearchy() {
RoleHierarchyImpl result = new RoleHierarchyImpl();
result.setHierarchy("ROLE_USER > ROLE_ADMIN");
return result;
}
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic().and()
.authorizeRequests()
.mvcMatchers("/path").denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic(withDefaults())
.authorizeRequests(authorizeRequests ->
authorizeRequests
.mvcMatchers("/path").denyAll()
);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherServletPathConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic().and()
.authorizeRequests()
.mvcMatchers("/path").servletPath("/spring").denyAll();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -586,24 +631,6 @@ public class AuthorizeRequestsTests {
}
@Test
public void mvcMatcherPathVariables() throws Exception {
loadConfig(MvcMatcherPathVariablesConfig.class);
this.request.setRequestURI("/user/user");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
this.setup();
this.request.setRequestURI("/user/deny");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -639,24 +666,6 @@ public class AuthorizeRequestsTests {
}
@Test
public void requestWhenMvcMatcherPathVariablesThenMatchesOnPathVariables() throws Exception {
loadConfig(MvcMatcherPathVariablesInLambdaConfig.class);
this.request.setRequestURI("/user/user");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
this.setup();
this.request.setRequestURI("/user/deny");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -739,13 +748,4 @@ public class AuthorizeRequestsTests {
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.setServletContext(this.servletContext);
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@ -84,6 +84,20 @@ public class ChannelSecurityConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ChannelProcessingFilter.class));
}
@Test
public void requiresChannelWhenInvokesTwiceThenUsesOriginalRequiresSecure() throws Exception {
this.spring.register(DuplicateInvocationsDoesNotOverrideConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("https://localhost/"));
}
@Test
public void requestWhenRequiresChannelConfiguredInLambdaThenRedirectsToHttps() throws Exception {
this.spring.register(RequiresChannelInLambdaConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("https://localhost/"));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
@ -114,13 +128,6 @@ public class ChannelSecurityConfigurerTests {
}
@Test
public void requiresChannelWhenInvokesTwiceThenUsesOriginalRequiresSecure() throws Exception {
this.spring.register(DuplicateInvocationsDoesNotOverrideConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("https://localhost/"));
}
@EnableWebSecurity
static class DuplicateInvocationsDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@ -137,13 +144,6 @@ public class ChannelSecurityConfigurerTests {
}
@Test
public void requestWhenRequiresChannelConfiguredInLambdaThenRedirectsToHttps() throws Exception {
this.spring.register(RequiresChannelInLambdaConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("https://localhost/"));
}
@EnableWebSecurity
static class RequiresChannelInLambdaConfig extends WebSecurityConfigurerAdapter {

View File

@ -70,22 +70,6 @@ public class CorsConfigurerTests {
"Please ensure Spring Security & Spring MVC are configured in a shared ApplicationContext");
}
@EnableWebSecurity
static class DefaultCorsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors();
// @formatter:on
}
}
@Test
public void getWhenCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsConfig.class).autowire();
@ -106,6 +90,124 @@ public class CorsConfigurerTests {
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void getWhenDefaultsInLambdaAndCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsInLambdaConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenDefaultsInLambdaAndCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsInLambdaConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void getWhenCorsConfigurationSourceBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(ConfigSourceConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenCorsConfigurationSourceBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(ConfigSourceConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void getWhenMvcCorsInLambdaConfigAndCorsConfigurationSourceBeanThenRespondsWithCorsHeaders()
throws Exception {
this.spring.register(ConfigSourceInLambdaConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenMvcCorsInLambdaConfigAndCorsConfigurationSourceBeanThenRespondsWithCorsHeaders()
throws Exception {
this.spring.register(ConfigSourceInLambdaConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void getWhenCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void getWhenConfigSourceInLambdaConfigAndCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterInLambdaConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenConfigSourceInLambdaConfigAndCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterInLambdaConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebSecurity
static class DefaultCorsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.cors();
// @formatter:on
}
}
@EnableWebMvc
@EnableWebSecurity
static class MvcCorsConfig extends WebSecurityConfigurerAdapter {
@ -134,26 +236,6 @@ public class CorsConfigurerTests {
}
@Test
public void getWhenDefaultsInLambdaAndCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsInLambdaConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenDefaultsInLambdaAndCrossOriginAnnotationThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(MvcCorsInLambdaConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebMvc
@EnableWebSecurity
static class MvcCorsInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -183,26 +265,6 @@ public class CorsConfigurerTests {
}
@Test
public void getWhenCorsConfigurationSourceBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(ConfigSourceConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenCorsConfigurationSourceBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(ConfigSourceConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebSecurity
static class ConfigSourceConfig extends WebSecurityConfigurerAdapter {
@ -229,28 +291,6 @@ public class CorsConfigurerTests {
}
@Test
public void getWhenMvcCorsInLambdaConfigAndCorsConfigurationSourceBeanThenRespondsWithCorsHeaders()
throws Exception {
this.spring.register(ConfigSourceInLambdaConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenMvcCorsInLambdaConfigAndCorsConfigurationSourceBeanThenRespondsWithCorsHeaders()
throws Exception {
this.spring.register(ConfigSourceInLambdaConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebSecurity
static class ConfigSourceInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -278,26 +318,6 @@ public class CorsConfigurerTests {
}
@Test
public void getWhenCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebSecurity
static class CorsFilterConfig extends WebSecurityConfigurerAdapter {
@ -324,26 +344,6 @@ public class CorsConfigurerTests {
}
@Test
public void getWhenConfigSourceInLambdaConfigAndCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterInLambdaConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ORIGIN, "https://example.com"))
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@Test
public void optionsWhenConfigSourceInLambdaConfigAndCorsFilterBeanThenRespondsWithCorsHeaders() throws Exception {
this.spring.register(CorsFilterInLambdaConfig.class).autowire();
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())
.andExpect(header().exists("Access-Control-Allow-Origin"))
.andExpect(header().exists("X-Content-Type-Options"));
}
@EnableWebSecurity
static class CorsFilterInLambdaConfig extends WebSecurityConfigurerAdapter {

View File

@ -56,6 +56,40 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
this.mvc.perform(post("/path")).andExpect(status().isOk());
}
@Test
public void requestWhenIgnoringRequestMatchersInLambdaThenAugmentedByConfiguredRequestMatcher() throws Exception {
this.spring.register(IgnoringRequestInLambdaMatchers.class, BasicController.class).autowire();
this.mvc.perform(get("/path")).andExpect(status().isForbidden());
this.mvc.perform(post("/path")).andExpect(status().isOk());
}
@Test
public void requestWhenIgnoringRequestMatcherThenUnionsWithConfiguredIgnoringAntMatchers() throws Exception {
this.spring.register(IgnoringPathsAndMatchers.class, BasicController.class).autowire();
this.mvc.perform(put("/csrf")).andExpect(status().isForbidden());
this.mvc.perform(post("/csrf")).andExpect(status().isOk());
this.mvc.perform(put("/no-csrf")).andExpect(status().isOk());
}
@Test
public void requestWhenIgnoringRequestMatcherInLambdaThenUnionsWithConfiguredIgnoringAntMatchers()
throws Exception {
this.spring.register(IgnoringPathsAndMatchersInLambdaConfig.class, BasicController.class).autowire();
this.mvc.perform(put("/csrf")).andExpect(status().isForbidden());
this.mvc.perform(post("/csrf")).andExpect(status().isOk());
this.mvc.perform(put("/no-csrf")).andExpect(status().isOk());
}
@EnableWebSecurity
static class IgnoringRequestMatchers extends WebSecurityConfigurerAdapter {
@ -73,15 +107,6 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
}
@Test
public void requestWhenIgnoringRequestMatchersInLambdaThenAugmentedByConfiguredRequestMatcher() throws Exception {
this.spring.register(IgnoringRequestInLambdaMatchers.class, BasicController.class).autowire();
this.mvc.perform(get("/path")).andExpect(status().isForbidden());
this.mvc.perform(post("/path")).andExpect(status().isOk());
}
@EnableWebSecurity
static class IgnoringRequestInLambdaMatchers extends WebSecurityConfigurerAdapter {
@ -101,18 +126,6 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
}
@Test
public void requestWhenIgnoringRequestMatcherThenUnionsWithConfiguredIgnoringAntMatchers() throws Exception {
this.spring.register(IgnoringPathsAndMatchers.class, BasicController.class).autowire();
this.mvc.perform(put("/csrf")).andExpect(status().isForbidden());
this.mvc.perform(post("/csrf")).andExpect(status().isOk());
this.mvc.perform(put("/no-csrf")).andExpect(status().isOk());
}
@EnableWebSecurity
static class IgnoringPathsAndMatchers extends WebSecurityConfigurerAdapter {
@ -130,19 +143,6 @@ public class CsrfConfigurerIgnoringRequestMatchersTests {
}
@Test
public void requestWhenIgnoringRequestMatcherInLambdaThenUnionsWithConfiguredIgnoringAntMatchers()
throws Exception {
this.spring.register(IgnoringPathsAndMatchersInLambdaConfig.class, BasicController.class).autowire();
this.mvc.perform(put("/csrf")).andExpect(status().isForbidden());
this.mvc.perform(post("/csrf")).andExpect(status().isOk());
this.mvc.perform(put("/no-csrf")).andExpect(status().isOk());
}
@EnableWebSecurity
static class IgnoringPathsAndMatchersInLambdaConfig extends WebSecurityConfigurerAdapter {

View File

@ -68,6 +68,13 @@ public class CsrfConfigurerNoWebMvcTests {
.isNotEqualTo(CsrfRequestDataValueProcessor.class);
}
private void loadContext(Class<?> configs) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(configs);
annotationConfigApplicationContext.refresh();
this.context = annotationConfigApplicationContext;
}
@EnableWebSecurity
static class EnableWebConfig extends WebSecurityConfigurerAdapter {
@ -97,11 +104,4 @@ public class CsrfConfigurerNoWebMvcTests {
}
private void loadContext(Class<?> configs) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.register(configs);
annotationConfigApplicationContext.refresh();
this.context = annotationConfigApplicationContext;
}
}

View File

@ -179,27 +179,6 @@ public class CsrfConfigurerTests {
assertThat(this.spring.getContext().getBean(RequestDataValueProcessor.class)).isNotNull();
}
@Configuration
static class AllowHttpMethodsFirewallConfig {
@Bean
StrictHttpFirewall strictHttpFirewall() {
StrictHttpFirewall result = new StrictHttpFirewall();
result.setUnsafeAllowAnyHttpMethod(true);
return result;
}
}
@EnableWebSecurity
static class CsrfAppliedDefaultConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
}
}
@Test
public void postWhenCsrfDisabledThenRespondsWithOk() throws Exception {
this.spring.register(DisableCsrfConfig.class, BasicController.class).autowire();
@ -207,20 +186,6 @@ public class CsrfConfigurerTests {
this.mvc.perform(post("/")).andExpect(status().isOk());
}
@EnableWebSecurity
static class DisableCsrfConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable();
// @formatter:on
}
}
@Test
public void postWhenCsrfDisabledInLambdaThenRespondsWithOk() throws Exception {
this.spring.register(DisableCsrfInLambdaConfig.class, BasicController.class).autowire();
@ -228,19 +193,6 @@ public class CsrfConfigurerTests {
this.mvc.perform(post("/")).andExpect(status().isOk());
}
@EnableWebSecurity
static class DisableCsrfInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf(AbstractHttpConfigurer::disable);
// @formatter:on
}
}
// SEC-2498
@Test
public void loginWhenCsrfDisabledThenRedirectsToPreviousPostRequest() throws Exception {
@ -253,34 +205,6 @@ public class CsrfConfigurerTests {
.andExpect(redirectedUrl("http://localhost/to-save"));
}
@EnableWebSecurity
static class DisableCsrfEnablesRequestCacheConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.csrf()
.disable();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void loginWhenCsrfEnabledThenDoesNotRedirectToPreviousPostRequest() throws Exception {
CsrfDisablesPostRequestFromRequestCacheConfig.REPO = mock(CsrfTokenRepository.class);
@ -315,36 +239,6 @@ public class CsrfConfigurerTests {
.loadToken(any(HttpServletRequest.class));
}
@EnableWebSecurity
static class CsrfDisablesPostRequestFromRequestCacheConfig extends WebSecurityConfigurerAdapter {
static CsrfTokenRepository REPO;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.csrf()
.csrfTokenRepository(REPO);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
// SEC-2422
@Test
public void postWhenCsrfEnabledAndSessionIsExpiredThenRespondsWithForbidden() throws Exception {
@ -357,22 +251,6 @@ public class CsrfConfigurerTests {
.andExpect(status().isForbidden());
}
@EnableWebSecurity
static class InvalidSessionUrlConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.and()
.sessionManagement()
.invalidSessionUrl("/error/sessionError");
// @formatter:on
}
}
@Test
public void requireCsrfProtectionMatcherWhenRequestDoesNotMatchThenRespondsWithOk() throws Exception {
this.spring.register(RequireCsrfProtectionMatcherConfig.class, BasicController.class).autowire();
@ -390,22 +268,6 @@ public class CsrfConfigurerTests {
this.mvc.perform(get("/")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RequireCsrfProtectionMatcherConfig extends WebSecurityConfigurerAdapter {
static RequestMatcher MATCHER;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.requireCsrfProtectionMatcher(MATCHER);
// @formatter:on
}
}
@Test
public void requireCsrfProtectionMatcherInLambdaWhenRequestDoesNotMatchThenRespondsWithOk() throws Exception {
RequireCsrfProtectionMatcherInLambdaConfig.MATCHER = mock(RequestMatcher.class);
@ -424,21 +286,6 @@ public class CsrfConfigurerTests {
this.mvc.perform(get("/")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RequireCsrfProtectionMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
static RequestMatcher MATCHER;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf(csrf -> csrf.requireCsrfProtectionMatcher(MATCHER));
// @formatter:on
}
}
@Test
public void getWhenCustomCsrfTokenRepositoryThenRepositoryIsUsed() throws Exception {
CsrfTokenRepositoryConfig.REPO = mock(CsrfTokenRepository.class);
@ -476,6 +323,247 @@ public class CsrfConfigurerTests {
any(HttpServletResponse.class));
}
@Test
public void getWhenCustomCsrfTokenRepositoryInLambdaThenRepositoryIsUsed() throws Exception {
CsrfTokenRepositoryInLambdaConfig.REPO = mock(CsrfTokenRepository.class);
when(CsrfTokenRepositoryInLambdaConfig.REPO.loadToken(any()))
.thenReturn(new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "token"));
this.spring.register(CsrfTokenRepositoryInLambdaConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")).andExpect(status().isOk());
verify(CsrfTokenRepositoryInLambdaConfig.REPO).loadToken(any(HttpServletRequest.class));
}
@Test
public void getWhenCustomAccessDeniedHandlerThenHandlerIsUsed() throws Exception {
AccessDeniedHandlerConfig.DENIED_HANDLER = mock(AccessDeniedHandler.class);
this.spring.register(AccessDeniedHandlerConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/")).andExpect(status().isOk());
verify(AccessDeniedHandlerConfig.DENIED_HANDLER).handle(any(HttpServletRequest.class),
any(HttpServletResponse.class), any());
}
@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());
}
@Test
public void logoutWhenNoCsrfTokenThenRespondsWithForbidden() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mvc.perform(post("/logout").with(user("username"))).andExpect(status().isForbidden())
.andExpect(authenticated());
}
// SEC-2543
@Test
public void logoutWhenCsrfEnabledAndGetRequestThenDoesNotLogout() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mvc.perform(get("/logout").with(user("username"))).andExpect(authenticated());
}
@Test
public void logoutWhenGetRequestAndGetEnabledForLogoutThenLogsOut() throws Exception {
this.spring.register(LogoutAllowsGetConfig.class).autowire();
this.mvc.perform(get("/logout").with(user("username"))).andExpect(unauthenticated());
}
// SEC-2749
@Test
public void configureWhenRequireCsrfProtectionMatcherNullThenException() {
assertThatThrownBy(() -> this.spring.register(NullRequireCsrfProtectionMatcherConfig.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@Test
public void getWhenDefaultCsrfTokenRepositoryThenDoesNotCreateSession() throws Exception {
this.spring.register(DefaultDoesNotCreateSession.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/")).andReturn();
assertThat(mvcResult.getRequest().getSession(false)).isNull();
}
@Test
public void getWhenNullAuthenticationStrategyThenException() {
assertThatThrownBy(() -> this.spring.register(NullAuthenticationStrategy.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@Test
public void csrfAuthenticationStrategyConfiguredThenStrategyUsed() throws Exception {
CsrfAuthenticationStrategyConfig.STRATEGY = mock(SessionAuthenticationStrategy.class);
this.spring.register(CsrfAuthenticationStrategyConfig.class).autowire();
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));
}
@Configuration
static class AllowHttpMethodsFirewallConfig {
@Bean
StrictHttpFirewall strictHttpFirewall() {
StrictHttpFirewall result = new StrictHttpFirewall();
result.setUnsafeAllowAnyHttpMethod(true);
return result;
}
}
@EnableWebSecurity
static class CsrfAppliedDefaultConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
}
}
@EnableWebSecurity
static class DisableCsrfConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable();
// @formatter:on
}
}
@EnableWebSecurity
static class DisableCsrfInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf(AbstractHttpConfigurer::disable);
// @formatter:on
}
}
@EnableWebSecurity
static class DisableCsrfEnablesRequestCacheConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.csrf()
.disable();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class CsrfDisablesPostRequestFromRequestCacheConfig extends WebSecurityConfigurerAdapter {
static CsrfTokenRepository REPO;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.csrf()
.csrfTokenRepository(REPO);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class InvalidSessionUrlConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.and()
.sessionManagement()
.invalidSessionUrl("/error/sessionError");
// @formatter:on
}
}
@EnableWebSecurity
static class RequireCsrfProtectionMatcherConfig extends WebSecurityConfigurerAdapter {
static RequestMatcher MATCHER;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.requireCsrfProtectionMatcher(MATCHER);
// @formatter:on
}
}
@EnableWebSecurity
static class RequireCsrfProtectionMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
static RequestMatcher MATCHER;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf(csrf -> csrf.requireCsrfProtectionMatcher(MATCHER));
// @formatter:on
}
}
@EnableWebSecurity
static class CsrfTokenRepositoryConfig extends WebSecurityConfigurerAdapter {
@ -503,17 +591,6 @@ public class CsrfConfigurerTests {
}
@Test
public void getWhenCustomCsrfTokenRepositoryInLambdaThenRepositoryIsUsed() throws Exception {
CsrfTokenRepositoryInLambdaConfig.REPO = mock(CsrfTokenRepository.class);
when(CsrfTokenRepositoryInLambdaConfig.REPO.loadToken(any()))
.thenReturn(new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "token"));
this.spring.register(CsrfTokenRepositoryInLambdaConfig.class, BasicController.class).autowire();
this.mvc.perform(get("/")).andExpect(status().isOk());
verify(CsrfTokenRepositoryInLambdaConfig.REPO).loadToken(any(HttpServletRequest.class));
}
@EnableWebSecurity
static class CsrfTokenRepositoryInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -530,17 +607,6 @@ public class CsrfConfigurerTests {
}
@Test
public void getWhenCustomAccessDeniedHandlerThenHandlerIsUsed() throws Exception {
AccessDeniedHandlerConfig.DENIED_HANDLER = mock(AccessDeniedHandler.class);
this.spring.register(AccessDeniedHandlerConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/")).andExpect(status().isOk());
verify(AccessDeniedHandlerConfig.DENIED_HANDLER).handle(any(HttpServletRequest.class),
any(HttpServletResponse.class), any());
}
@EnableWebSecurity
static class AccessDeniedHandlerConfig extends WebSecurityConfigurerAdapter {
@ -557,30 +623,6 @@ public class CsrfConfigurerTests {
}
@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());
}
@Test
public void logoutWhenNoCsrfTokenThenRespondsWithForbidden() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mvc.perform(post("/logout").with(user("username"))).andExpect(status().isForbidden())
.andExpect(authenticated());
}
// SEC-2543
@Test
public void logoutWhenCsrfEnabledAndGetRequestThenDoesNotLogout() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
this.mvc.perform(get("/logout").with(user("username"))).andExpect(authenticated());
}
@EnableWebSecurity
static class FormLoginConfig extends WebSecurityConfigurerAdapter {
@ -594,13 +636,6 @@ public class CsrfConfigurerTests {
}
@Test
public void logoutWhenGetRequestAndGetEnabledForLogoutThenLogsOut() throws Exception {
this.spring.register(LogoutAllowsGetConfig.class).autowire();
this.mvc.perform(get("/logout").with(user("username"))).andExpect(unauthenticated());
}
@EnableWebSecurity
static class LogoutAllowsGetConfig extends WebSecurityConfigurerAdapter {
@ -617,13 +652,6 @@ public class CsrfConfigurerTests {
}
// SEC-2749
@Test
public void configureWhenRequireCsrfProtectionMatcherNullThenException() {
assertThatThrownBy(() -> this.spring.register(NullRequireCsrfProtectionMatcherConfig.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullRequireCsrfProtectionMatcherConfig extends WebSecurityConfigurerAdapter {
@ -638,15 +666,6 @@ public class CsrfConfigurerTests {
}
@Test
public void getWhenDefaultCsrfTokenRepositoryThenDoesNotCreateSession() throws Exception {
this.spring.register(DefaultDoesNotCreateSession.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/")).andReturn();
assertThat(mvcResult.getRequest().getSession(false)).isNull();
}
@EnableWebSecurity
static class DefaultDoesNotCreateSession extends WebSecurityConfigurerAdapter {
@ -688,12 +707,6 @@ public class CsrfConfigurerTests {
}
@Test
public void getWhenNullAuthenticationStrategyThenException() {
assertThatThrownBy(() -> this.spring.register(NullAuthenticationStrategy.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class CsrfAuthenticationStrategyConfig extends WebSecurityConfigurerAdapter {
@ -721,19 +734,6 @@ public class CsrfConfigurerTests {
}
@Test
public void csrfAuthenticationStrategyConfiguredThenStrategyUsed() throws Exception {
CsrfAuthenticationStrategyConfig.STRATEGY = mock(SessionAuthenticationStrategy.class);
this.spring.register(CsrfAuthenticationStrategyConfig.class).autowire();
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));
}
@RestController
static class BasicController {

View File

@ -77,20 +77,6 @@ public class DefaultFiltersTests {
assertThat(this.spring.getContext().getBean(FilterChainProxy.class)).isNotNull();
}
@EnableWebSecurity
static class FilterChainProxyBuilderMissingConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
// @formatter:on
}
}
@Test
public void nullWebInvocationPrivilegeEvaluator() {
this.spring.register(NullWebInvocationPrivilegeEvaluatorConfig.class, UserDetailsServiceConfig.class);
@ -105,30 +91,6 @@ public class DefaultFiltersTests {
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);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin();
}
}
@Test
public void filterChainProxyBuilderIgnoringResources() {
this.spring.register(FilterChainProxyBuilderIgnoringConfig.class, UserDetailsServiceConfig.class);
@ -156,6 +118,60 @@ public class DefaultFiltersTests {
assertThat(classes.contains(FilterSecurityInterceptor.class)).isTrue();
}
@Test
public void defaultFiltersPermitAll() throws IOException, ServletException {
this.spring.register(DefaultFiltersConfigPermitAll.class, UserDetailsServiceConfig.class);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest("POST", "");
request.setServletPath("/logout");
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
new HttpSessionCsrfTokenRepository().saveToken(csrfToken, request, response);
request.setParameter(csrfToken.getParameterName(), csrfToken.getToken());
this.spring.getContext().getBean("springSecurityFilterChain", Filter.class).doFilter(request, response,
new MockFilterChain());
assertThat(response.getRedirectedUrl()).isEqualTo("/login?logout");
}
@EnableWebSecurity
static class FilterChainProxyBuilderMissingConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
// @formatter:on
}
}
@Configuration
static class UserDetailsServiceConfig {
@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(PasswordEncodedUser.user(), PasswordEncodedUser.admin());
}
}
@EnableWebSecurity
static class NullWebInvocationPrivilegeEvaluatorConfig extends WebSecurityConfigurerAdapter {
NullWebInvocationPrivilegeEvaluatorConfig() {
super(true);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin();
}
}
@EnableWebSecurity
static class FilterChainProxyBuilderIgnoringConfig extends WebSecurityConfigurerAdapter {
@ -179,22 +195,6 @@ public class DefaultFiltersTests {
}
@Test
public void defaultFiltersPermitAll() throws IOException, ServletException {
this.spring.register(DefaultFiltersConfigPermitAll.class, UserDetailsServiceConfig.class);
MockHttpServletResponse response = new MockHttpServletResponse();
MockHttpServletRequest request = new MockHttpServletRequest("POST", "");
request.setServletPath("/logout");
CsrfToken csrfToken = new DefaultCsrfToken("X-CSRF-TOKEN", "_csrf", "BaseSpringSpec_CSRFTOKEN");
new HttpSessionCsrfTokenRepository().saveToken(csrfToken, request, response);
request.setParameter(csrfToken.getParameterName(), csrfToken.getToken());
this.spring.getContext().getBean("springSecurityFilterChain", Filter.class).doFilter(request, response,
new MockFilterChain());
assertThat(response.getRedirectedUrl()).isEqualTo("/login?logout");
}
@EnableWebSecurity
static class DefaultFiltersConfigPermitAll extends WebSecurityConfigurerAdapter {

View File

@ -176,31 +176,6 @@ public class DefaultLoginPageConfigurerTests {
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@EnableWebSecurity
static class DefaultLoginPageConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void loginPageWhenLoggedOutAndCustomLogoutSuccessHandlerThenDoesNotRenderLoginPage() throws Exception {
this.spring.register(DefaultLoginPageCustomLogoutSuccessHandlerConfig.class).autowire();
@ -208,25 +183,6 @@ public class DefaultLoginPageConfigurerTests {
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
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.logout()
.logoutSuccessHandler(new SimpleUrlLogoutSuccessHandler())
.and()
.formLogin();
// @formatter:on
}
}
@Test
public void loginPageWhenLoggedOutAndCustomLogoutSuccessUrlThenDoesNotRenderLoginPage() throws Exception {
this.spring.register(DefaultLoginPageCustomLogoutSuccessUrlConfig.class).autowire();
@ -234,25 +190,6 @@ public class DefaultLoginPageConfigurerTests {
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
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.and()
.formLogin();
// @formatter:on
}
}
@Test
public void loginPageWhenRememberConfigureThenDefaultLoginPageWithRememberMeCheckbox() throws Exception {
this.spring.register(DefaultLoginPageWithRememberMeConfig.class).autowire();
@ -283,24 +220,6 @@ public class DefaultLoginPageConfigurerTests {
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@EnableWebSecurity
static class DefaultLoginPageWithRememberMeConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.and()
.rememberMe();
// @formatter:on
}
}
@Test
public void loginPageWhenOpenIdLoginConfiguredThenOpedIdLoginPage() throws Exception {
this.spring.register(DefaultLoginPageWithOpenIDConfig.class).autowire();
@ -327,22 +246,6 @@ public class DefaultLoginPageConfigurerTests {
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@EnableWebSecurity
static class DefaultLoginPageWithOpenIDConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.openidLogin();
// @formatter:on
}
}
@Test
public void loginPageWhenOpenIdLoginAndFormLoginAndRememberMeConfiguredThenOpedIdLoginPage() throws Exception {
this.spring.register(DefaultLoginPageWithFormLoginOpenIDRememberMeConfig.class).autowire();
@ -383,55 +286,6 @@ public class DefaultLoginPageConfigurerTests {
+ " </form>\n" + "</div>\n" + "</body></html>"));
}
@EnableWebSecurity
static class DefaultLoginPageWithFormLoginOpenIDRememberMeConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.rememberMe()
.and()
.formLogin()
.and()
.openidLogin();
// @formatter:on
}
}
@Test
public void configureWhenAuthenticationEntryPointThenNoDefaultLoginPageGeneratingFilter() {
this.spring.register(DefaultLoginWithCustomAuthenticationEntryPointConfig.class).autowire();
FilterChainProxy filterChain = this.spring.getContext().getBean(FilterChainProxy.class);
assertThat(filterChain.getFilterChains().get(0).getFilters().stream()
.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
http
.exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
.and()
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin();
// @formatter:on
}
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnDefaultLoginPageGeneratingFilter() {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@ -465,6 +319,152 @@ public class DefaultLoginPageConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ExceptionTranslationFilter.class));
}
@Test
public void configureWhenAuthenticationEntryPointThenNoDefaultLoginPageGeneratingFilter() {
this.spring.register(DefaultLoginWithCustomAuthenticationEntryPointConfig.class).autowire();
FilterChainProxy filterChain = this.spring.getContext().getBean(FilterChainProxy.class);
assertThat(filterChain.getFilterChains().get(0).getFilters().stream()
.filter(filter -> filter.getClass().isAssignableFrom(DefaultLoginPageGeneratingFilter.class)).count())
.isZero();
}
@EnableWebSecurity
static class DefaultLoginPageConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class DefaultLoginPageCustomLogoutSuccessHandlerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.logout()
.logoutSuccessHandler(new SimpleUrlLogoutSuccessHandler())
.and()
.formLogin();
// @formatter:on
}
}
@EnableWebSecurity
static class DefaultLoginPageCustomLogoutSuccessUrlConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.and()
.formLogin();
// @formatter:on
}
}
@EnableWebSecurity
static class DefaultLoginPageWithRememberMeConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.and()
.rememberMe();
// @formatter:on
}
}
@EnableWebSecurity
static class DefaultLoginPageWithOpenIDConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.openidLogin();
// @formatter:on
}
}
@EnableWebSecurity
static class DefaultLoginPageWithFormLoginOpenIDRememberMeConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.rememberMe()
.and()
.formLogin()
.and()
.openidLogin();
// @formatter:on
}
}
@EnableWebSecurity
static class DefaultLoginWithCustomAuthenticationEntryPointConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.exceptionHandling()
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"))
.and()
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin();
// @formatter:on
}
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {

View File

@ -60,6 +60,26 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
this.mvc.perform(get("/goodbye")).andExpect(status().isForbidden());
}
@Test
@WithMockUser(roles = "ANYTHING")
public void getWhenAccessDeniedOverriddenInLambdaThenCustomizesResponseByRequest() throws Exception {
this.spring.register(RequestMatcherBasedAccessDeniedHandlerInLambdaConfig.class).autowire();
this.mvc.perform(get("/hello")).andExpect(status().isIAmATeapot());
this.mvc.perform(get("/goodbye")).andExpect(status().isForbidden());
}
@Test
@WithMockUser(roles = "ANYTHING")
public void getWhenAccessDeniedOverriddenByOnlyOneHandlerThenAllRequestsUseThatHandler() throws Exception {
this.spring.register(SingleRequestMatcherAccessDeniedHandlerConfig.class).autowire();
this.mvc.perform(get("/hello")).andExpect(status().isIAmATeapot());
this.mvc.perform(get("/goodbye")).andExpect(status().isIAmATeapot());
}
@EnableWebSecurity
static class RequestMatcherBasedAccessDeniedHandlerConfig extends WebSecurityConfigurerAdapter {
@ -85,16 +105,6 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
}
@Test
@WithMockUser(roles = "ANYTHING")
public void getWhenAccessDeniedOverriddenInLambdaThenCustomizesResponseByRequest() throws Exception {
this.spring.register(RequestMatcherBasedAccessDeniedHandlerInLambdaConfig.class).autowire();
this.mvc.perform(get("/hello")).andExpect(status().isIAmATeapot());
this.mvc.perform(get("/goodbye")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RequestMatcherBasedAccessDeniedHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -125,16 +135,6 @@ public class ExceptionHandlingConfigurerAccessDeniedHandlerTests {
}
@Test
@WithMockUser(roles = "ANYTHING")
public void getWhenAccessDeniedOverriddenByOnlyOneHandlerThenAllRequestsUseThatHandler() throws Exception {
this.spring.register(SingleRequestMatcherAccessDeniedHandlerConfig.class).autowire();
this.mvc.perform(get("/hello")).andExpect(status().isIAmATeapot());
this.mvc.perform(get("/goodbye")).andExpect(status().isIAmATeapot());
}
@EnableWebSecurity
static class SingleRequestMatcherAccessDeniedHandlerConfig extends WebSecurityConfigurerAdapter {

View File

@ -70,35 +70,6 @@ public class ExceptionHandlingConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ExceptionTranslationFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.exceptionHandling();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
// SEC-2199
@Test
public void getWhenAcceptHeaderIsApplicationXhtmlXmlThenRespondsWith302() throws Exception {
@ -226,6 +197,71 @@ public class ExceptionHandlingConfigurerTests {
.andExpect(status().isUnauthorized());
}
@Test
public void getWhenCustomContentNegotiationStrategyThenStrategyIsUsed() throws Exception {
this.spring.register(OverrideContentNegotiationStrategySharedObjectConfig.class, DefaultSecurityConfig.class)
.autowire();
this.mvc.perform(get("/"));
verify(OverrideContentNegotiationStrategySharedObjectConfig.CNS, atLeastOnce())
.resolveMediaTypes(any(NativeWebRequest.class));
}
@Test
public void getWhenUsingDefaultsAndUnauthenticatedThenRedirectsToLogin() throws Exception {
this.spring.register(DefaultHttpConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, "bogus/type"))
.andExpect(redirectedUrl("http://localhost/login"));
}
@Test
public void getWhenDeclaringHttpBasicBeforeFormLoginThenRespondsWith401() throws Exception {
this.spring.register(BasicAuthenticationEntryPointBeforeFormLoginConfig.class).autowire();
this.mvc.perform(get("/").header(HttpHeaders.ACCEPT, "bogus/type")).andExpect(status().isUnauthorized());
}
@Test
public void getWhenInvokingExceptionHandlingTwiceThenOriginalEntryPointUsed() throws Exception {
this.spring.register(InvokeTwiceDoesNotOverrideConfig.class).autowire();
this.mvc.perform(get("/"));
verify(InvokeTwiceDoesNotOverrideConfig.AEP).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.exceptionHandling();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@EnableWebSecurity
static class DefaultSecurityConfig {
@ -267,17 +303,6 @@ public class ExceptionHandlingConfigurerTests {
}
@Test
public void getWhenCustomContentNegotiationStrategyThenStrategyIsUsed() throws Exception {
this.spring.register(OverrideContentNegotiationStrategySharedObjectConfig.class, DefaultSecurityConfig.class)
.autowire();
this.mvc.perform(get("/"));
verify(OverrideContentNegotiationStrategySharedObjectConfig.CNS, atLeastOnce())
.resolveMediaTypes(any(NativeWebRequest.class));
}
@EnableWebSecurity
static class OverrideContentNegotiationStrategySharedObjectConfig extends WebSecurityConfigurerAdapter {
@ -290,26 +315,11 @@ public class ExceptionHandlingConfigurerTests {
}
@Test
public void getWhenUsingDefaultsAndUnauthenticatedThenRedirectsToLogin() throws Exception {
this.spring.register(DefaultHttpConfig.class).autowire();
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());
}
@EnableWebSecurity
static class BasicAuthenticationEntryPointBeforeFormLoginConfig extends WebSecurityConfigurerAdapter {
@ -328,16 +338,6 @@ public class ExceptionHandlingConfigurerTests {
}
@Test
public void getWhenInvokingExceptionHandlingTwiceThenOriginalEntryPointUsed() throws Exception {
this.spring.register(InvokeTwiceDoesNotOverrideConfig.class).autowire();
this.mvc.perform(get("/"));
verify(InvokeTwiceDoesNotOverrideConfig.AEP).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {

View File

@ -90,20 +90,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
"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
http
.authorizeRequests()
.anyRequest().hasRole("ROLE_USER");
// @formatter:on
}
}
@Test
public void configureWhenNoCustomAccessDecisionManagerThenUsesAffirmativeBased() {
this.spring.register(NoSpecificAccessDecisionManagerConfig.class).autowire();
@ -111,27 +97,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
verify(NoSpecificAccessDecisionManagerConfig.objectPostProcessor).postProcess(any(AffirmativeBased.class));
}
@EnableWebSecurity
static class NoSpecificAccessDecisionManagerConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER");
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
@Test
public void configureWhenAuthorizedRequestsAndNoRequestsThenException() {
assertThatThrownBy(() -> this.spring.register(NoRequestsConfig.class).autowire())
@ -139,40 +104,12 @@ public class ExpressionUrlAuthorizationConfigurerTests {
"At least one mapping is required (i.e. authorizeRequests().anyRequest().authenticated())");
}
@EnableWebSecurity
static class NoRequestsConfig extends WebSecurityConfigurerAdapter {
@Override
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 ");
}
@EnableWebSecurity
static class IncompleteMappingConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/a").authenticated()
.anyRequest();
// @formatter:on
}
}
@Test
public void getWhenHasAnyAuthorityRoleUserConfiguredAndAuthorityIsRoleUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserAnyAuthorityConfig.class, BasicController.class).autowire();
@ -197,22 +134,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class RoleUserAnyAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().hasAnyAuthority("ROLE_USER");
// @formatter:on
}
}
@Test
public void getWhenHasAuthorityRoleUserConfiguredAndAuthorityIsRoleUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserAuthorityConfig.class, BasicController.class).autowire();
@ -237,22 +158,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class RoleUserAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().hasAuthority("ROLE_USER");
// @formatter:on
}
}
@Test
public void getWhenAuthorityRoleUserOrAdminRequiredAndAuthorityIsRoleUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserOrRoleAdminAuthorityConfig.class, BasicController.class).autowire();
@ -285,22 +190,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
this.mvc.perform(get("/")).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class RoleUserOrRoleAdminAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().hasAnyAuthority("ROLE_USER", "ROLE_ADMIN");
// @formatter:on
}
}
@Test
public void getWhenHasAnyRoleUserConfiguredAndRoleIsUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserConfig.class, BasicController.class).autowire();
@ -315,20 +204,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
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
http
.authorizeRequests()
.anyRequest().hasAnyRole("USER");
// @formatter:on
}
}
@Test
public void getWhenRoleUserOrAdminConfiguredAndRoleIsUserThenRespondsWithOk() throws Exception {
this.spring.register(RoleUserOrAdminConfig.class, BasicController.class).autowire();
@ -350,20 +225,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
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
http
.authorizeRequests()
.anyRequest().hasAnyRole("USER", "ADMIN");
// @formatter:on
}
}
@Test
public void getWhenHasIpAddressConfiguredAndIpAddressMatchesThenRespondsWithOk() throws Exception {
this.spring.register(HasIpAddressConfig.class, BasicController.class).autowire();
@ -384,22 +245,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
})).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class HasIpAddressConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().hasIpAddress("192.168.1.0");
// @formatter:on
}
}
@Test
public void getWhenAnonymousConfiguredAndAnonymousUserThenRespondsWithOk() throws Exception {
this.spring.register(AnonymousConfig.class, BasicController.class).autowire();
@ -414,22 +259,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
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
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().anonymous();
// @formatter:on
}
}
@Test
public void getWhenRememberMeConfiguredAndNoUserThenRespondsWithUnauthorized() throws Exception {
this.spring.register(RememberMeConfig.class, BasicController.class).autowire();
@ -446,6 +275,377 @@ public class ExpressionUrlAuthorizationConfigurerTests {
.andExpect(status().isOk());
}
@Test
public void getWhenDenyAllConfiguredAndNoUserThenRespondsWithUnauthorized() throws Exception {
this.spring.register(DenyAllConfig.class, BasicController.class).autowire();
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());
}
@Test
public void getWhenNotDenyAllConfiguredAndNoUserThenRespondsWithOk() throws Exception {
this.spring.register(NotDenyAllConfig.class, BasicController.class).autowire();
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")))))
.andExpect(status().isOk());
}
@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")))))
.andExpect(status().isUnauthorized());
}
@Test
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());
}
@Test
public void getWhenAccessRoleUserOrGetRequestConfiguredThenRespondsWithOk() throws Exception {
this.spring.register(AccessConfig.class, BasicController.class).autowire();
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());
}
@Test
public void postWhenAccessRoleUserOrGetRequestConfiguredThenRespondsWithUnauthorized() throws Exception {
this.spring.register(AccessConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/").with(csrf())).andExpect(status().isUnauthorized());
}
@Test
public void authorizeRequestsWhenInvokedTwiceThenUsesOriginalConfiguration() throws Exception {
this.spring.register(InvokeTwiceDoesNotResetConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/").with(csrf())).andExpect(status().isUnauthorized());
}
@Test
public void configureWhenUsingAllAuthorizeRequestPropertiesThenCompiles() {
this.spring.register(AllPropertiesWorkConfig.class).autowire();
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenApplicationListenerInvokedOnAuthorizedEvent()
throws Exception {
this.spring.register(AuthorizedRequestsWithPostProcessorConfig.class).autowire();
this.mvc.perform(get("/"));
verify(AuthorizedRequestsWithPostProcessorConfig.AL).onApplicationEvent(any(AuthorizedEvent.class));
}
@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());
}
@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());
}
@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());
}
@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());
}
@Test
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());
}
@Test
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());
}
@Test
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());
}
@Test
public void getWhenCustomExpressionHandlerAndAuthenticationNameDoesNotMatchThenRespondsWithForbidden()
throws Exception {
this.spring.register(CustomExpressionRootConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/deny").with(user("user").roles("USER"))).andExpect(status().isForbidden());
}
// SEC-3011
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnAccessDecisionManager() {
this.spring.register(Sec3011Config.class).autowire();
verify(Sec3011Config.objectPostProcessor).postProcess(any(AccessDecisionManager.class));
}
@Test
public void getWhenRegisteringPermissionEvaluatorAndPermissionWithIdAndTypeMatchesThenRespondsWithOk()
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/allow")).andExpect(status().isOk());
}
@Test
public void getWhenRegisteringPermissionEvaluatorAndPermissionWithIdAndTypeDoesNotMatchThenRespondsWithForbidden()
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/deny")).andExpect(status().isForbidden());
}
@Test
public void getWhenRegisteringPermissionEvaluatorAndPermissionWithObjectMatchesThenRespondsWithOk()
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/allowObject")).andExpect(status().isOk());
}
@Test
public void getWhenRegisteringPermissionEvaluatorAndPermissionWithObjectDoesNotMatchThenRespondsWithForbidden()
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/denyObject")).andExpect(status().isForbidden());
}
@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());
}
@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());
}
@EnableWebSecurity
static class HasRoleStartingWithRoleConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("ROLE_USER");
// @formatter:on
}
}
@EnableWebSecurity
static class NoSpecificAccessDecisionManagerConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER");
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
@EnableWebSecurity
static class NoRequestsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests();
// @formatter:on
}
}
@EnableWebSecurity
static class IncompleteMappingConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/a").authenticated()
.anyRequest();
// @formatter:on
}
}
@EnableWebSecurity
static class RoleUserAnyAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().hasAnyAuthority("ROLE_USER");
// @formatter:on
}
}
@EnableWebSecurity
static class RoleUserAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().hasAuthority("ROLE_USER");
// @formatter:on
}
}
@EnableWebSecurity
static class RoleUserOrRoleAdminAuthorityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().hasAnyAuthority("ROLE_USER", "ROLE_ADMIN");
// @formatter:on
}
}
@EnableWebSecurity
static class RoleUserConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasAnyRole("USER");
// @formatter:on
}
}
@EnableWebSecurity
static class RoleUserOrAdminConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasAnyRole("USER", "ADMIN");
// @formatter:on
}
}
@EnableWebSecurity
static class HasIpAddressConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().hasIpAddress("192.168.1.0");
// @formatter:on
}
}
@EnableWebSecurity
static class AnonymousConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.authorizeRequests()
.anyRequest().anonymous();
// @formatter:on
}
}
@EnableWebSecurity
static class RememberMeConfig extends WebSecurityConfigurerAdapter {
@ -473,20 +673,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@Test
public void getWhenDenyAllConfiguredAndNoUserThenRespondsWithUnauthorized() throws Exception {
this.spring.register(DenyAllConfig.class, BasicController.class).autowire();
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());
}
@EnableWebSecurity
static class DenyAllConfig extends WebSecurityConfigurerAdapter {
@ -503,22 +689,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@Test
public void getWhenNotDenyAllConfiguredAndNoUserThenRespondsWithOk() throws Exception {
this.spring.register(NotDenyAllConfig.class, BasicController.class).autowire();
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")))))
.andExpect(status().isOk());
}
@EnableWebSecurity
static class NotDenyAllConfig extends WebSecurityConfigurerAdapter {
@ -535,22 +705,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@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")))))
.andExpect(status().isUnauthorized());
}
@Test
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());
}
@EnableWebSecurity
static class FullyAuthenticatedConfig extends WebSecurityConfigurerAdapter {
@ -569,27 +723,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@Test
public void getWhenAccessRoleUserOrGetRequestConfiguredThenRespondsWithOk() throws Exception {
this.spring.register(AccessConfig.class, BasicController.class).autowire();
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());
}
@Test
public void postWhenAccessRoleUserOrGetRequestConfiguredThenRespondsWithUnauthorized() throws Exception {
this.spring.register(AccessConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/").with(csrf())).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class AccessConfig extends WebSecurityConfigurerAdapter {
@ -608,13 +741,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@Test
public void authorizeRequestsWhenInvokedTwiceThenUsesOriginalConfiguration() throws Exception {
this.spring.register(InvokeTwiceDoesNotResetConfig.class, BasicController.class).autowire();
this.mvc.perform(post("/").with(csrf())).andExpect(status().isUnauthorized());
}
@EnableWebSecurity
static class InvokeTwiceDoesNotResetConfig extends WebSecurityConfigurerAdapter {
@ -633,11 +759,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@Test
public void configureWhenUsingAllAuthorizeRequestPropertiesThenCompiles() {
this.spring.register(AllPropertiesWorkConfig.class).autowire();
}
@EnableWebSecurity
static class AllPropertiesWorkConfig extends WebSecurityConfigurerAdapter {
@ -661,16 +782,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenApplicationListenerInvokedOnAuthorizedEvent()
throws Exception {
this.spring.register(AuthorizedRequestsWithPostProcessorConfig.class).autowire();
this.mvc.perform(get("/"));
verify(AuthorizedRequestsWithPostProcessorConfig.AL).onApplicationEvent(any(AuthorizedEvent.class));
}
@EnableWebSecurity
static class AuthorizedRequestsWithPostProcessorConfig extends WebSecurityConfigurerAdapter {
@ -700,34 +811,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@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());
}
@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());
}
@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());
}
@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());
}
@EnableWebSecurity
static class UseBeansInExpressions extends WebSecurityConfigurerAdapter {
@ -758,35 +841,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@Test
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());
}
@Test
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());
}
@Test
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());
}
@Test
public void getWhenCustomExpressionHandlerAndAuthenticationNameDoesNotMatchThenRespondsWithForbidden()
throws Exception {
this.spring.register(CustomExpressionRootConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/deny").with(user("user").roles("USER"))).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class CustomExpressionRootConfig extends WebSecurityConfigurerAdapter {
@ -837,14 +891,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
// SEC-3011
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnAccessDecisionManager() {
this.spring.register(Sec3011Config.class).autowire();
verify(Sec3011Config.objectPostProcessor).postProcess(any(AccessDecisionManager.class));
}
@EnableWebSecurity
static class Sec3011Config extends WebSecurityConfigurerAdapter {
@ -874,38 +920,6 @@ public class ExpressionUrlAuthorizationConfigurerTests {
}
@Test
public void getWhenRegisteringPermissionEvaluatorAndPermissionWithIdAndTypeMatchesThenRespondsWithOk()
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/allow")).andExpect(status().isOk());
}
@Test
public void getWhenRegisteringPermissionEvaluatorAndPermissionWithIdAndTypeDoesNotMatchThenRespondsWithForbidden()
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/deny")).andExpect(status().isForbidden());
}
@Test
public void getWhenRegisteringPermissionEvaluatorAndPermissionWithObjectMatchesThenRespondsWithOk()
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/allowObject")).andExpect(status().isOk());
}
@Test
public void getWhenRegisteringPermissionEvaluatorAndPermissionWithObjectDoesNotMatchThenRespondsWithForbidden()
throws Exception {
this.spring.register(PermissionEvaluatorConfig.class, WildcardController.class).autowire();
this.mvc.perform(get("/denyObject")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class PermissionEvaluatorConfig extends WebSecurityConfigurerAdapter {
@ -941,20 +955,6 @@ 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());
}
@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());
}
@EnableWebSecurity
static class RoleHierarchyConfig extends WebSecurityConfigurerAdapter {

View File

@ -77,23 +77,6 @@ public class FormLoginConfigurerTests {
verify(config.requestCache).getRequest(any(), any());
}
@EnableWebSecurity
static class RequestCacheConfig extends WebSecurityConfigurerAdapter {
private RequestCache requestCache = mock(RequestCache.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.formLogin().and()
.requestCache()
.requestCache(this.requestCache);
// @formatter:on
}
}
@Test
public void requestCacheAsBean() throws Exception {
this.spring.register(RequestCacheBeanConfig.class, AuthenticationTestConfiguration.class).autowire();
@ -105,16 +88,6 @@ public class FormLoginConfigurerTests {
verify(requestCache).getRequest(any(), any());
}
@EnableWebSecurity
static class RequestCacheBeanConfig {
@Bean
RequestCache requestCache() {
return mock(RequestCache.class);
}
}
@Test
public void loginWhenFormLoginConfiguredThenHasDefaultUsernameAndPasswordParameterNames() throws Exception {
this.spring.register(FormLoginConfig.class).autowire();
@ -160,41 +133,6 @@ public class FormLoginConfigurerTests {
.andExpect(redirectedUrl("http://localhost/login"));
}
@EnableWebSecurity
static class FormLoginConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
// @formatter:off
web
.ignoring()
.antMatchers("/resources/**");
// @formatter:on
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.loginPage("/login");
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void loginWhenFormLoginDefaultsInLambdaThenHasDefaultUsernameAndPasswordParameterNames() throws Exception {
this.spring.register(FormLoginInLambdaConfig.class).autowire();
@ -240,32 +178,6 @@ public class FormLoginConfigurerTests {
.andExpect(redirectedUrl("http://localhost/login"));
}
@EnableWebSecurity
static class FormLoginInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.anyRequest().hasRole("USER")
)
.formLogin(withDefaults());
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void getLoginPageWhenFormLoginPermitAllThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginConfigPermitAll.class).autowire();
@ -288,23 +200,6 @@ public class FormLoginConfigurerTests {
.andExpect(redirectedUrl("/login?error"));
}
@EnableWebSecurity
static class FormLoginConfigPermitAll extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.permitAll();
// @formatter:on
}
}
@Test
public void getLoginPageWhenCustomLoginPageThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginDefaultsConfig.class).autowire();
@ -341,6 +236,198 @@ public class FormLoginConfigurerTests {
this.mockMvc.perform(get("/authenticate?logout")).andExpect(redirectedUrl(null));
}
@Test
public void getLoginPageWhenCustomLoginPageInLambdaThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginDefaultsInLambdaConfig.class).autowire();
this.mockMvc.perform(get("/authenticate")).andExpect(redirectedUrl(null));
}
@Test
public void loginWhenCustomLoginProcessingUrlThenRedirectsToHome() throws Exception {
this.spring.register(FormLoginLoginProcessingUrlConfig.class).autowire();
this.mockMvc.perform(formLogin("/loginCheck")).andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@Test
public void loginWhenCustomLoginProcessingUrlInLambdaThenRedirectsToHome() throws Exception {
this.spring.register(FormLoginLoginProcessingUrlInLambdaConfig.class).autowire();
this.mockMvc.perform(formLogin("/loginCheck")).andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@Test
public void requestWhenCustomPortMapperThenPortMapperUsed() throws Exception {
FormLoginUsesPortMapperConfig.PORT_MAPPER = mock(PortMapper.class);
when(FormLoginUsesPortMapperConfig.PORT_MAPPER.lookupHttpsPort(any())).thenReturn(9443);
this.spring.register(FormLoginUsesPortMapperConfig.class).autowire();
this.mockMvc.perform(get("http://localhost:9090")).andExpect(status().isFound())
.andExpect(redirectedUrl("https://localhost:9443/login"));
verify(FormLoginUsesPortMapperConfig.PORT_MAPPER).lookupHttpsPort(any());
}
@Test
public void failureUrlWhenPermitAllAndFailureHandlerThenSecured() throws Exception {
this.spring.register(PermitAllIgnoresFailureHandlerConfig.class).autowire();
this.mockMvc.perform(get("/login?error")).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/login"));
}
@Test
public void formLoginWhenInvokedTwiceThenUsesOriginalUsernameParameter() throws Exception {
this.spring.register(DuplicateInvocationsDoesNotOverrideConfig.class).autowire();
this.mockMvc.perform(formLogin().user("custom-username", "user")).andExpect(authenticated());
}
@Test
public void loginWhenInvalidLoginAndFailureForwardUrlThenForwardsToFailureForwardUrl() throws Exception {
this.spring.register(FormLoginUserForwardAuthenticationSuccessAndFailureConfig.class).autowire();
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"));
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnUsernamePasswordAuthenticationFilter() {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(UsernamePasswordAuthenticationFilter.class));
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnLoginUrlAuthenticationEntryPoint() {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(LoginUrlAuthenticationEntryPoint.class));
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnExceptionTranslationFilter() {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ExceptionTranslationFilter.class));
}
@EnableWebSecurity
static class RequestCacheConfig extends WebSecurityConfigurerAdapter {
private RequestCache requestCache = mock(RequestCache.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.formLogin().and()
.requestCache()
.requestCache(this.requestCache);
// @formatter:on
}
}
@EnableWebSecurity
static class RequestCacheBeanConfig {
@Bean
RequestCache requestCache() {
return mock(RequestCache.class);
}
}
@EnableWebSecurity
static class FormLoginConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
// @formatter:off
web
.ignoring()
.antMatchers("/resources/**");
// @formatter:on
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.loginPage("/login");
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class FormLoginInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.anyRequest().hasRole("USER")
)
.formLogin(withDefaults());
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class FormLoginConfigPermitAll extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.permitAll();
// @formatter:on
}
}
@EnableWebSecurity
static class FormLoginDefaultsConfig extends WebSecurityConfigurerAdapter {
@ -362,13 +449,6 @@ public class FormLoginConfigurerTests {
}
@Test
public void getLoginPageWhenCustomLoginPageInLambdaThenPermittedAndNoRedirect() throws Exception {
this.spring.register(FormLoginDefaultsInLambdaConfig.class).autowire();
this.mockMvc.perform(get("/authenticate")).andExpect(redirectedUrl(null));
}
@EnableWebSecurity
static class FormLoginDefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -391,13 +471,6 @@ public class FormLoginConfigurerTests {
}
@Test
public void loginWhenCustomLoginProcessingUrlThenRedirectsToHome() throws Exception {
this.spring.register(FormLoginLoginProcessingUrlConfig.class).autowire();
this.mockMvc.perform(formLogin("/loginCheck")).andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@EnableWebSecurity
static class FormLoginLoginProcessingUrlConfig extends WebSecurityConfigurerAdapter {
@ -434,13 +507,6 @@ public class FormLoginConfigurerTests {
}
@Test
public void loginWhenCustomLoginProcessingUrlInLambdaThenRedirectsToHome() throws Exception {
this.spring.register(FormLoginLoginProcessingUrlInLambdaConfig.class).autowire();
this.mockMvc.perform(formLogin("/loginCheck")).andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@EnableWebSecurity
static class FormLoginLoginProcessingUrlInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -479,18 +545,6 @@ public class FormLoginConfigurerTests {
}
@Test
public void requestWhenCustomPortMapperThenPortMapperUsed() throws Exception {
FormLoginUsesPortMapperConfig.PORT_MAPPER = mock(PortMapper.class);
when(FormLoginUsesPortMapperConfig.PORT_MAPPER.lookupHttpsPort(any())).thenReturn(9443);
this.spring.register(FormLoginUsesPortMapperConfig.class).autowire();
this.mockMvc.perform(get("http://localhost:9090")).andExpect(status().isFound())
.andExpect(redirectedUrl("https://localhost:9443/login"));
verify(FormLoginUsesPortMapperConfig.PORT_MAPPER).lookupHttpsPort(any());
}
@EnableWebSecurity
static class FormLoginUsesPortMapperConfig extends WebSecurityConfigurerAdapter {
@ -516,14 +570,6 @@ public class FormLoginConfigurerTests {
}
@Test
public void failureUrlWhenPermitAllAndFailureHandlerThenSecured() throws Exception {
this.spring.register(PermitAllIgnoresFailureHandlerConfig.class).autowire();
this.mockMvc.perform(get("/login?error")).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/login"));
}
@EnableWebSecurity
static class PermitAllIgnoresFailureHandlerConfig extends WebSecurityConfigurerAdapter {
@ -544,13 +590,6 @@ public class FormLoginConfigurerTests {
}
@Test
public void formLoginWhenInvokedTwiceThenUsesOriginalUsernameParameter() throws Exception {
this.spring.register(DuplicateInvocationsDoesNotOverrideConfig.class).autowire();
this.mockMvc.perform(formLogin().user("custom-username", "user")).andExpect(authenticated());
}
@EnableWebSecurity
static class DuplicateInvocationsDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@ -576,20 +615,6 @@ public class FormLoginConfigurerTests {
}
@Test
public void loginWhenInvalidLoginAndFailureForwardUrlThenForwardsToFailureForwardUrl() throws Exception {
this.spring.register(FormLoginUserForwardAuthenticationSuccessAndFailureConfig.class).autowire();
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"));
}
@EnableWebSecurity
static class FormLoginUserForwardAuthenticationSuccessAndFailureConfig extends WebSecurityConfigurerAdapter {
@ -620,31 +645,6 @@ public class FormLoginConfigurerTests {
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnUsernamePasswordAuthenticationFilter() {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor)
.postProcess(any(UsernamePasswordAuthenticationFilter.class));
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnLoginUrlAuthenticationEntryPoint() {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(LoginUrlAuthenticationEntryPoint.class));
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnExceptionTranslationFilter() {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
this.spring.register(ObjectPostProcessorConfig.class).autowire();
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(ExceptionTranslationFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {

View File

@ -47,6 +47,18 @@ public class HeadersConfigurerEagerHeadersTests {
@Autowired
MockMvc mvc;
@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"))
.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("X-XSS-Protection", "1; mode=block"));
}
@EnableWebSecurity
public static class HeadersAtTheBeginningOfRequestConfig extends WebSecurityConfigurerAdapter {
@ -65,16 +77,4 @@ public class HeadersConfigurerEagerHeadersTests {
}
@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"))
.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("X-XSS-Protection", "1; mode=block"));
}
}

View File

@ -71,6 +71,52 @@ public class HttpBasicConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(BasicAuthenticationFilter.class));
}
@Test
public void httpBasicWhenUsingDefaultsInLambdaThenResponseIncludesBasicChallenge() throws Exception {
this.spring.register(DefaultsLambdaEntryPointConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
}
// SEC-2198
@Test
public void httpBasicWhenUsingDefaultsThenResponseIncludesBasicChallenge() throws Exception {
this.spring.register(DefaultsEntryPointConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
}
@Test
public void httpBasicWhenUsingCustomAuthenticationEntryPointThenResponseIncludesBasicChallenge() throws Exception {
this.spring.register(CustomAuthenticationEntryPointConfig.class).autowire();
this.mvc.perform(get("/"));
verify(CustomAuthenticationEntryPointConfig.ENTRY_POINT).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@Test
public void httpBasicWhenInvokedTwiceThenUsesOriginalEntryPoint() throws Exception {
this.spring.register(DuplicateDoesNotOverrideConfig.class).autowire();
this.mvc.perform(get("/"));
verify(DuplicateDoesNotOverrideConfig.ENTRY_POINT).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
// 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"))
.andExpect(cookie().exists("remember-me"));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
@ -100,14 +146,6 @@ public class HttpBasicConfigurerTests {
}
@Test
public void httpBasicWhenUsingDefaultsInLambdaThenResponseIncludesBasicChallenge() throws Exception {
this.spring.register(DefaultsLambdaEntryPointConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
}
@EnableWebSecurity
static class DefaultsLambdaEntryPointConfig extends WebSecurityConfigurerAdapter {
@ -133,15 +171,6 @@ public class HttpBasicConfigurerTests {
}
// SEC-2198
@Test
public void httpBasicWhenUsingDefaultsThenResponseIncludesBasicChallenge() throws Exception {
this.spring.register(DefaultsEntryPointConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(status().isUnauthorized())
.andExpect(header().string("WWW-Authenticate", "Basic realm=\"Realm\""));
}
@EnableWebSecurity
static class DefaultsEntryPointConfig extends WebSecurityConfigurerAdapter {
@ -166,16 +195,6 @@ public class HttpBasicConfigurerTests {
}
@Test
public void httpBasicWhenUsingCustomAuthenticationEntryPointThenResponseIncludesBasicChallenge() throws Exception {
this.spring.register(CustomAuthenticationEntryPointConfig.class).autowire();
this.mvc.perform(get("/"));
verify(CustomAuthenticationEntryPointConfig.ENTRY_POINT).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@EnableWebSecurity
static class CustomAuthenticationEntryPointConfig extends WebSecurityConfigurerAdapter {
@ -203,16 +222,6 @@ public class HttpBasicConfigurerTests {
}
@Test
public void httpBasicWhenInvokedTwiceThenUsesOriginalEntryPoint() throws Exception {
this.spring.register(DuplicateDoesNotOverrideConfig.class).autowire();
this.mvc.perform(get("/"));
verify(DuplicateDoesNotOverrideConfig.ENTRY_POINT).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@ -242,15 +251,6 @@ public class HttpBasicConfigurerTests {
}
// 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"))
.andExpect(cookie().exists("remember-me"));
}
@EnableWebSecurity
@Configuration
static class BasicUsesRememberMeConfig extends WebSecurityConfigurerAdapter {

View File

@ -78,6 +78,25 @@ public class HttpSecurityAntMatchersTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_FORBIDDEN);
}
// SEC-3135
@Test
public void antMatchersMethodAndEmptyPatterns() throws Exception {
loadConfig(AntMatchersEmptyPatternsConfig.class);
this.request.setMethod("POST");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
@EnableWebSecurity
@Configuration
static class AntMatchersNoPatternsConfig extends WebSecurityConfigurerAdapter {
@ -104,17 +123,6 @@ public class HttpSecurityAntMatchersTests {
}
// SEC-3135
@Test
public void antMatchersMethodAndEmptyPatterns() throws Exception {
loadConfig(AntMatchersEmptyPatternsConfig.class);
this.request.setMethod("POST");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
@EnableWebSecurity
@Configuration
static class AntMatchersEmptyPatternsConfig extends WebSecurityConfigurerAdapter {
@ -142,12 +150,4 @@ public class HttpSecurityAntMatchersTests {
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@ -86,6 +86,14 @@ public class HttpSecurityLogoutTests {
assertThat(currentContext.getAuthentication()).isNotNull();
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
@EnableWebSecurity
@Configuration
static class ClearAuthenticationFalseConfig extends WebSecurityConfigurerAdapter {
@ -110,12 +118,4 @@ public class HttpSecurityLogoutTests {
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@ -105,6 +105,119 @@ public class HttpSecurityRequestMatchersTests {
assertThat(this.springSecurityFilterChain.getFilters("/path")).isNotEmpty();
}
@Test
public void requestMatchersMvcMatcher() throws Exception {
loadConfig(RequestMatchersMvcMatcherConfig.class, LegacyMvcMatchingConfig.class);
this.request.setServletPath("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
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);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@Test
public void requestMatchersWhenMvcMatcherInLambdaThenPathIsSecured() throws Exception {
loadConfig(RequestMatchersMvcMatcherInLambdaConfig.class, LegacyMvcMatchingConfig.class);
this.request.setServletPath("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
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);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@Test
public void requestMatchersMvcMatcherServletPath() throws Exception {
loadConfig(RequestMatchersMvcMatcherServeltPathConfig.class);
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("");
this.request.setRequestURI("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/other");
this.request.setRequestURI("/other/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
@Test
public void requestMatcherWhensMvcMatcherServletPathInLambdaThenPathIsSecured() throws Exception {
loadConfig(RequestMatchersMvcMatcherServletPathInLambdaConfig.class);
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("");
this.request.setRequestURI("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/other");
this.request.setRequestURI("/other/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.setServletContext(new MockServletContext());
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -141,30 +254,6 @@ public class HttpSecurityRequestMatchersTests {
}
@Test
public void requestMatchersMvcMatcher() throws Exception {
loadConfig(RequestMatchersMvcMatcherConfig.class, LegacyMvcMatchingConfig.class);
this.request.setServletPath("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
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);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -203,30 +292,6 @@ public class HttpSecurityRequestMatchersTests {
}
@Test
public void requestMatchersWhenMvcMatcherInLambdaThenPathIsSecured() throws Exception {
loadConfig(RequestMatchersMvcMatcherInLambdaConfig.class, LegacyMvcMatchingConfig.class);
this.request.setServletPath("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
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);
setup();
this.request.setServletPath("/path/");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -260,34 +325,6 @@ public class HttpSecurityRequestMatchersTests {
}
@Test
public void requestMatchersMvcMatcherServletPath() throws Exception {
loadConfig(RequestMatchersMvcMatcherServeltPathConfig.class);
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("");
this.request.setRequestURI("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/other");
this.request.setRequestURI("/other/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -327,34 +364,6 @@ public class HttpSecurityRequestMatchersTests {
}
@Test
public void requestMatcherWhensMvcMatcherServletPathInLambdaThenPathIsSecured() throws Exception {
loadConfig(RequestMatchersMvcMatcherServletPathInLambdaConfig.class);
this.request.setServletPath("/spring");
this.request.setRequestURI("/spring/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_UNAUTHORIZED);
setup();
this.request.setServletPath("");
this.request.setRequestURI("/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
setup();
this.request.setServletPath("/other");
this.request.setRequestURI("/other/path");
this.springSecurityFilterChain.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -399,13 +408,4 @@ public class HttpSecurityRequestMatchersTests {
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.setServletContext(new MockServletContext());
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@ -60,6 +60,36 @@ public class Issue55Tests {
assertThat(filter.getAuthenticationManager().authenticate(token)).isEqualTo(CustomAuthenticationManager.RESULT);
}
@Test
public void multiHttpWebSecurityConfigurerAdapterDefaultsToAutowired()
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this");
this.spring.register(MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig.class);
this.spring.getContext().getBean(FilterChainProxy.class);
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);
}
Filter findFilter(Class<?> filter, int index) {
List<Filter> filters = filterChain(index).getFilters();
for (Filter it : filters) {
if (filter.isAssignableFrom(it.getClass())) {
return it;
}
}
return null;
}
SecurityFilterChain filterChain(int index) {
return this.spring.getContext().getBean(FilterChainProxy.class).getFilterChains().get(index);
}
@EnableWebSecurity
static class WebSecurityConfigurerAdapterDefaultsAuthManagerConfig {
@ -89,22 +119,6 @@ public class Issue55Tests {
}
@Test
public void multiHttpWebSecurityConfigurerAdapterDefaultsToAutowired()
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TestingAuthenticationToken token = new TestingAuthenticationToken("test", "this");
this.spring.register(MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig.class);
this.spring.getContext().getBean(FilterChainProxy.class);
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);
}
@EnableWebSecurity
static class MultiWebSecurityConfigurerAdapterDefaultsAuthManagerConfig {
@ -160,18 +174,4 @@ public class Issue55Tests {
}
Filter findFilter(Class<?> filter, int index) {
List<Filter> filters = filterChain(index).getFilters();
for (Filter it : filters) {
if (filter.isAssignableFrom(it.getClass())) {
return it;
}
}
return null;
}
SecurityFilterChain filterChain(int index) {
return this.spring.getContext().getBean(FilterChainProxy.class).getFilterChains().get(index);
}
}

View File

@ -75,6 +75,63 @@ public class JeeConfigurerTests {
.postProcess(any(J2eeBasedPreAuthenticatedWebAuthenticationDetailsSource.class));
}
@Test
public void jeeWhenInvokedTwiceThenUsesOriginalMappableRoles() throws Exception {
this.spring.register(InvokeTwiceDoesNotOverride.class).autowire();
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"));
}
@Test
public void requestWhenJeeMappableRolesInLambdaThenAuthenticatedWithMappableRoles() throws Exception {
this.spring.register(JeeMappableRolesConfig.class).autowire();
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"));
}
@Test
public void requestWhenJeeMappableAuthoritiesInLambdaThenAuthenticatedWithMappableAuthorities() throws Exception {
this.spring.register(JeeMappableAuthoritiesConfig.class).autowire();
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")));
}
@Test
public void requestWhenCustomAuthenticatedUserDetailsServiceInLambdaThenCustomAuthenticatedUserDetailsServiceUsed()
throws Exception {
this.spring.register(JeeCustomAuthenticatedUserDetailsServiceConfig.class).autowire();
Principal user = mock(Principal.class);
User userDetails = new User("user", "N/A", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_USER"));
when(user.getName()).thenReturn("user");
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"));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
@ -104,19 +161,6 @@ public class JeeConfigurerTests {
}
@Test
public void jeeWhenInvokedTwiceThenUsesOriginalMappableRoles() throws Exception {
this.spring.register(InvokeTwiceDoesNotOverride.class).autowire();
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"));
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
@ -133,19 +177,6 @@ public class JeeConfigurerTests {
}
@Test
public void requestWhenJeeMappableRolesInLambdaThenAuthenticatedWithMappableRoles() throws Exception {
this.spring.register(JeeMappableRolesConfig.class).autowire();
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"));
}
@EnableWebSecurity
public static class JeeMappableRolesConfig extends WebSecurityConfigurerAdapter {
@ -166,19 +197,6 @@ public class JeeConfigurerTests {
}
@Test
public void requestWhenJeeMappableAuthoritiesInLambdaThenAuthenticatedWithMappableAuthorities() throws Exception {
this.spring.register(JeeMappableAuthoritiesConfig.class).autowire();
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")));
}
@EnableWebSecurity
public static class JeeMappableAuthoritiesConfig extends WebSecurityConfigurerAdapter {
@ -199,24 +217,6 @@ public class JeeConfigurerTests {
}
@Test
public void requestWhenCustomAuthenticatedUserDetailsServiceInLambdaThenCustomAuthenticatedUserDetailsServiceUsed()
throws Exception {
this.spring.register(JeeCustomAuthenticatedUserDetailsServiceConfig.class).autowire();
Principal user = mock(Principal.class);
User userDetails = new User("user", "N/A", true, true, true, true,
AuthorityUtils.createAuthorityList("ROLE_USER"));
when(user.getName()).thenReturn("user");
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"));
}
@EnableWebSecurity
public static class JeeCustomAuthenticatedUserDetailsServiceConfig extends WebSecurityConfigurerAdapter {

View File

@ -70,82 +70,24 @@ public class LogoutConfigurerTests {
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutSuccessHandlerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout()
.defaultLogoutSuccessHandlerFor(null, mock(RequestMatcher.class));
// @formatter:on
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullLogoutHandlerInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullLogoutSuccessHandlerInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutSuccessHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout ->
logout.defaultLogoutSuccessHandlerFor(null, mock(RequestMatcher.class))
);
// @formatter:on
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullMatcherThenException() {
assertThatThrownBy(() -> this.spring.register(NullMatcherConfig.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout()
.defaultLogoutSuccessHandlerFor(mock(LogoutSuccessHandler.class), null);
// @formatter:on
}
}
@Test
public void configureWhenDefaultLogoutSuccessHandlerForHasNullMatcherInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullMatcherInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout ->
logout.defaultLogoutSuccessHandlerFor(mock(LogoutSuccessHandler.class), null)
);
// @formatter:on
}
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnLogoutFilter() {
this.spring.register(ObjectPostProcessorConfig.class).autowire();
@ -153,35 +95,6 @@ public class LogoutConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(LogoutFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout();
// @formatter:on
}
@Bean
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();
@ -190,30 +103,6 @@ public class LogoutConfigurerTests {
.andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout()
.logoutUrl("/custom/logout")
.and()
.logout();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
// SEC-2311
@Test
public void logoutWhenGetRequestAndCsrfDisabledThenRedirectsToLogin() throws Exception {
@ -243,21 +132,6 @@ public class LogoutConfigurerTests {
this.mvc.perform(delete("/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
static class CsrfDisabledConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.logout();
// @formatter:on
}
}
@Test
public void logoutWhenGetRequestAndCsrfDisabledAndCustomLogoutUrlThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledAndCustomLogoutConfig.class).autowire();
@ -288,22 +162,6 @@ public class LogoutConfigurerTests {
.andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
static class CsrfDisabledAndCustomLogoutConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.logout()
.logoutUrl("/custom/logout");
// @formatter:on
}
}
@Test
public void logoutWhenCustomLogoutUrlInLambdaThenRedirectsToLogin() throws Exception {
this.spring.register(CsrfDisabledAndCustomLogoutInLambdaConfig.class).autowire();
@ -311,21 +169,6 @@ public class LogoutConfigurerTests {
this.mvc.perform(get("/custom/logout")).andExpect(status().isFound()).andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
static class CsrfDisabledAndCustomLogoutInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.logout(logout -> logout.logoutUrl("/custom/logout"));
// @formatter:on
}
}
// SEC-3170
@Test
public void configureWhenLogoutHandlerNullThenException() {
@ -333,39 +176,12 @@ public class LogoutConfigurerTests {
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutHandlerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout()
.addLogoutHandler(null);
// @formatter:on
}
}
@Test
public void configureWhenLogoutHandlerNullInLambdaThenException() {
assertThatThrownBy(() -> this.spring.register(NullLogoutHandlerInLambdaConfig.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class);
}
@EnableWebSecurity
static class NullLogoutHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout -> logout.addLogoutHandler(null));
// @formatter:on
}
}
// SEC-3170
@Test
public void rememberMeWhenRememberMeServicesNotLogoutHandlerThenRedirectsToLogin() throws Exception {
@ -375,22 +191,6 @@ public class LogoutConfigurerTests {
.andExpect(redirectedUrl("/login?logout"));
}
@EnableWebSecurity
static class RememberMeNoLogoutHandler extends WebSecurityConfigurerAdapter {
static RememberMeServices REMEMBER_ME = mock(RememberMeServices.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.rememberMe()
.rememberMeServices(REMEMBER_ME);
// @formatter:on
}
}
@Test
public void logoutWhenAcceptTextHtmlThenRedirectsToLogin() throws Exception {
this.spring.register(BasicSecurityConfig.class).autowire();
@ -439,11 +239,6 @@ public class LogoutConfigurerTests {
.andExpect(status().isNoContent());
}
@EnableWebSecurity
static class BasicSecurityConfig extends WebSecurityConfigurerAdapter {
}
@Test
public void logoutWhenDisabledThenLogoutUrlNotFound() throws Exception {
this.spring.register(LogoutDisabledConfig.class).autowire();
@ -451,6 +246,211 @@ public class LogoutConfigurerTests {
this.mvc.perform(post("/logout").with(csrf())).andExpect(status().isNotFound());
}
@EnableWebSecurity
static class NullLogoutSuccessHandlerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout()
.defaultLogoutSuccessHandlerFor(null, mock(RequestMatcher.class));
// @formatter:on
}
}
@EnableWebSecurity
static class NullLogoutSuccessHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout ->
logout.defaultLogoutSuccessHandlerFor(null, mock(RequestMatcher.class))
);
// @formatter:on
}
}
@EnableWebSecurity
static class NullMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout()
.defaultLogoutSuccessHandlerFor(mock(LogoutSuccessHandler.class), null);
// @formatter:on
}
}
@EnableWebSecurity
static class NullMatcherInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout ->
logout.defaultLogoutSuccessHandlerFor(mock(LogoutSuccessHandler.class), null)
);
// @formatter:on
}
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout()
.logoutUrl("/custom/logout")
.and()
.logout();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
}
@EnableWebSecurity
static class CsrfDisabledConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.logout();
// @formatter:on
}
}
@EnableWebSecurity
static class CsrfDisabledAndCustomLogoutConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.logout()
.logoutUrl("/custom/logout");
// @formatter:on
}
}
@EnableWebSecurity
static class CsrfDisabledAndCustomLogoutInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.csrf()
.disable()
.logout(logout -> logout.logoutUrl("/custom/logout"));
// @formatter:on
}
}
@EnableWebSecurity
static class NullLogoutHandlerConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout()
.addLogoutHandler(null);
// @formatter:on
}
}
@EnableWebSecurity
static class NullLogoutHandlerInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.logout(logout -> logout.addLogoutHandler(null));
// @formatter:on
}
}
@EnableWebSecurity
static class RememberMeNoLogoutHandler extends WebSecurityConfigurerAdapter {
static RememberMeServices REMEMBER_ME = mock(RememberMeServices.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.rememberMe()
.rememberMeServices(REMEMBER_ME);
// @formatter:on
}
}
@EnableWebSecurity
static class BasicSecurityConfig extends WebSecurityConfigurerAdapter {
}
@EnableWebSecurity
static class LogoutDisabledConfig extends WebSecurityConfigurerAdapter {

View File

@ -61,11 +61,6 @@ public class NamespaceDebugTests {
verify(appender, atLeastOnce()).doAppend(any(ILoggingEvent.class));
}
@EnableWebSecurity(debug = true)
static class DebugWebSecurity extends WebSecurityConfigurerAdapter {
}
@Test
public void requestWhenDebugSetToFalseThenDoesNotLogDebugInformation() throws Exception {
Appender<ILoggingEvent> appender = mockAppenderFor("Spring Security Debugger");
@ -75,11 +70,6 @@ public class NamespaceDebugTests {
verify(appender, never()).doAppend(any(ILoggingEvent.class));
}
@EnableWebSecurity
static class NoDebugWebSecurity extends WebSecurityConfigurerAdapter {
}
private Appender<ILoggingEvent> mockAppenderFor(String name) {
Appender<ILoggingEvent> appender = mock(Appender.class);
Logger logger = (Logger) LoggerFactory.getLogger(name);
@ -92,4 +82,14 @@ public class NamespaceDebugTests {
return this.spring.getContext().getBean("springSecurityFilterChain").getClass();
}
@EnableWebSecurity(debug = true)
static class DebugWebSecurity extends WebSecurityConfigurerAdapter {
}
@EnableWebSecurity
static class NoDebugWebSecurity extends WebSecurityConfigurerAdapter {
}
}

View File

@ -60,6 +60,30 @@ public class NamespaceHttpAnonymousTests {
this.mvc.perform(get("/type")).andExpect(content().string(AnonymousAuthenticationToken.class.getSimpleName()));
}
@Test
public void anonymousRequestWhenDisablingAnonymousThenDenies() throws Exception {
this.spring.register(AnonymousDisabledConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/type")).andExpect(status().isForbidden());
}
@Test
public void requestWhenAnonymousThenSendsAnonymousConfiguredAuthorities() throws Exception {
this.spring.register(AnonymousGrantedAuthorityConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/type")).andExpect(content().string(AnonymousAuthenticationToken.class.getSimpleName()));
}
@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())));
}
@Test
public void anonymousRequestWhenAnonymousUsernameConfiguredThenUsernameIsUsed() throws Exception {
this.spring.register(AnonymousUsernameConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/principal")).andExpect(content().string("AnonymousUsernameConfig"));
}
@EnableWebSecurity
static class AnonymousConfig extends WebSecurityConfigurerAdapter {
@ -75,12 +99,6 @@ public class NamespaceHttpAnonymousTests {
}
@Test
public void anonymousRequestWhenDisablingAnonymousThenDenies() throws Exception {
this.spring.register(AnonymousDisabledConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/type")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class AnonymousDisabledConfig extends WebSecurityConfigurerAdapter {
@ -107,12 +125,6 @@ public class NamespaceHttpAnonymousTests {
}
@Test
public void requestWhenAnonymousThenSendsAnonymousConfiguredAuthorities() throws Exception {
this.spring.register(AnonymousGrantedAuthorityConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/type")).andExpect(content().string(AnonymousAuthenticationToken.class.getSimpleName()));
}
@EnableWebSecurity
static class AnonymousGrantedAuthorityConfig extends WebSecurityConfigurerAdapter {
@ -131,12 +143,6 @@ public class NamespaceHttpAnonymousTests {
}
@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())));
}
@EnableWebSecurity
static class AnonymousKeyConfig extends WebSecurityConfigurerAdapter {
@ -154,12 +160,6 @@ public class NamespaceHttpAnonymousTests {
}
@Test
public void anonymousRequestWhenAnonymousUsernameConfiguredThenUsernameIsUsed() throws Exception {
this.spring.register(AnonymousUsernameConfig.class, AnonymousController.class).autowire();
this.mvc.perform(get("/principal")).andExpect(content().string("AnonymousUsernameConfig"));
}
@EnableWebSecurity
static class AnonymousUsernameConfig extends WebSecurityConfigurerAdapter {

View File

@ -73,6 +73,90 @@ public class NamespaceHttpBasicTests {
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@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("/").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());
}
/**
* http@realm equivalent
*/
@Test
public void basicAuthenticationWhenUsingCustomRealmThenMatchesNamespace() throws Exception {
this.spring.register(CustomHttpBasicConfig.class, UserConfig.class).autowire();
this.mvc.perform(get("/").with(httpBasic("user", "invalid"))).andExpect(status().isUnauthorized())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\""));
}
@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())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\""));
}
/**
* http/http-basic@authentication-details-source-ref equivalent
*/
@Test
public void basicAuthenticationWhenUsingAuthenticationDetailsSourceRefThenMatchesNamespace() throws Exception {
this.spring.register(AuthenticationDetailsSourceHttpBasicConfig.class, UserConfig.class).autowire();
AuthenticationDetailsSource<HttpServletRequest, ?> source = this.spring.getContext()
.getBean(AuthenticationDetailsSource.class);
this.mvc.perform(get("/").with(httpBasic("user", "password")));
verify(source).buildDetails(any(HttpServletRequest.class));
}
@Test
public void basicAuthenticationWhenUsingAuthenticationDetailsSourceRefInLambdaThenMatchesNamespace()
throws Exception {
this.spring.register(AuthenticationDetailsSourceHttpBasicLambdaConfig.class, UserConfig.class).autowire();
AuthenticationDetailsSource<HttpServletRequest, ?> source = this.spring.getContext()
.getBean(AuthenticationDetailsSource.class);
this.mvc.perform(get("/").with(httpBasic("user", "password")));
verify(source).buildDetails(any(HttpServletRequest.class));
}
/**
* http/http-basic@entry-point-ref
*/
@Test
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("/").with(httpBasic("user", "invalid"))).andExpect(status().is(999));
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@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("/").with(httpBasic("user", "invalid"))).andExpect(status().is(999));
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@Configuration
static class UserConfig {
@ -107,18 +191,6 @@ public class NamespaceHttpBasicTests {
}
@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("/").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());
}
@EnableWebSecurity
static class HttpBasicLambdaConfig extends WebSecurityConfigurerAdapter {
@ -136,17 +208,6 @@ public class NamespaceHttpBasicTests {
}
/**
* http@realm equivalent
*/
@Test
public void basicAuthenticationWhenUsingCustomRealmThenMatchesNamespace() throws Exception {
this.spring.register(CustomHttpBasicConfig.class, UserConfig.class).autowire();
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 {
@ -163,14 +224,6 @@ public class NamespaceHttpBasicTests {
}
@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())
.andExpect(header().string(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Custom Realm\""));
}
@EnableWebSecurity
static class CustomHttpBasicLambdaConfig extends WebSecurityConfigurerAdapter {
@ -188,21 +241,6 @@ public class NamespaceHttpBasicTests {
}
/**
* http/http-basic@authentication-details-source-ref equivalent
*/
@Test
public void basicAuthenticationWhenUsingAuthenticationDetailsSourceRefThenMatchesNamespace() throws Exception {
this.spring.register(AuthenticationDetailsSourceHttpBasicConfig.class, UserConfig.class).autowire();
AuthenticationDetailsSource<HttpServletRequest, ?> source = this.spring.getContext()
.getBean(AuthenticationDetailsSource.class);
this.mvc.perform(get("/").with(httpBasic("user", "password")));
verify(source).buildDetails(any(HttpServletRequest.class));
}
@EnableWebSecurity
static class AuthenticationDetailsSourceHttpBasicConfig extends WebSecurityConfigurerAdapter {
@ -225,19 +263,6 @@ public class NamespaceHttpBasicTests {
}
@Test
public void basicAuthenticationWhenUsingAuthenticationDetailsSourceRefInLambdaThenMatchesNamespace()
throws Exception {
this.spring.register(AuthenticationDetailsSourceHttpBasicLambdaConfig.class, UserConfig.class).autowire();
AuthenticationDetailsSource<HttpServletRequest, ?> source = this.spring.getContext()
.getBean(AuthenticationDetailsSource.class);
this.mvc.perform(get("/").with(httpBasic("user", "password")));
verify(source).buildDetails(any(HttpServletRequest.class));
}
@EnableWebSecurity
static class AuthenticationDetailsSourceHttpBasicLambdaConfig extends WebSecurityConfigurerAdapter {
@ -260,20 +285,6 @@ public class NamespaceHttpBasicTests {
}
/**
* http/http-basic@entry-point-ref
*/
@Test
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("/").with(httpBasic("user", "invalid"))).andExpect(status().is(999));
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@EnableWebSecurity
static class EntryPointRefHttpBasicConfig extends WebSecurityConfigurerAdapter {
@ -293,17 +304,6 @@ public class NamespaceHttpBasicTests {
}
@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("/").with(httpBasic("user", "invalid"))).andExpect(status().is(999));
this.mvc.perform(get("/").with(httpBasic("user", "password"))).andExpect(status().isNotFound());
}
@EnableWebSecurity
static class EntryPointRefHttpBasicLambdaConfig extends WebSecurityConfigurerAdapter {

View File

@ -65,6 +65,37 @@ public class NamespaceHttpCustomFilterTests {
assertThatFilters().containsSubsequence(CustomFilter.class, UsernamePasswordAuthenticationFilter.class);
}
@Test
public void getFiltersWhenFilterAddedAfterThenBehaviorMatchesNamespace() {
this.spring.register(CustomFilterAfterConfig.class, UserDetailsServiceConfig.class).autowire();
assertThatFilters().containsSubsequence(UsernamePasswordAuthenticationFilter.class, CustomFilter.class);
}
@Test
public void getFiltersWhenFilterAddedThenBehaviorMatchesNamespace() {
this.spring.register(CustomFilterPositionConfig.class, UserDetailsServiceConfig.class).autowire();
assertThatFilters().containsExactly(CustomFilter.class);
}
@Test
public void getFiltersWhenFilterAddedAtPositionThenBehaviorMatchesNamespace() {
this.spring.register(CustomFilterPositionAtConfig.class, UserDetailsServiceConfig.class).autowire();
assertThatFilters().containsExactly(OtherCustomFilter.class);
}
@Test
public void getFiltersWhenCustomAuthenticationManagerThenBehaviorMatchesNamespace() {
this.spring.register(NoAuthenticationManagerInHttpConfigurationConfig.class).autowire();
assertThatFilters().startsWith(CustomFilter.class);
}
private ListAssert<Class<?>> assertThatFilters() {
FilterChainProxy filterChain = this.spring.getContext().getBean(FilterChainProxy.class);
List<Class<?>> filters = filterChain.getFilters("/").stream().map(Object::getClass)
.collect(Collectors.toList());
return assertThat(filters);
}
@EnableWebSecurity
static class CustomFilterBeforeConfig extends WebSecurityConfigurerAdapter {
@ -79,12 +110,6 @@ public class NamespaceHttpCustomFilterTests {
}
@Test
public void getFiltersWhenFilterAddedAfterThenBehaviorMatchesNamespace() {
this.spring.register(CustomFilterAfterConfig.class, UserDetailsServiceConfig.class).autowire();
assertThatFilters().containsSubsequence(UsernamePasswordAuthenticationFilter.class, CustomFilter.class);
}
@EnableWebSecurity
static class CustomFilterAfterConfig extends WebSecurityConfigurerAdapter {
@ -99,12 +124,6 @@ public class NamespaceHttpCustomFilterTests {
}
@Test
public void getFiltersWhenFilterAddedThenBehaviorMatchesNamespace() {
this.spring.register(CustomFilterPositionConfig.class, UserDetailsServiceConfig.class).autowire();
assertThatFilters().containsExactly(CustomFilter.class);
}
@EnableWebSecurity
static class CustomFilterPositionConfig extends WebSecurityConfigurerAdapter {
@ -125,12 +144,6 @@ public class NamespaceHttpCustomFilterTests {
}
@Test
public void getFiltersWhenFilterAddedAtPositionThenBehaviorMatchesNamespace() {
this.spring.register(CustomFilterPositionAtConfig.class, UserDetailsServiceConfig.class).autowire();
assertThatFilters().containsExactly(OtherCustomFilter.class);
}
@EnableWebSecurity
static class CustomFilterPositionAtConfig extends WebSecurityConfigurerAdapter {
@ -149,12 +162,6 @@ public class NamespaceHttpCustomFilterTests {
}
@Test
public void getFiltersWhenCustomAuthenticationManagerThenBehaviorMatchesNamespace() {
this.spring.register(NoAuthenticationManagerInHttpConfigurationConfig.class).autowire();
assertThatFilters().startsWith(CustomFilter.class);
}
@EnableWebSecurity
static class NoAuthenticationManagerInHttpConfigurationConfig extends WebSecurityConfigurerAdapter {
@ -220,11 +227,4 @@ public class NamespaceHttpCustomFilterTests {
}
private ListAssert<Class<?>> assertThatFilters() {
FilterChainProxy filterChain = this.spring.getContext().getBean(FilterChainProxy.class);
List<Class<?>> filters = filterChain.getFilters("/").stream().map(Object::getClass)
.collect(Collectors.toList());
return assertThat(filters);
}
}

View File

@ -70,6 +70,10 @@ public class NamespaceHttpExpressionHandlerTests {
verifyBean("expressionParser", ExpressionParser.class).parseExpression("hasRole('USER')");
}
private <T> T verifyBean(String beanName, Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanName, beanClass));
}
@EnableWebMvc
@EnableWebSecurity
private static class ExpressionHandlerConfig extends WebSecurityConfigurerAdapter {
@ -115,8 +119,4 @@ public class NamespaceHttpExpressionHandlerTests {
}
private <T> T verifyBean(String beanName, Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanName, beanClass));
}
}

View File

@ -56,11 +56,6 @@ public class NamespaceHttpFirewallTests {
assertThatCode(() -> this.mvc.perform(get("/public/../private/"))).isInstanceOf(RequestRejectedException.class);
}
@EnableWebSecurity
static class HttpFirewallConfig {
}
@Test
public void requestWithCustomFirewallThenBehaviorMatchesNamespace() {
this.rule.register(CustomHttpFirewallConfig.class).autowire();
@ -68,6 +63,18 @@ public class NamespaceHttpFirewallTests {
.isInstanceOf(RequestRejectedException.class);
}
@Test
public void requestWithCustomFirewallBeanThenBehaviorMatchesNamespace() {
this.rule.register(CustomHttpFirewallBeanConfig.class).autowire();
assertThatCode(() -> this.mvc.perform(get("/").param("deny", "true")))
.isInstanceOf(RequestRejectedException.class);
}
@EnableWebSecurity
static class HttpFirewallConfig {
}
@EnableWebSecurity
static class CustomHttpFirewallConfig extends WebSecurityConfigurerAdapter {
@ -78,13 +85,6 @@ public class NamespaceHttpFirewallTests {
}
@Test
public void requestWithCustomFirewallBeanThenBehaviorMatchesNamespace() {
this.rule.register(CustomHttpFirewallBeanConfig.class).autowire();
assertThatCode(() -> this.mvc.perform(get("/").param("deny", "true")))
.isInstanceOf(RequestRejectedException.class);
}
@EnableWebSecurity
static class CustomHttpFirewallBeanConfig {

View File

@ -71,6 +71,36 @@ public class NamespaceHttpFormLoginTests {
.andExpect(redirectedUrl("/"));
}
@Test
public void formLoginWithCustomEndpointsThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(FormLoginCustomConfig.class, UserDetailsServiceConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("http://localhost/authentication/login"));
this.mvc.perform(post("/authentication/login/process").with(csrf()))
.andExpect(redirectedUrl("/authentication/login?failed"));
this.mvc.perform(post("/authentication/login/process").param("username", "user").param("password", "password")
.with(csrf())).andExpect(redirectedUrl("/default"));
}
@Test
public void formLoginWithCustomHandlersThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(FormLoginCustomRefsConfig.class, UserDetailsServiceConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("http://localhost/login"));
this.mvc.perform(post("/login").with(csrf())).andExpect(redirectedUrl("/custom/failure"));
verifyBean(WebAuthenticationDetailsSource.class).buildDetails(any(HttpServletRequest.class));
this.mvc.perform(post("/login").param("username", "user").param("password", "password").with(csrf()))
.andExpect(redirectedUrl("/custom/targetUrl"));
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
@EnableWebSecurity
static class FormLoginConfig extends WebSecurityConfigurerAdapter {
@ -92,19 +122,6 @@ public class NamespaceHttpFormLoginTests {
}
@Test
public void formLoginWithCustomEndpointsThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(FormLoginCustomConfig.class, UserDetailsServiceConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("http://localhost/authentication/login"));
this.mvc.perform(post("/authentication/login/process").with(csrf()))
.andExpect(redirectedUrl("/authentication/login?failed"));
this.mvc.perform(post("/authentication/login/process").param("username", "user").param("password", "password")
.with(csrf())).andExpect(redirectedUrl("/default"));
}
@EnableWebSecurity
static class FormLoginCustomConfig extends WebSecurityConfigurerAdapter {
@ -128,19 +145,6 @@ public class NamespaceHttpFormLoginTests {
}
@Test
public void formLoginWithCustomHandlersThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(FormLoginCustomRefsConfig.class, UserDetailsServiceConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("http://localhost/login"));
this.mvc.perform(post("/login").with(csrf())).andExpect(redirectedUrl("/custom/failure"));
verifyBean(WebAuthenticationDetailsSource.class).buildDetails(any(HttpServletRequest.class));
this.mvc.perform(post("/login").param("username", "user").param("password", "password").with(csrf()))
.andExpect(redirectedUrl("/custom/targetUrl"));
}
@EnableWebSecurity
static class FormLoginCustomRefsConfig extends WebSecurityConfigurerAdapter {
@ -186,8 +190,4 @@ public class NamespaceHttpFormLoginTests {
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
}

View File

@ -73,19 +73,6 @@ public class NamespaceHttpHeadersTests {
this.mvc.perform(get("/").secure(true)).andExpect(includesDefaults());
}
@EnableWebSecurity
static class HeadersDefaultConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers();
// @formatter:on
}
}
@Test
public void secureRequestWhenCacheControlOnlyThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(HeadersCacheControlConfig.class).autowire();
@ -93,21 +80,6 @@ public class NamespaceHttpHeadersTests {
this.mvc.perform(get("/").secure(true)).andExpect(includes("Cache-Control", "Expires", "Pragma"));
}
@EnableWebSecurity
static class HeadersCacheControlConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
.defaultsDisabled()
.cacheControl();
// @formatter:on
}
}
@Test
public void secureRequestWhenHstsOnlyThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(HstsConfig.class).autowire();
@ -115,21 +87,6 @@ public class NamespaceHttpHeadersTests {
this.mvc.perform(get("/").secure(true)).andExpect(includes("Strict-Transport-Security"));
}
@EnableWebSecurity
static class HstsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
.defaultsDisabled()
.httpStrictTransportSecurity();
// @formatter:on
}
}
@Test
public void requestWhenHstsCustomThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(HstsCustomConfig.class).autowire();
@ -138,25 +95,6 @@ public class NamespaceHttpHeadersTests {
.andExpect(includes(Collections.singletonMap("Strict-Transport-Security", "max-age=15768000")));
}
@EnableWebSecurity
static class HstsCustomConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// hsts@request-matcher-ref, hsts@max-age-seconds, hsts@include-subdomains
.defaultsDisabled()
.httpStrictTransportSecurity()
.requestMatcher(AnyRequestMatcher.INSTANCE)
.maxAgeInSeconds(15768000)
.includeSubDomains(false);
// @formatter:on
}
}
@Test
public void requestWhenFrameOptionsSameOriginThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(FrameOptionsSameOriginConfig.class).autowire();
@ -164,26 +102,6 @@ public class NamespaceHttpHeadersTests {
this.mvc.perform(get("/")).andExpect(includes(Collections.singletonMap("X-Frame-Options", "SAMEORIGIN")));
}
@EnableWebSecurity
static class FrameOptionsSameOriginConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// frame-options@policy=SAMEORIGIN
.defaultsDisabled()
.frameOptions()
.sameOrigin();
// @formatter:on
}
}
// frame-options@strategy, frame-options@value, frame-options@parameter are not
// provided instead use frame-options@ref
@Test
public void requestWhenFrameOptionsAllowFromThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(FrameOptionsAllowFromConfig.class).autowire();
@ -192,23 +110,6 @@ public class NamespaceHttpHeadersTests {
.andExpect(includes(Collections.singletonMap("X-Frame-Options", "ALLOW-FROM https://example.com")));
}
@EnableWebSecurity
static class FrameOptionsAllowFromConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// frame-options@ref
.defaultsDisabled()
.addHeaderWriter(new XFrameOptionsHeaderWriter(
new StaticAllowFromStrategy(URI.create("https://example.com"))));
// @formatter:on
}
}
@Test
public void requestWhenXssOnlyThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(XssProtectionConfig.class).autowire();
@ -216,22 +117,6 @@ public class NamespaceHttpHeadersTests {
this.mvc.perform(get("/")).andExpect(includes("X-XSS-Protection"));
}
@EnableWebSecurity
static class XssProtectionConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// xss-protection
.defaultsDisabled()
.xssProtection();
// @formatter:on
}
}
@Test
public void requestWhenXssCustomThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(XssProtectionCustomConfig.class).autowire();
@ -239,24 +124,6 @@ public class NamespaceHttpHeadersTests {
this.mvc.perform(get("/")).andExpect(includes(Collections.singletonMap("X-XSS-Protection", "1")));
}
@EnableWebSecurity
static class XssProtectionCustomConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// xss-protection@enabled and xss-protection@block
.defaultsDisabled()
.xssProtection()
.xssProtectionEnabled(true)
.block(false);
// @formatter:on
}
}
@Test
public void requestWhenXContentTypeOptionsOnlyThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(ContentTypeOptionsConfig.class).autowire();
@ -264,24 +131,6 @@ public class NamespaceHttpHeadersTests {
this.mvc.perform(get("/")).andExpect(includes("X-Content-Type-Options"));
}
@EnableWebSecurity
static class ContentTypeOptionsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// content-type-options
.defaultsDisabled()
.contentTypeOptions();
// @formatter:on
}
}
// header@name / header@value are not provided instead use header@ref
@Test
public void requestWhenCustomHeaderOnlyThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(HeaderRefConfig.class).autowire();
@ -290,21 +139,6 @@ public class NamespaceHttpHeadersTests {
.andExpect(includes(Collections.singletonMap("customHeaderName", "customHeaderValue")));
}
@EnableWebSecurity
static class HeaderRefConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
.defaultsDisabled()
.addHeaderWriter(new StaticHeadersWriter("customHeaderName", "customHeaderValue"));
// @formatter:on
}
}
private static ResultMatcher includesDefaults() {
return includes(defaultHeaders);
}
@ -326,4 +160,165 @@ public class NamespaceHttpHeadersTests {
};
}
@EnableWebSecurity
static class HeadersDefaultConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers();
// @formatter:on
}
}
@EnableWebSecurity
static class HeadersCacheControlConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
.defaultsDisabled()
.cacheControl();
// @formatter:on
}
}
@EnableWebSecurity
static class HstsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
.defaultsDisabled()
.httpStrictTransportSecurity();
// @formatter:on
}
}
@EnableWebSecurity
static class HstsCustomConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// hsts@request-matcher-ref, hsts@max-age-seconds, hsts@include-subdomains
.defaultsDisabled()
.httpStrictTransportSecurity()
.requestMatcher(AnyRequestMatcher.INSTANCE)
.maxAgeInSeconds(15768000)
.includeSubDomains(false);
// @formatter:on
}
}
@EnableWebSecurity
static class FrameOptionsSameOriginConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// frame-options@policy=SAMEORIGIN
.defaultsDisabled()
.frameOptions()
.sameOrigin();
// @formatter:on
}
}
@EnableWebSecurity
static class FrameOptionsAllowFromConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// frame-options@ref
.defaultsDisabled()
.addHeaderWriter(new XFrameOptionsHeaderWriter(
new StaticAllowFromStrategy(URI.create("https://example.com"))));
// @formatter:on
}
}
@EnableWebSecurity
static class XssProtectionConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// xss-protection
.defaultsDisabled()
.xssProtection();
// @formatter:on
}
}
@EnableWebSecurity
static class XssProtectionCustomConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// xss-protection@enabled and xss-protection@block
.defaultsDisabled()
.xssProtection()
.xssProtectionEnabled(true)
.block(false);
// @formatter:on
}
}
@EnableWebSecurity
static class ContentTypeOptionsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
// content-type-options
.defaultsDisabled()
.contentTypeOptions();
// @formatter:on
}
}
@EnableWebSecurity
static class HeaderRefConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.headers()
.defaultsDisabled()
.addHeaderWriter(new StaticHeadersWriter("customHeaderName", "customHeaderValue"));
// @formatter:on
}
}
}

View File

@ -100,6 +100,10 @@ public class NamespaceHttpInterceptUrlTests {
this.mvc.perform(get("https://localhost/user")).andExpect(redirectedUrl("http://localhost/user"));
}
private static Authentication user(String role) {
return new UsernamePasswordAuthenticationToken("user", null, AuthorityUtils.createAuthorityList(role));
}
@EnableWebSecurity
static class HttpInterceptUrlConfig extends WebSecurityConfigurerAdapter {
@ -173,8 +177,4 @@ public class NamespaceHttpInterceptUrlTests {
}
private static Authentication user(String role) {
return new UsernamePasswordAuthenticationToken("user", null, AuthorityUtils.createAuthorityList(role));
}
}

View File

@ -73,23 +73,6 @@ public class NamespaceHttpJeeTests {
})).andExpect(status().isOk()).andExpect(content().string("ROLE_admin,ROLE_user"));
}
@EnableWebSecurity
public static class JeeMappableRolesConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("user")
.and()
.jee()
.mappableRoles("user", "admin");
// @formatter:on
}
}
@Test
public void requestWhenCustomAuthenticatedUserDetailsServiceThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(JeeUserServiceRefConfig.class, BaseController.class).autowire();
@ -108,6 +91,31 @@ public class NamespaceHttpJeeTests {
verifyBean(AuthenticationUserDetailsService.class).loadUserDetails(any());
}
private <T> T bean(Class<T> beanClass) {
return this.spring.getContext().getBean(beanClass);
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
@EnableWebSecurity
public static class JeeMappableRolesConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("user")
.and()
.jee()
.mappableRoles("user", "admin");
// @formatter:on
}
}
@EnableWebSecurity
public static class JeeUserServiceRefConfig extends WebSecurityConfigurerAdapter {
@ -149,12 +157,4 @@ public class NamespaceHttpJeeTests {
}
private <T> T bean(Class<T> beanClass) {
return this.spring.getContext().getBean(beanClass);
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
}

View File

@ -76,15 +76,6 @@ public class NamespaceHttpLogoutTests {
.andExpect(redirectedUrl("/login?logout")).andExpect(noCookies()).andExpect(session(Objects::isNull));
}
@EnableWebSecurity
static class HttpLogoutConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
}
}
@Test
@WithMockUser
public void logoutWhenDisabledInLambdaThenRespondsWithNotFound() throws Exception {
@ -93,16 +84,6 @@ public class NamespaceHttpLogoutTests {
this.mvc.perform(post("/logout").with(csrf()).with(user("user"))).andExpect(status().isNotFound());
}
@EnableWebSecurity
static class HttpLogoutDisabledInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.logout(AbstractHttpConfigurer::disable);
}
}
/**
* http/logout custom
*/
@ -117,6 +98,73 @@ public class NamespaceHttpLogoutTests {
.andExpect(cookie().maxAge("remove", 0)).andExpect(session(Objects::nonNull));
}
@Test
@WithMockUser
public void logoutWhenUsingVariousCustomizationsInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(CustomHttpLogoutInLambdaConfig.class).autowire();
this.mvc.perform(post("/custom-logout").with(csrf())).andExpect(authenticated(false))
.andExpect(redirectedUrl("/logout-success"))
.andExpect(result -> assertThat(result.getResponse().getCookies()).hasSize(1))
.andExpect(cookie().maxAge("remove", 0)).andExpect(session(Objects::nonNull));
}
/**
* http/logout@success-handler-ref
*/
@Test
@WithMockUser
public void logoutWhenUsingSuccessHandlerRefThenMatchesNamespace() throws Exception {
this.spring.register(SuccessHandlerRefHttpLogoutConfig.class).autowire();
this.mvc.perform(post("/logout").with(csrf())).andExpect(authenticated(false))
.andExpect(redirectedUrl("/SuccessHandlerRefHttpLogoutConfig")).andExpect(noCookies())
.andExpect(session(Objects::isNull));
}
@Test
@WithMockUser
public void logoutWhenUsingSuccessHandlerRefInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(SuccessHandlerRefHttpLogoutInLambdaConfig.class).autowire();
this.mvc.perform(post("/logout").with(csrf())).andExpect(authenticated(false))
.andExpect(redirectedUrl("/SuccessHandlerRefHttpLogoutConfig")).andExpect(noCookies())
.andExpect(session(Objects::isNull));
}
ResultMatcher authenticated(boolean authenticated) {
return result -> assertThat(Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
.map(Authentication::isAuthenticated).orElse(false)).isEqualTo(authenticated);
}
ResultMatcher noCookies() {
return result -> assertThat(result.getResponse().getCookies()).isEmpty();
}
ResultMatcher session(Predicate<HttpSession> sessionPredicate) {
return result -> assertThat(result.getRequest().getSession(false))
.is(new Condition<>(sessionPredicate, "sessionPredicate failed"));
}
@EnableWebSecurity
static class HttpLogoutConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) {
}
}
@EnableWebSecurity
static class HttpLogoutDisabledInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.logout(AbstractHttpConfigurer::disable);
}
}
@EnableWebSecurity
static class CustomHttpLogoutConfig extends WebSecurityConfigurerAdapter {
@ -134,17 +182,6 @@ public class NamespaceHttpLogoutTests {
}
@Test
@WithMockUser
public void logoutWhenUsingVariousCustomizationsInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(CustomHttpLogoutInLambdaConfig.class).autowire();
this.mvc.perform(post("/custom-logout").with(csrf())).andExpect(authenticated(false))
.andExpect(redirectedUrl("/logout-success"))
.andExpect(result -> assertThat(result.getResponse().getCookies()).hasSize(1))
.andExpect(cookie().maxAge("remove", 0)).andExpect(session(Objects::nonNull));
}
@EnableWebSecurity
static class CustomHttpLogoutInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -163,19 +200,6 @@ public class NamespaceHttpLogoutTests {
}
/**
* http/logout@success-handler-ref
*/
@Test
@WithMockUser
public void logoutWhenUsingSuccessHandlerRefThenMatchesNamespace() throws Exception {
this.spring.register(SuccessHandlerRefHttpLogoutConfig.class).autowire();
this.mvc.perform(post("/logout").with(csrf())).andExpect(authenticated(false))
.andExpect(redirectedUrl("/SuccessHandlerRefHttpLogoutConfig")).andExpect(noCookies())
.andExpect(session(Objects::isNull));
}
@EnableWebSecurity
static class SuccessHandlerRefHttpLogoutConfig extends WebSecurityConfigurerAdapter {
@ -192,16 +216,6 @@ public class NamespaceHttpLogoutTests {
}
@Test
@WithMockUser
public void logoutWhenUsingSuccessHandlerRefInLambdaThenMatchesNamespace() throws Exception {
this.spring.register(SuccessHandlerRefHttpLogoutInLambdaConfig.class).autowire();
this.mvc.perform(post("/logout").with(csrf())).andExpect(authenticated(false))
.andExpect(redirectedUrl("/SuccessHandlerRefHttpLogoutConfig")).andExpect(noCookies())
.andExpect(session(Objects::isNull));
}
@EnableWebSecurity
static class SuccessHandlerRefHttpLogoutInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -218,18 +232,4 @@ public class NamespaceHttpLogoutTests {
}
ResultMatcher authenticated(boolean authenticated) {
return result -> assertThat(Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
.map(Authentication::isAuthenticated).orElse(false)).isEqualTo(authenticated);
}
ResultMatcher noCookies() {
return result -> assertThat(result.getResponse().getCookies()).isEmpty();
}
ResultMatcher session(Predicate<HttpSession> sessionPredicate) {
return result -> assertThat(result.getRequest().getSession(false))
.is(new Condition<>(sessionPredicate, "sessionPredicate failed"));
}
}

View File

@ -92,24 +92,6 @@ public class NamespaceHttpOpenIDLoginTests {
this.mvc.perform(post("/login/openid").with(csrf())).andExpect(redirectedUrl("/login?error"));
}
@Configuration
@EnableWebSecurity
static class OpenIDLoginConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.openidLogin()
.permitAll();
// @formatter:on
}
}
@Test
public void openidLoginWhenAttributeExchangeConfiguredThenFetchAttributesMatchAttributeList() throws Exception {
OpenIDLoginAttributeExchangeConfig.CONSUMER_MANAGER = mock(ConsumerManager.class);
@ -148,6 +130,59 @@ public class NamespaceHttpOpenIDLoginTests {
}
}
@Test
public void openidLoginWhenUsingCustomEndpointsThenMatchesNamespace() throws Exception {
this.spring.register(OpenIDLoginCustomConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("http://localhost/authentication/login"));
this.mvc.perform(post("/authentication/login/process").with(csrf()))
.andExpect(redirectedUrl("/authentication/login?failed"));
}
@Test
public void openidLoginWithCustomHandlersThenBehaviorMatchesNamespace() throws Exception {
OpenIDAuthenticationToken token = new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.SUCCESS,
"identityUrl", "message", Arrays.asList(new OpenIDAttribute("name", "type")));
OpenIDLoginCustomRefsConfig.AUDS = mock(AuthenticationUserDetailsService.class);
when(OpenIDLoginCustomRefsConfig.AUDS.loadUserDetails(any(Authentication.class)))
.thenReturn(new User("user", "password", AuthorityUtils.createAuthorityList("ROLE_USER")));
OpenIDLoginCustomRefsConfig.ADS = spy(new WebAuthenticationDetailsSource());
OpenIDLoginCustomRefsConfig.CONSUMER = mock(OpenIDConsumer.class);
this.spring.register(OpenIDLoginCustomRefsConfig.class, UserDetailsServiceConfig.class).autowire();
when(OpenIDLoginCustomRefsConfig.CONSUMER.endConsumption(any(HttpServletRequest.class)))
.thenThrow(new AuthenticationServiceException("boom"));
this.mvc.perform(post("/login/openid").with(csrf()).param("openid.identity", "identity"))
.andExpect(redirectedUrl("/custom/failure"));
reset(OpenIDLoginCustomRefsConfig.CONSUMER);
when(OpenIDLoginCustomRefsConfig.CONSUMER.endConsumption(any(HttpServletRequest.class))).thenReturn(token);
this.mvc.perform(post("/login/openid").with(csrf()).param("openid.identity", "identity"))
.andExpect(redirectedUrl("/custom/targetUrl"));
verify(OpenIDLoginCustomRefsConfig.AUDS).loadUserDetails(any(Authentication.class));
verify(OpenIDLoginCustomRefsConfig.ADS).buildDetails(any(Object.class));
}
@Configuration
@EnableWebSecurity
static class OpenIDLoginConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.openidLogin()
.permitAll();
// @formatter:on
}
}
@Configuration
@EnableWebSecurity
static class OpenIDLoginAttributeExchangeConfig extends WebSecurityConfigurerAdapter {
@ -194,14 +229,6 @@ public class NamespaceHttpOpenIDLoginTests {
}
@Test
public void openidLoginWhenUsingCustomEndpointsThenMatchesNamespace() throws Exception {
this.spring.register(OpenIDLoginCustomConfig.class).autowire();
this.mvc.perform(get("/")).andExpect(redirectedUrl("http://localhost/authentication/login"));
this.mvc.perform(post("/authentication/login/process").with(csrf()))
.andExpect(redirectedUrl("/authentication/login?failed"));
}
@Configuration
@EnableWebSecurity
static class OpenIDLoginCustomConfig extends WebSecurityConfigurerAdapter {
@ -225,33 +252,6 @@ public class NamespaceHttpOpenIDLoginTests {
}
@Test
public void openidLoginWithCustomHandlersThenBehaviorMatchesNamespace() throws Exception {
OpenIDAuthenticationToken token = new OpenIDAuthenticationToken(OpenIDAuthenticationStatus.SUCCESS,
"identityUrl", "message", Arrays.asList(new OpenIDAttribute("name", "type")));
OpenIDLoginCustomRefsConfig.AUDS = mock(AuthenticationUserDetailsService.class);
when(OpenIDLoginCustomRefsConfig.AUDS.loadUserDetails(any(Authentication.class)))
.thenReturn(new User("user", "password", AuthorityUtils.createAuthorityList("ROLE_USER")));
OpenIDLoginCustomRefsConfig.ADS = spy(new WebAuthenticationDetailsSource());
OpenIDLoginCustomRefsConfig.CONSUMER = mock(OpenIDConsumer.class);
this.spring.register(OpenIDLoginCustomRefsConfig.class, UserDetailsServiceConfig.class).autowire();
when(OpenIDLoginCustomRefsConfig.CONSUMER.endConsumption(any(HttpServletRequest.class)))
.thenThrow(new AuthenticationServiceException("boom"));
this.mvc.perform(post("/login/openid").with(csrf()).param("openid.identity", "identity"))
.andExpect(redirectedUrl("/custom/failure"));
reset(OpenIDLoginCustomRefsConfig.CONSUMER);
when(OpenIDLoginCustomRefsConfig.CONSUMER.endConsumption(any(HttpServletRequest.class))).thenReturn(token);
this.mvc.perform(post("/login/openid").with(csrf()).param("openid.identity", "identity"))
.andExpect(redirectedUrl("/custom/targetUrl"));
verify(OpenIDLoginCustomRefsConfig.AUDS).loadUserDetails(any(Authentication.class));
verify(OpenIDLoginCustomRefsConfig.ADS).buildDetails(any(Object.class));
}
@Configuration
@EnableWebSecurity
static class OpenIDLoginCustomRefsConfig extends WebSecurityConfigurerAdapter {

View File

@ -64,6 +64,21 @@ public class NamespaceHttpRequestCacheTests {
verifyBean(RequestCache.class).saveRequest(any(HttpServletRequest.class), any(HttpServletResponse.class));
}
@Test
public void requestWhenDefaultConfigurationThenUsesHttpSessionRequestCache() throws Exception {
this.spring.register(DefaultRequestCacheRefConfig.class).autowire();
MvcResult result = this.mvc.perform(get("/")).andExpect(status().isForbidden()).andReturn();
HttpSession session = result.getRequest().getSession(false);
assertThat(session).isNotNull();
assertThat(session.getAttribute("SPRING_SECURITY_SAVED_REQUEST")).isNotNull();
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
@EnableWebSecurity
static class RequestCacheRefConfig extends WebSecurityConfigurerAdapter {
@ -96,17 +111,6 @@ public class NamespaceHttpRequestCacheTests {
}
@Test
public void requestWhenDefaultConfigurationThenUsesHttpSessionRequestCache() throws Exception {
this.spring.register(DefaultRequestCacheRefConfig.class).autowire();
MvcResult result = this.mvc.perform(get("/")).andExpect(status().isForbidden()).andReturn();
HttpSession session = result.getRequest().getSession(false);
assertThat(session).isNotNull();
assertThat(session.getAttribute("SPRING_SECURITY_SAVED_REQUEST")).isNotNull();
}
@EnableWebSecurity
static class DefaultRequestCacheRefConfig extends WebSecurityConfigurerAdapter {
@ -131,8 +135,4 @@ public class NamespaceHttpRequestCacheTests {
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
}

View File

@ -65,6 +65,40 @@ public class NamespaceHttpServerAccessDeniedHandlerTests {
.andExpect(forwardedUrl("/AccessDeniedPageConfig"));
}
@Test
public void requestWhenCustomAccessDeniedPageInLambdaThenForwardedToCustomPage() throws Exception {
this.spring.register(AccessDeniedPageInLambdaConfig.class).autowire();
this.mvc.perform(get("/").with(authentication(user()))).andExpect(status().isForbidden())
.andExpect(forwardedUrl("/AccessDeniedPageConfig"));
}
@Test
public void requestWhenCustomAccessDeniedHandlerThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(AccessDeniedHandlerRefConfig.class).autowire();
this.mvc.perform(get("/").with(authentication(user())));
verifyBean(AccessDeniedHandler.class).handle(any(HttpServletRequest.class), any(HttpServletResponse.class),
any(AccessDeniedException.class));
}
@Test
public void requestWhenCustomAccessDeniedHandlerInLambdaThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(AccessDeniedHandlerRefInLambdaConfig.class).autowire();
this.mvc.perform(get("/").with(authentication(user())));
verify(AccessDeniedHandlerRefInLambdaConfig.accessDeniedHandler).handle(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AccessDeniedException.class));
}
private static Authentication user() {
return new UsernamePasswordAuthenticationToken("user", null, AuthorityUtils.NO_AUTHORITIES);
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
@EnableWebSecurity
static class AccessDeniedPageConfig extends WebSecurityConfigurerAdapter {
@ -82,18 +116,6 @@ public class NamespaceHttpServerAccessDeniedHandlerTests {
}
private static Authentication user() {
return new UsernamePasswordAuthenticationToken("user", null, AuthorityUtils.NO_AUTHORITIES);
}
@Test
public void requestWhenCustomAccessDeniedPageInLambdaThenForwardedToCustomPage() throws Exception {
this.spring.register(AccessDeniedPageInLambdaConfig.class).autowire();
this.mvc.perform(get("/").with(authentication(user()))).andExpect(status().isForbidden())
.andExpect(forwardedUrl("/AccessDeniedPageConfig"));
}
@EnableWebSecurity
static class AccessDeniedPageInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -113,14 +135,6 @@ public class NamespaceHttpServerAccessDeniedHandlerTests {
}
@Test
public void requestWhenCustomAccessDeniedHandlerThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(AccessDeniedHandlerRefConfig.class).autowire();
this.mvc.perform(get("/").with(authentication(user())));
verifyBean(AccessDeniedHandler.class).handle(any(HttpServletRequest.class), any(HttpServletResponse.class),
any(AccessDeniedException.class));
}
@EnableWebSecurity
static class AccessDeniedHandlerRefConfig extends WebSecurityConfigurerAdapter {
@ -143,16 +157,6 @@ public class NamespaceHttpServerAccessDeniedHandlerTests {
}
@Test
public void requestWhenCustomAccessDeniedHandlerInLambdaThenBehaviorMatchesNamespace() throws Exception {
this.spring.register(AccessDeniedHandlerRefInLambdaConfig.class).autowire();
this.mvc.perform(get("/").with(authentication(user())));
verify(AccessDeniedHandlerRefInLambdaConfig.accessDeniedHandler).handle(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AccessDeniedException.class));
}
@EnableWebSecurity
static class AccessDeniedHandlerRefInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -179,8 +183,4 @@ public class NamespaceHttpServerAccessDeniedHandlerTests {
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
}

View File

@ -77,6 +77,58 @@ public class NamespaceHttpX509Tests {
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("rod"));
}
@Test
public void x509AuthenticationWhenHasCustomAuthenticationDetailsSourceThenMatchesNamespace() throws Exception {
this.spring.register(AuthenticationDetailsSourceRefConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rod.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("rod"));
verifyBean(AuthenticationDetailsSource.class).buildDetails(any());
}
@Test
public void x509AuthenticationWhenHasSubjectPrincipalRegexThenMatchesNamespace() throws Exception {
this.spring.register(SubjectPrincipalRegexConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("rod"));
}
@Test
public void x509AuthenticationWhenHasCustomPrincipalExtractorThenMatchesNamespace() throws Exception {
this.spring.register(CustomPrincipalExtractorConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("rod@example.com"));
}
@Test
public void x509AuthenticationWhenHasCustomUserDetailsServiceThenMatchesNamespace() throws Exception {
this.spring.register(UserDetailsServiceRefConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("customuser"));
}
@Test
public void x509AuthenticationWhenHasCustomAuthenticationUserDetailsServiceThenMatchesNamespace() throws Exception {
this.spring.register(AuthenticationUserDetailsServiceConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("customuser"));
}
<T extends Certificate> T loadCert(String location) {
try (InputStream is = new ClassPathResource(location).getInputStream()) {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
return (T) certFactory.generateCertificate(is);
}
catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
<T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
@EnableWebSecurity
@EnableWebMvc
public static class X509Config extends WebSecurityConfigurerAdapter {
@ -103,16 +155,6 @@ public class NamespaceHttpX509Tests {
}
@Test
public void x509AuthenticationWhenHasCustomAuthenticationDetailsSourceThenMatchesNamespace() throws Exception {
this.spring.register(AuthenticationDetailsSourceRefConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rod.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("rod"));
verifyBean(AuthenticationDetailsSource.class).buildDetails(any());
}
@EnableWebSecurity
@EnableWebMvc
static class AuthenticationDetailsSourceRefConfig extends WebSecurityConfigurerAdapter {
@ -146,13 +188,6 @@ public class NamespaceHttpX509Tests {
}
@Test
public void x509AuthenticationWhenHasSubjectPrincipalRegexThenMatchesNamespace() throws Exception {
this.spring.register(SubjectPrincipalRegexConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("rod"));
}
@EnableWebMvc
@EnableWebSecurity
public static class SubjectPrincipalRegexConfig extends WebSecurityConfigurerAdapter {
@ -180,13 +215,6 @@ public class NamespaceHttpX509Tests {
}
@Test
public void x509AuthenticationWhenHasCustomPrincipalExtractorThenMatchesNamespace() throws Exception {
this.spring.register(CustomPrincipalExtractorConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("rod@example.com"));
}
@EnableWebMvc
@EnableWebSecurity
public static class CustomPrincipalExtractorConfig extends WebSecurityConfigurerAdapter {
@ -223,13 +251,6 @@ public class NamespaceHttpX509Tests {
}
@Test
public void x509AuthenticationWhenHasCustomUserDetailsServiceThenMatchesNamespace() throws Exception {
this.spring.register(UserDetailsServiceRefConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("customuser"));
}
@EnableWebMvc
@EnableWebSecurity
public static class UserDetailsServiceRefConfig extends WebSecurityConfigurerAdapter {
@ -257,13 +278,6 @@ public class NamespaceHttpX509Tests {
}
@Test
public void x509AuthenticationWhenHasCustomAuthenticationUserDetailsServiceThenMatchesNamespace() throws Exception {
this.spring.register(AuthenticationUserDetailsServiceConfig.class, X509Controller.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/whoami").with(x509(certificate))).andExpect(content().string("customuser"));
}
@EnableWebMvc
@EnableWebSecurity
public static class AuthenticationUserDetailsServiceConfig extends WebSecurityConfigurerAdapter {
@ -297,18 +311,4 @@ public class NamespaceHttpX509Tests {
}
<T extends Certificate> T loadCert(String location) {
try (InputStream is = new ClassPathResource(location).getInputStream()) {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
return (T) certFactory.generateCertificate(is);
}
catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
<T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
}

View File

@ -98,6 +98,160 @@ public class NamespaceRememberMeTests {
.andExpect(redirectedUrl("http://localhost/login")).andReturn();
}
// SEC-3170 - RememberMeService implementations should not have to also implement
// LogoutHandler
@Test
public void logoutWhenCustomRememberMeServicesDeclaredThenUses() throws Exception {
RememberMeServicesRefConfig.REMEMBER_ME_SERVICES = mock(RememberMeServicesWithoutLogoutHandler.class);
this.spring.register(RememberMeServicesRefConfig.class).autowire();
this.mvc.perform(get("/"));
verify(RememberMeServicesRefConfig.REMEMBER_ME_SERVICES).autoLogin(any(HttpServletRequest.class),
any(HttpServletResponse.class));
this.mvc.perform(post("/login").with(csrf()));
verify(RememberMeServicesRefConfig.REMEMBER_ME_SERVICES).loginFail(any(HttpServletRequest.class),
any(HttpServletResponse.class));
}
@Test
public void rememberMeLoginWhenAuthenticationSuccessHandlerDeclaredThenUses() throws Exception {
AuthSuccessConfig.SUCCESS_HANDLER = mock(AuthenticationSuccessHandler.class);
this.spring.register(AuthSuccessConfig.class).autowire();
MvcResult result = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn();
verifyZeroInteractions(AuthSuccessConfig.SUCCESS_HANDLER);
Cookie rememberMe = result.getResponse().getCookie("remember-me");
assertThat(rememberMe).isNotNull();
this.mvc.perform(get("/somewhere").cookie(rememberMe));
verify(AuthSuccessConfig.SUCCESS_HANDLER).onAuthenticationSuccess(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(Authentication.class));
}
@Test
public void rememberMeLoginWhenKeyDeclaredThenMatchesNamespace() throws Exception {
this.spring.register(WithoutKeyConfig.class, KeyConfig.class, SecurityController.class).autowire();
Cookie withoutKey = this.mvc.perform(post("/without-key/login").with(rememberMeLogin()))
.andExpect(redirectedUrl("/")).andReturn().getResponse().getCookie("remember-me");
this.mvc.perform(get("/somewhere").cookie(withoutKey)).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/login"));
Cookie withKey = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("remember-me");
this.mvc.perform(get("/somewhere").cookie(withKey)).andExpect(status().isNotFound());
}
// http/remember-me@services-alias is not supported use standard aliasing instead
// (i.e. @Bean("alias"))
// http/remember-me@data-source-ref is not supported directly. Instead use
// http/remember-me@token-repository-ref example
@Test
public void rememberMeLoginWhenDeclaredTokenRepositoryThenMatchesNamespace() throws Exception {
TokenRepositoryRefConfig.TOKEN_REPOSITORY = mock(PersistentTokenRepository.class);
this.spring.register(TokenRepositoryRefConfig.class).autowire();
this.mvc.perform(post("/login").with(rememberMeLogin()));
verify(TokenRepositoryRefConfig.TOKEN_REPOSITORY).createNewToken(any(PersistentRememberMeToken.class));
}
@Test
public void rememberMeLoginWhenTokenValidityDeclaredThenMatchesNamespace() throws Exception {
this.spring.register(TokenValiditySecondsConfig.class).autowire();
Cookie expiredRememberMe = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("remember-me");
assertThat(expiredRememberMe).extracting(Cookie::getMaxAge).isEqualTo(314);
}
@Test
public void rememberMeLoginWhenUsingDefaultsThenCookieMaxAgeMatchesNamespace() throws Exception {
this.spring.register(RememberMeConfig.class).autowire();
Cookie expiredRememberMe = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("remember-me");
assertThat(expiredRememberMe).extracting(Cookie::getMaxAge).isEqualTo(AbstractRememberMeServices.TWO_WEEKS_S);
}
@Test
public void rememberMeLoginWhenUsingSecureCookieThenMatchesNamespace() throws Exception {
this.spring.register(UseSecureCookieConfig.class).autowire();
Cookie secureCookie = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("remember-me");
assertThat(secureCookie).extracting(Cookie::getSecure).isEqualTo(true);
}
@Test
public void rememberMeLoginWhenUsingDefaultsThenCookieSecurityMatchesNamespace() throws Exception {
this.spring.register(RememberMeConfig.class).autowire();
Cookie secureCookie = this.mvc.perform(post("/login").with(rememberMeLogin()).secure(true)).andReturn()
.getResponse().getCookie("remember-me");
assertThat(secureCookie).extracting(Cookie::getSecure).isEqualTo(true);
}
@Test
public void rememberMeLoginWhenParameterSpecifiedThenMatchesNamespace() throws Exception {
this.spring.register(RememberMeParameterConfig.class).autowire();
Cookie rememberMe = this.mvc.perform(post("/login").with(rememberMeLogin("rememberMe", true))).andReturn()
.getResponse().getCookie("remember-me");
assertThat(rememberMe).isNotNull();
}
// SEC-2880
@Test
public void rememberMeLoginWhenCookieNameDeclaredThenMatchesNamespace() throws Exception {
this.spring.register(RememberMeCookieNameConfig.class).autowire();
Cookie rememberMe = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("rememberMe");
assertThat(rememberMe).isNotNull();
}
@Test
public void rememberMeLoginWhenGlobalUserDetailsServiceDeclaredThenMatchesNamespace() throws Exception {
DefaultsUserDetailsServiceWithDaoConfig.USERDETAILS_SERVICE = mock(UserDetailsService.class);
this.spring.register(DefaultsUserDetailsServiceWithDaoConfig.class).autowire();
this.mvc.perform(post("/login").with(rememberMeLogin()));
verify(DefaultsUserDetailsServiceWithDaoConfig.USERDETAILS_SERVICE).loadUserByUsername("user");
}
@Test
public void rememberMeLoginWhenUserDetailsServiceDeclaredThenMatchesNamespace() throws Exception {
UserServiceRefConfig.USERDETAILS_SERVICE = mock(UserDetailsService.class);
this.spring.register(UserServiceRefConfig.class).autowire();
when(UserServiceRefConfig.USERDETAILS_SERVICE.loadUserByUsername("user"))
.thenReturn(new User("user", "password", AuthorityUtils.createAuthorityList("ROLE_USER")));
this.mvc.perform(post("/login").with(rememberMeLogin()));
verify(UserServiceRefConfig.USERDETAILS_SERVICE).loadUserByUsername("user");
}
static RequestPostProcessor rememberMeLogin() {
return rememberMeLogin("remember-me", true);
}
static RequestPostProcessor rememberMeLogin(String parameterName, boolean parameterValue) {
return request -> {
csrf().postProcessRequest(request);
request.setParameter("username", "user");
request.setParameter("password", "password");
request.setParameter(parameterName, String.valueOf(parameterValue));
return request;
};
}
@Configuration
@EnableWebSecurity
static class RememberMeConfig extends UsersConfig {
@ -117,22 +271,6 @@ public class NamespaceRememberMeTests {
}
// SEC-3170 - RememberMeService implementations should not have to also implement
// LogoutHandler
@Test
public void logoutWhenCustomRememberMeServicesDeclaredThenUses() throws Exception {
RememberMeServicesRefConfig.REMEMBER_ME_SERVICES = mock(RememberMeServicesWithoutLogoutHandler.class);
this.spring.register(RememberMeServicesRefConfig.class).autowire();
this.mvc.perform(get("/"));
verify(RememberMeServicesRefConfig.REMEMBER_ME_SERVICES).autoLogin(any(HttpServletRequest.class),
any(HttpServletResponse.class));
this.mvc.perform(post("/login").with(csrf()));
verify(RememberMeServicesRefConfig.REMEMBER_ME_SERVICES).loginFail(any(HttpServletRequest.class),
any(HttpServletResponse.class));
}
interface RememberMeServicesWithoutLogoutHandler extends RememberMeServices {
}
@ -156,23 +294,6 @@ public class NamespaceRememberMeTests {
}
@Test
public void rememberMeLoginWhenAuthenticationSuccessHandlerDeclaredThenUses() throws Exception {
AuthSuccessConfig.SUCCESS_HANDLER = mock(AuthenticationSuccessHandler.class);
this.spring.register(AuthSuccessConfig.class).autowire();
MvcResult result = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn();
verifyZeroInteractions(AuthSuccessConfig.SUCCESS_HANDLER);
Cookie rememberMe = result.getResponse().getCookie("remember-me");
assertThat(rememberMe).isNotNull();
this.mvc.perform(get("/somewhere").cookie(rememberMe));
verify(AuthSuccessConfig.SUCCESS_HANDLER).onAuthenticationSuccess(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(Authentication.class));
}
@Configuration
@EnableWebSecurity
static class AuthSuccessConfig extends UsersConfig {
@ -192,20 +313,6 @@ public class NamespaceRememberMeTests {
}
@Test
public void rememberMeLoginWhenKeyDeclaredThenMatchesNamespace() throws Exception {
this.spring.register(WithoutKeyConfig.class, KeyConfig.class, SecurityController.class).autowire();
Cookie withoutKey = this.mvc.perform(post("/without-key/login").with(rememberMeLogin()))
.andExpect(redirectedUrl("/")).andReturn().getResponse().getCookie("remember-me");
this.mvc.perform(get("/somewhere").cookie(withoutKey)).andExpect(status().isFound())
.andExpect(redirectedUrl("http://localhost/login"));
Cookie withKey = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("remember-me");
this.mvc.perform(get("/somewhere").cookie(withKey)).andExpect(status().isNotFound());
}
@Configuration
@EnableWebSecurity
@Order(0)
@ -245,21 +352,6 @@ public class NamespaceRememberMeTests {
}
// http/remember-me@services-alias is not supported use standard aliasing instead
// (i.e. @Bean("alias"))
// http/remember-me@data-source-ref is not supported directly. Instead use
// http/remember-me@token-repository-ref example
@Test
public void rememberMeLoginWhenDeclaredTokenRepositoryThenMatchesNamespace() throws Exception {
TokenRepositoryRefConfig.TOKEN_REPOSITORY = mock(PersistentTokenRepository.class);
this.spring.register(TokenRepositoryRefConfig.class).autowire();
this.mvc.perform(post("/login").with(rememberMeLogin()));
verify(TokenRepositoryRefConfig.TOKEN_REPOSITORY).createNewToken(any(PersistentRememberMeToken.class));
}
@Configuration
@EnableWebSecurity
static class TokenRepositoryRefConfig extends UsersConfig {
@ -282,15 +374,6 @@ public class NamespaceRememberMeTests {
}
@Test
public void rememberMeLoginWhenTokenValidityDeclaredThenMatchesNamespace() throws Exception {
this.spring.register(TokenValiditySecondsConfig.class).autowire();
Cookie expiredRememberMe = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("remember-me");
assertThat(expiredRememberMe).extracting(Cookie::getMaxAge).isEqualTo(314);
}
@Configuration
@EnableWebSecurity
static class TokenValiditySecondsConfig extends UsersConfig {
@ -311,24 +394,6 @@ public class NamespaceRememberMeTests {
}
@Test
public void rememberMeLoginWhenUsingDefaultsThenCookieMaxAgeMatchesNamespace() throws Exception {
this.spring.register(RememberMeConfig.class).autowire();
Cookie expiredRememberMe = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("remember-me");
assertThat(expiredRememberMe).extracting(Cookie::getMaxAge).isEqualTo(AbstractRememberMeServices.TWO_WEEKS_S);
}
@Test
public void rememberMeLoginWhenUsingSecureCookieThenMatchesNamespace() throws Exception {
this.spring.register(UseSecureCookieConfig.class).autowire();
Cookie secureCookie = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("remember-me");
assertThat(secureCookie).extracting(Cookie::getSecure).isEqualTo(true);
}
@Configuration
@EnableWebSecurity
static class UseSecureCookieConfig extends UsersConfig {
@ -346,24 +411,6 @@ public class NamespaceRememberMeTests {
}
@Test
public void rememberMeLoginWhenUsingDefaultsThenCookieSecurityMatchesNamespace() throws Exception {
this.spring.register(RememberMeConfig.class).autowire();
Cookie secureCookie = this.mvc.perform(post("/login").with(rememberMeLogin()).secure(true)).andReturn()
.getResponse().getCookie("remember-me");
assertThat(secureCookie).extracting(Cookie::getSecure).isEqualTo(true);
}
@Test
public void rememberMeLoginWhenParameterSpecifiedThenMatchesNamespace() throws Exception {
this.spring.register(RememberMeParameterConfig.class).autowire();
Cookie rememberMe = this.mvc.perform(post("/login").with(rememberMeLogin("rememberMe", true))).andReturn()
.getResponse().getCookie("remember-me");
assertThat(rememberMe).isNotNull();
}
@Configuration
@EnableWebSecurity
static class RememberMeParameterConfig extends UsersConfig {
@ -381,17 +428,6 @@ public class NamespaceRememberMeTests {
}
// SEC-2880
@Test
public void rememberMeLoginWhenCookieNameDeclaredThenMatchesNamespace() throws Exception {
this.spring.register(RememberMeCookieNameConfig.class).autowire();
Cookie rememberMe = this.mvc.perform(post("/login").with(rememberMeLogin())).andReturn().getResponse()
.getCookie("rememberMe");
assertThat(rememberMe).isNotNull();
}
@Configuration
@EnableWebSecurity
static class RememberMeCookieNameConfig extends UsersConfig {
@ -409,16 +445,6 @@ public class NamespaceRememberMeTests {
}
@Test
public void rememberMeLoginWhenGlobalUserDetailsServiceDeclaredThenMatchesNamespace() throws Exception {
DefaultsUserDetailsServiceWithDaoConfig.USERDETAILS_SERVICE = mock(UserDetailsService.class);
this.spring.register(DefaultsUserDetailsServiceWithDaoConfig.class).autowire();
this.mvc.perform(post("/login").with(rememberMeLogin()));
verify(DefaultsUserDetailsServiceWithDaoConfig.USERDETAILS_SERVICE).loadUserByUsername("user");
}
@EnableWebSecurity
@Configuration
static class DefaultsUserDetailsServiceWithDaoConfig extends WebSecurityConfigurerAdapter {
@ -445,19 +471,6 @@ public class NamespaceRememberMeTests {
}
@Test
public void rememberMeLoginWhenUserDetailsServiceDeclaredThenMatchesNamespace() throws Exception {
UserServiceRefConfig.USERDETAILS_SERVICE = mock(UserDetailsService.class);
this.spring.register(UserServiceRefConfig.class).autowire();
when(UserServiceRefConfig.USERDETAILS_SERVICE.loadUserByUsername("user"))
.thenReturn(new User("user", "password", AuthorityUtils.createAuthorityList("ROLE_USER")));
this.mvc.perform(post("/login").with(rememberMeLogin()));
verify(UserServiceRefConfig.USERDETAILS_SERVICE).loadUserByUsername("user");
}
@Configuration
@EnableWebSecurity
static class UserServiceRefConfig extends UsersConfig {
@ -477,20 +490,6 @@ public class NamespaceRememberMeTests {
}
static RequestPostProcessor rememberMeLogin() {
return rememberMeLogin("remember-me", true);
}
static RequestPostProcessor rememberMeLogin(String parameterName, boolean parameterValue) {
return request -> {
csrf().postProcessRequest(request);
request.setParameter("username", "user");
request.setParameter("password", "password");
request.setParameter(parameterName, String.valueOf(parameterValue));
return request;
};
}
static class UsersConfig extends WebSecurityConfigurerAdapter {
@Override

View File

@ -91,11 +91,6 @@ public class NamespaceSessionManagementTests {
assertThat(result.getRequest().getSession(false).getId()).isNotEqualTo(sessionId);
}
@EnableWebSecurity
static class SessionManagementConfig extends WebSecurityConfigurerAdapter {
}
@Test
public void authenticateWhenUsingInvalidSessionUrlThenMatchesNamespace() throws Exception {
this.spring.register(CustomSessionManagementConfig.class).autowire();
@ -157,6 +152,104 @@ public class NamespaceSessionManagementTests {
verify(sessionRegistry).registerNewSession(any(String.class), any(Object.class));
}
// gh-3371
@Test
public void authenticateWhenUsingCustomInvalidSessionStrategyThenMatchesNamespace() throws Exception {
this.spring.register(InvalidSessionStrategyConfig.class).autowire();
this.mvc.perform(get("/auth").with(request -> {
request.setRequestedSessionIdValid(false);
request.setRequestedSessionId("id");
return request;
})).andExpect(status().isOk());
verifyBean(InvalidSessionStrategy.class).onInvalidSessionDetected(any(HttpServletRequest.class),
any(HttpServletResponse.class));
}
@Test
public void authenticateWhenUsingCustomSessionAuthenticationStrategyThenMatchesNamespace() throws Exception {
this.spring.register(RefsSessionManagementConfig.class, BasicController.class, UserDetailsServiceConfig.class)
.autowire();
this.mvc.perform(get("/auth").with(httpBasic("user", "password"))).andExpect(status().isOk());
verifyBean(SessionAuthenticationStrategy.class).onAuthentication(any(Authentication.class),
any(HttpServletRequest.class), any(HttpServletResponse.class));
}
@Test
public void authenticateWhenNoSessionFixationProtectionThenMatchesNamespace() throws Exception {
this.spring
.register(SFPNoneSessionManagementConfig.class, BasicController.class, UserDetailsServiceConfig.class)
.autowire();
MockHttpSession givenSession = new MockHttpSession();
String givenSessionId = givenSession.getId();
MockHttpSession resultingSession = (MockHttpSession) this.mvc
.perform(get("/auth").session(givenSession).with(httpBasic("user", "password")))
.andExpect(status().isOk()).andReturn().getRequest().getSession(false);
assertThat(givenSessionId).isEqualTo(resultingSession.getId());
}
@Test
public void authenticateWhenMigrateSessionFixationProtectionThenMatchesNamespace() throws Exception {
this.spring.register(SFPMigrateSessionManagementConfig.class, BasicController.class,
UserDetailsServiceConfig.class).autowire();
MockHttpSession givenSession = new MockHttpSession();
String givenSessionId = givenSession.getId();
givenSession.setAttribute("name", "value");
MockHttpSession resultingSession = (MockHttpSession) this.mvc
.perform(get("/auth").session(givenSession).with(httpBasic("user", "password")))
.andExpect(status().isOk()).andReturn().getRequest().getSession(false);
assertThat(givenSessionId).isNotEqualTo(resultingSession.getId());
assertThat(resultingSession.getAttribute("name")).isEqualTo("value");
}
// SEC-2913
@Test
public void authenticateWhenUsingSessionFixationProtectionThenUsesNonNullEventPublisher() throws Exception {
this.spring.register(SFPPostProcessedConfig.class, UserDetailsServiceConfig.class).autowire();
this.mvc.perform(get("/auth").session(new MockHttpSession()).with(httpBasic("user", "password")))
.andExpect(status().isNotFound());
verifyBean(MockEventListener.class).onApplicationEvent(any(SessionFixationProtectionEvent.class));
}
@Test
public void authenticateWhenNewSessionFixationProtectionThenMatchesNamespace() throws Exception {
this.spring.register(SFPNewSessionSessionManagementConfig.class, UserDetailsServiceConfig.class).autowire();
MockHttpSession givenSession = new MockHttpSession();
String givenSessionId = givenSession.getId();
givenSession.setAttribute("name", "value");
MockHttpSession resultingSession = (MockHttpSession) this.mvc
.perform(get("/auth").session(givenSession).with(httpBasic("user", "password")))
.andExpect(status().isNotFound()).andReturn().getRequest().getSession(false);
assertThat(givenSessionId).isNotEqualTo(resultingSession.getId());
assertThat(resultingSession.getAttribute("name")).isNull();
}
private <T> T verifyBean(Class<T> clazz) {
return verify(this.spring.getContext().getBean(clazz));
}
private static SessionResultMatcher session() {
return new SessionResultMatcher();
}
@EnableWebSecurity
static class SessionManagementConfig extends WebSecurityConfigurerAdapter {
}
@EnableWebSecurity
static class CustomSessionManagementConfig extends WebSecurityConfigurerAdapter {
@ -188,21 +281,6 @@ public class NamespaceSessionManagementTests {
}
// gh-3371
@Test
public void authenticateWhenUsingCustomInvalidSessionStrategyThenMatchesNamespace() throws Exception {
this.spring.register(InvalidSessionStrategyConfig.class).autowire();
this.mvc.perform(get("/auth").with(request -> {
request.setRequestedSessionIdValid(false);
request.setRequestedSessionId("id");
return request;
})).andExpect(status().isOk());
verifyBean(InvalidSessionStrategy.class).onInvalidSessionDetected(any(HttpServletRequest.class),
any(HttpServletResponse.class));
}
@EnableWebSecurity
static class InvalidSessionStrategyConfig extends WebSecurityConfigurerAdapter {
@ -224,17 +302,6 @@ public class NamespaceSessionManagementTests {
}
@Test
public void authenticateWhenUsingCustomSessionAuthenticationStrategyThenMatchesNamespace() throws Exception {
this.spring.register(RefsSessionManagementConfig.class, BasicController.class, UserDetailsServiceConfig.class)
.autowire();
this.mvc.perform(get("/auth").with(httpBasic("user", "password"))).andExpect(status().isOk());
verifyBean(SessionAuthenticationStrategy.class).onAuthentication(any(Authentication.class),
any(HttpServletRequest.class), any(HttpServletResponse.class));
}
@EnableWebSecurity
static class RefsSessionManagementConfig extends WebSecurityConfigurerAdapter {
@ -258,21 +325,6 @@ public class NamespaceSessionManagementTests {
}
@Test
public void authenticateWhenNoSessionFixationProtectionThenMatchesNamespace() throws Exception {
this.spring
.register(SFPNoneSessionManagementConfig.class, BasicController.class, UserDetailsServiceConfig.class)
.autowire();
MockHttpSession givenSession = new MockHttpSession();
String givenSessionId = givenSession.getId();
MockHttpSession resultingSession = (MockHttpSession) this.mvc
.perform(get("/auth").session(givenSession).with(httpBasic("user", "password")))
.andExpect(status().isOk()).andReturn().getRequest().getSession(false);
assertThat(givenSessionId).isEqualTo(resultingSession.getId());
}
@EnableWebSecurity
static class SFPNoneSessionManagementConfig extends WebSecurityConfigurerAdapter {
@ -289,23 +341,6 @@ public class NamespaceSessionManagementTests {
}
@Test
public void authenticateWhenMigrateSessionFixationProtectionThenMatchesNamespace() throws Exception {
this.spring.register(SFPMigrateSessionManagementConfig.class, BasicController.class,
UserDetailsServiceConfig.class).autowire();
MockHttpSession givenSession = new MockHttpSession();
String givenSessionId = givenSession.getId();
givenSession.setAttribute("name", "value");
MockHttpSession resultingSession = (MockHttpSession) this.mvc
.perform(get("/auth").session(givenSession).with(httpBasic("user", "password")))
.andExpect(status().isOk()).andReturn().getRequest().getSession(false);
assertThat(givenSessionId).isNotEqualTo(resultingSession.getId());
assertThat(resultingSession.getAttribute("name")).isEqualTo("value");
}
@EnableWebSecurity
static class SFPMigrateSessionManagementConfig extends WebSecurityConfigurerAdapter {
@ -321,17 +356,6 @@ public class NamespaceSessionManagementTests {
}
// SEC-2913
@Test
public void authenticateWhenUsingSessionFixationProtectionThenUsesNonNullEventPublisher() throws Exception {
this.spring.register(SFPPostProcessedConfig.class, UserDetailsServiceConfig.class).autowire();
this.mvc.perform(get("/auth").session(new MockHttpSession()).with(httpBasic("user", "password")))
.andExpect(status().isNotFound());
verifyBean(MockEventListener.class).onApplicationEvent(any(SessionFixationProtectionEvent.class));
}
@EnableWebSecurity
static class SFPPostProcessedConfig extends WebSecurityConfigurerAdapter {
@ -352,22 +376,6 @@ public class NamespaceSessionManagementTests {
}
@Test
public void authenticateWhenNewSessionFixationProtectionThenMatchesNamespace() throws Exception {
this.spring.register(SFPNewSessionSessionManagementConfig.class, UserDetailsServiceConfig.class).autowire();
MockHttpSession givenSession = new MockHttpSession();
String givenSessionId = givenSession.getId();
givenSession.setAttribute("name", "value");
MockHttpSession resultingSession = (MockHttpSession) this.mvc
.perform(get("/auth").session(givenSession).with(httpBasic("user", "password")))
.andExpect(status().isNotFound()).andReturn().getRequest().getSession(false);
assertThat(givenSessionId).isNotEqualTo(resultingSession.getId());
assertThat(resultingSession.getAttribute("name")).isNull();
}
@EnableWebSecurity
static class SFPNewSessionSessionManagementConfig extends WebSecurityConfigurerAdapter {
@ -384,10 +392,6 @@ public class NamespaceSessionManagementTests {
}
private <T> T verifyBean(Class<T> clazz) {
return verify(this.spring.getContext().getBean(clazz));
}
static class MockEventListener implements ApplicationListener<SessionFixationProtectionEvent> {
List<SessionFixationProtectionEvent> events = new ArrayList<>();
@ -431,10 +435,6 @@ public class NamespaceSessionManagementTests {
}
private static SessionResultMatcher session() {
return new SessionResultMatcher();
}
private static class SessionResultMatcher implements ResultMatcher {
private String id;

View File

@ -55,6 +55,13 @@ public class PermitAllSupportTests {
this.mvc.perform(get("/app/abc").with(csrf()).contextPath("/app")).andExpect(status().isFound());
}
@Test
public void configureWhenNotAuthorizeRequestsThenException() {
assertThatCode(() -> this.spring.register(NoAuthorizedUrlsConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("permitAll only works with HttpSecurity.authorizeRequests");
}
@EnableWebSecurity
static class PermitAllConfig extends WebSecurityConfigurerAdapter {
@ -73,13 +80,6 @@ public class PermitAllSupportTests {
}
@Test
public void configureWhenNotAuthorizeRequestsThenException() {
assertThatCode(() -> this.spring.register(NoAuthorizedUrlsConfig.class).autowire())
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("permitAll only works with HttpSecurity.authorizeRequests");
}
@EnableWebSecurity
static class NoAuthorizedUrlsConfig extends WebSecurityConfigurerAdapter {

View File

@ -50,6 +50,20 @@ public class PortMapperConfigurerTests {
this.mockMvc.perform(get("http://localhost:543")).andExpect(redirectedUrl("https://localhost:123"));
}
@Test
public void requestWhenPortMapperHttpMapsToInLambdaThenRedirectsToHttpsPort() throws Exception {
this.spring.register(HttpMapsToInLambdaConfig.class).autowire();
this.mockMvc.perform(get("http://localhost:543")).andExpect(redirectedUrl("https://localhost:123"));
}
@Test
public void requestWhenCustomPortMapperInLambdaThenRedirectsToHttpsPort() throws Exception {
this.spring.register(CustomPortMapperInLambdaConfig.class).autowire();
this.mockMvc.perform(get("http://localhost:543")).andExpect(redirectedUrl("https://localhost:123"));
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
@ -69,13 +83,6 @@ public class PortMapperConfigurerTests {
}
@Test
public void requestWhenPortMapperHttpMapsToInLambdaThenRedirectsToHttpsPort() throws Exception {
this.spring.register(HttpMapsToInLambdaConfig.class).autowire();
this.mockMvc.perform(get("http://localhost:543")).andExpect(redirectedUrl("https://localhost:123"));
}
@EnableWebSecurity
static class HttpMapsToInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -96,13 +103,6 @@ public class PortMapperConfigurerTests {
}
@Test
public void requestWhenCustomPortMapperInLambdaThenRedirectsToHttpsPort() throws Exception {
this.spring.register(CustomPortMapperInLambdaConfig.class).autowire();
this.mockMvc.perform(get("http://localhost:543")).andExpect(redirectedUrl("https://localhost:123"));
}
@EnableWebSecurity
static class CustomPortMapperInLambdaConfig extends WebSecurityConfigurerAdapter {

View File

@ -86,35 +86,6 @@ public class RememberMeConfigurerTests {
.param("remember-me", "true").with(csrf()))).hasMessageContaining("UserDetailsService is required");
}
@EnableWebSecurity
static class NullUserDetailsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.and()
.rememberMe();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
User user = (User) PasswordEncodedUser.user();
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(new InMemoryUserDetailsManager(Collections.singletonList(user)));
// @formatter:off
auth
.authenticationProvider(provider);
// @formatter:on
}
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnRememberMeAuthenticationFilter() {
this.spring.register(ObjectPostProcessorConfig.class).autowire();
@ -122,44 +93,6 @@ public class RememberMeConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(RememberMeAuthenticationFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.rememberMe()
.userDetailsService(new AuthenticationManagerBuilder(objectPostProcessor).getDefaultUserDetailsService());
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@Test
public void rememberMeWhenInvokedTwiceThenUsesOriginalUserDetailsService() throws Exception {
when(DuplicateDoesNotOverrideConfig.userDetailsService.loadUserByUsername(anyString()))
@ -171,40 +104,6 @@ public class RememberMeConfigurerTests {
verify(DuplicateDoesNotOverrideConfig.userDetailsService).loadUserByUsername("user");
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
static UserDetailsService userDetailsService = mock(UserDetailsService.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.rememberMe()
.userDetailsService(userDetailsService)
.and()
.rememberMe();
// @formatter:on
}
@Override
@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(
// @formatter:off
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
// @formatter:on
);
}
}
@Test
public void loginWhenRememberMeTrueThenRespondsWithRememberMeCookie() throws Exception {
this.spring.register(RememberMeConfig.class).autowire();
@ -255,6 +154,152 @@ public class RememberMeConfigurerTests {
.andExpect(redirectedUrl("http://localhost/login"));
}
@Test
public void loginWhenRememberMeConfiguredInLambdaThenRespondsWithRememberMeCookie() throws Exception {
this.spring.register(RememberMeInLambdaConfig.class).autowire();
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password")
.param("remember-me", "true")).andExpect(cookie().exists("remember-me"));
}
@Test
public void loginWhenRememberMeTrueAndCookieDomainThenRememberMeCookieHasDomain() throws Exception {
this.spring.register(RememberMeCookieDomainConfig.class).autowire();
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password")
.param("remember-me", "true")).andExpect(cookie().exists("remember-me"))
.andExpect(cookie().domain("remember-me", "spring.io"));
}
@Test
public void loginWhenRememberMeTrueAndCookieDomainInLambdaThenRememberMeCookieHasDomain() throws Exception {
this.spring.register(RememberMeCookieDomainInLambdaConfig.class).autowire();
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password")
.param("remember-me", "true")).andExpect(cookie().exists("remember-me"))
.andExpect(cookie().domain("remember-me", "spring.io"));
}
@Test
public void configureWhenRememberMeCookieNameAndRememberMeServicesThenException() {
assertThatThrownBy(() -> this.spring.register(RememberMeCookieNameAndRememberMeServicesConfig.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Can not set rememberMeCookieName and custom rememberMeServices.");
}
@Test
public void getWhenRememberMeCookieAndNoKeyConfiguredThenKeyFromRememberMeServicesIsUsed() throws Exception {
this.spring.register(FallbackRememberMeKeyConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(post("/login").with(csrf()).param("username", "user")
.param("password", "password").param("remember-me", "true")).andReturn();
Cookie rememberMeCookie = mvcResult.getResponse().getCookie("remember-me");
this.mvc.perform(get("/abc").cookie(rememberMeCookie)).andExpect(authenticated()
.withAuthentication(auth -> assertThat(auth).isInstanceOf(RememberMeAuthenticationToken.class)));
}
@EnableWebSecurity
static class NullUserDetailsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.formLogin()
.and()
.rememberMe();
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) {
User user = (User) PasswordEncodedUser.user();
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(new InMemoryUserDetailsManager(Collections.singletonList(user)));
// @formatter:off
auth
.authenticationProvider(provider);
// @formatter:on
}
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.rememberMe()
.userDetailsService(new AuthenticationManagerBuilder(objectPostProcessor).getDefaultUserDetailsService());
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
static UserDetailsService userDetailsService = mock(UserDetailsService.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.rememberMe()
.userDetailsService(userDetailsService)
.and()
.rememberMe();
// @formatter:on
}
@Override
@Bean
public UserDetailsService userDetailsService() {
return new InMemoryUserDetailsManager(
// @formatter:off
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
// @formatter:on
);
}
}
@EnableWebSecurity
static class RememberMeConfig extends WebSecurityConfigurerAdapter {
@ -282,14 +327,6 @@ public class RememberMeConfigurerTests {
}
@Test
public void loginWhenRememberMeConfiguredInLambdaThenRespondsWithRememberMeCookie() throws Exception {
this.spring.register(RememberMeInLambdaConfig.class).autowire();
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password")
.param("remember-me", "true")).andExpect(cookie().exists("remember-me"));
}
@EnableWebSecurity
static class RememberMeInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -317,15 +354,6 @@ public class RememberMeConfigurerTests {
}
@Test
public void loginWhenRememberMeTrueAndCookieDomainThenRememberMeCookieHasDomain() throws Exception {
this.spring.register(RememberMeCookieDomainConfig.class).autowire();
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password")
.param("remember-me", "true")).andExpect(cookie().exists("remember-me"))
.andExpect(cookie().domain("remember-me", "spring.io"));
}
@EnableWebSecurity
static class RememberMeCookieDomainConfig extends WebSecurityConfigurerAdapter {
@ -354,15 +382,6 @@ public class RememberMeConfigurerTests {
}
@Test
public void loginWhenRememberMeTrueAndCookieDomainInLambdaThenRememberMeCookieHasDomain() throws Exception {
this.spring.register(RememberMeCookieDomainInLambdaConfig.class).autowire();
this.mvc.perform(post("/login").with(csrf()).param("username", "user").param("password", "password")
.param("remember-me", "true")).andExpect(cookie().exists("remember-me"))
.andExpect(cookie().domain("remember-me", "spring.io"));
}
@EnableWebSecurity
static class RememberMeCookieDomainInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -393,13 +412,6 @@ public class RememberMeConfigurerTests {
}
@Test
public void configureWhenRememberMeCookieNameAndRememberMeServicesThenException() {
assertThatThrownBy(() -> this.spring.register(RememberMeCookieNameAndRememberMeServicesConfig.class).autowire())
.isInstanceOf(BeanCreationException.class).hasRootCauseInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Can not set rememberMeCookieName and custom rememberMeServices.");
}
@EnableWebSecurity
static class RememberMeCookieNameAndRememberMeServicesConfig extends WebSecurityConfigurerAdapter {
@ -432,18 +444,6 @@ public class RememberMeConfigurerTests {
}
@Test
public void getWhenRememberMeCookieAndNoKeyConfiguredThenKeyFromRememberMeServicesIsUsed() throws Exception {
this.spring.register(FallbackRememberMeKeyConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(post("/login").with(csrf()).param("username", "user")
.param("password", "password").param("remember-me", "true")).andReturn();
Cookie rememberMeCookie = mvcResult.getResponse().getCookie("remember-me");
this.mvc.perform(get("/abc").cookie(rememberMeCookie)).andExpect(authenticated()
.withAuthentication(auth -> assertThat(auth).isInstanceOf(RememberMeAuthenticationToken.class)));
}
@EnableWebSecurity
static class FallbackRememberMeKeyConfig extends RememberMeConfig {

View File

@ -72,35 +72,6 @@ public class RequestCacheConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(RequestCacheAwareFilter.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.requestCache();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@Test
public void getWhenInvokingExceptionHandlingTwiceThenOriginalEntryPointUsed() throws Exception {
this.spring.register(InvokeTwiceDoesNotOverrideConfig.class).autowire();
@ -111,24 +82,6 @@ public class RequestCacheConfigurerTests {
any(HttpServletResponse.class));
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
static RequestCache requestCache = mock(RequestCache.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.requestCache()
.requestCache(requestCache)
.and()
.requestCache();
// @formatter:on
}
}
@Test
public void getWhenBookmarkedUrlIsFaviconIcoThenPostAuthenticationRedirectsToRoot() throws Exception {
this.spring.register(RequestCacheDefaultsConfig.class, DefaultSecurityConfig.class).autowire();
@ -242,22 +195,6 @@ public class RequestCacheConfigurerTests {
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("http://localhost/messages"));
}
@EnableWebSecurity
static class RequestCacheDefaultsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
// @formatter:on
}
}
// gh-6102
@Test
public void getWhenRequestCacheIsDisabledThenExceptionTranslationFilterDoesNotStoreRequest() throws Exception {
@ -282,6 +219,101 @@ public class RequestCacheConfigurerTests {
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/"));
}
@Test
public void getWhenRequestCacheIsDisabledInLambdaThenExceptionTranslationFilterDoesNotStoreRequest()
throws Exception {
this.spring.register(RequestCacheDisabledInLambdaConfig.class, DefaultSecurityConfig.class).autowire();
MockHttpSession session = (MockHttpSession) this.mvc.perform(get("/bob")).andReturn().getRequest().getSession();
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/"));
}
@Test
public void getWhenRequestCacheInLambdaThenRedirectedToCachedPage() throws Exception {
this.spring.register(RequestCacheInLambdaConfig.class, DefaultSecurityConfig.class).autowire();
MockHttpSession session = (MockHttpSession) this.mvc.perform(get("/bob")).andReturn().getRequest().getSession();
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("http://localhost/bob"));
}
@Test
public void getWhenCustomRequestCacheInLambdaThenCustomRequestCacheUsed() throws Exception {
this.spring.register(CustomRequestCacheInLambdaConfig.class, DefaultSecurityConfig.class).autowire();
MockHttpSession session = (MockHttpSession) this.mvc.perform(get("/bob")).andReturn().getRequest().getSession();
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/"));
}
private static RequestBuilder formLogin(MockHttpSession session) {
return post("/login").param("username", "user").param("password", "password").session(session).with(csrf());
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.requestCache();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
static RequestCache requestCache = mock(RequestCache.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.requestCache()
.requestCache(requestCache)
.and()
.requestCache();
// @formatter:on
}
}
@EnableWebSecurity
static class RequestCacheDefaultsConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
// @formatter:on
}
}
@EnableWebSecurity
static class RequestCacheDisabledConfig extends WebSecurityConfigurerAdapter {
@ -293,16 +325,6 @@ public class RequestCacheConfigurerTests {
}
@Test
public void getWhenRequestCacheIsDisabledInLambdaThenExceptionTranslationFilterDoesNotStoreRequest()
throws Exception {
this.spring.register(RequestCacheDisabledInLambdaConfig.class, DefaultSecurityConfig.class).autowire();
MockHttpSession session = (MockHttpSession) this.mvc.perform(get("/bob")).andReturn().getRequest().getSession();
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/"));
}
@EnableWebSecurity
static class RequestCacheDisabledInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -321,15 +343,6 @@ public class RequestCacheConfigurerTests {
}
@Test
public void getWhenRequestCacheInLambdaThenRedirectedToCachedPage() throws Exception {
this.spring.register(RequestCacheInLambdaConfig.class, DefaultSecurityConfig.class).autowire();
MockHttpSession session = (MockHttpSession) this.mvc.perform(get("/bob")).andReturn().getRequest().getSession();
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("http://localhost/bob"));
}
@EnableWebSecurity
static class RequestCacheInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -348,15 +361,6 @@ public class RequestCacheConfigurerTests {
}
@Test
public void getWhenCustomRequestCacheInLambdaThenCustomRequestCacheUsed() throws Exception {
this.spring.register(CustomRequestCacheInLambdaConfig.class, DefaultSecurityConfig.class).autowire();
MockHttpSession session = (MockHttpSession) this.mvc.perform(get("/bob")).andReturn().getRequest().getSession();
this.mvc.perform(formLogin(session)).andExpect(redirectedUrl("/"));
}
@EnableWebSecurity
static class CustomRequestCacheInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -395,8 +399,4 @@ public class RequestCacheConfigurerTests {
}
private static RequestBuilder formLogin(MockHttpSession session) {
return post("/login").param("username", "user").param("password", "password").session(session).with(csrf());
}
}

View File

@ -52,6 +52,14 @@ public class RequestMatcherConfigurerTests {
this.mvc.perform(get("/api/abc")).andExpect(status().isForbidden());
}
@Test
public void authorizeRequestsWhenInvokedMultipleTimesInLambdaThenChainsPaths() throws Exception {
this.spring.register(AuthorizeRequestInLambdaConfig.class).autowire();
this.mvc.perform(get("/oauth/abc")).andExpect(status().isForbidden());
this.mvc.perform(get("/api/abc")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class Sec2908Config extends WebSecurityConfigurerAdapter {
@ -72,14 +80,6 @@ public class RequestMatcherConfigurerTests {
}
@Test
public void authorizeRequestsWhenInvokedMultipleTimesInLambdaThenChainsPaths() throws Exception {
this.spring.register(AuthorizeRequestInLambdaConfig.class).autowire();
this.mvc.perform(get("/oauth/abc")).andExpect(status().isForbidden());
this.mvc.perform(get("/api/abc")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class AuthorizeRequestInLambdaConfig extends WebSecurityConfigurerAdapter {

View File

@ -71,6 +71,51 @@ public class SecurityContextConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(SecurityContextPersistenceFilter.class));
}
@Test
public void securityContextWhenInvokedTwiceThenUsesOriginalSecurityContextRepository() throws Exception {
this.spring.register(DuplicateDoesNotOverrideConfig.class).autowire();
when(DuplicateDoesNotOverrideConfig.SCR.loadContext(any())).thenReturn(mock(SecurityContext.class));
this.mvc.perform(get("/"));
verify(DuplicateDoesNotOverrideConfig.SCR).loadContext(any(HttpRequestResponseHolder.class));
}
// SEC-2932
@Test
public void securityContextWhenSecurityContextRepositoryNotConfiguredThenDoesNotThrowException() throws Exception {
this.spring.register(SecurityContextRepositoryDefaultsSecurityContextRepositoryConfig.class).autowire();
this.mvc.perform(get("/"));
}
@Test
public void requestWhenSecurityContextWithDefaultsInLambdaThenSessionIsCreated() throws Exception {
this.spring.register(SecurityContextWithDefaultsInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(formLogin()).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNotNull();
}
@Test
public void requestWhenSecurityContextDisabledInLambdaThenContextNotSavedInSession() throws Exception {
this.spring.register(SecurityContextDisabledInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(formLogin()).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@Test
public void requestWhenNullSecurityContextRepositoryInLambdaThenContextNotSavedInSession() throws Exception {
this.spring.register(NullSecurityContextRepositoryInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(formLogin()).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
@ -100,16 +145,6 @@ public class SecurityContextConfigurerTests {
}
@Test
public void securityContextWhenInvokedTwiceThenUsesOriginalSecurityContextRepository() throws Exception {
this.spring.register(DuplicateDoesNotOverrideConfig.class).autowire();
when(DuplicateDoesNotOverrideConfig.SCR.loadContext(any())).thenReturn(mock(SecurityContext.class));
this.mvc.perform(get("/"));
verify(DuplicateDoesNotOverrideConfig.SCR).loadContext(any(HttpRequestResponseHolder.class));
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@ -128,14 +163,6 @@ public class SecurityContextConfigurerTests {
}
// SEC-2932
@Test
public void securityContextWhenSecurityContextRepositoryNotConfiguredThenDoesNotThrowException() throws Exception {
this.spring.register(SecurityContextRepositoryDefaultsSecurityContextRepositoryConfig.class).autowire();
this.mvc.perform(get("/"));
}
@Configuration
@EnableWebSecurity
static class SecurityContextRepositoryDefaultsSecurityContextRepositoryConfig extends WebSecurityConfigurerAdapter {
@ -171,15 +198,6 @@ public class SecurityContextConfigurerTests {
}
@Test
public void requestWhenSecurityContextWithDefaultsInLambdaThenSessionIsCreated() throws Exception {
this.spring.register(SecurityContextWithDefaultsInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(formLogin()).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNotNull();
}
@EnableWebSecurity
static class SecurityContextWithDefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -203,15 +221,6 @@ public class SecurityContextConfigurerTests {
}
@Test
public void requestWhenSecurityContextDisabledInLambdaThenContextNotSavedInSession() throws Exception {
this.spring.register(SecurityContextDisabledInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(formLogin()).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@EnableWebSecurity
static class SecurityContextDisabledInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -235,15 +244,6 @@ public class SecurityContextConfigurerTests {
}
@Test
public void requestWhenNullSecurityContextRepositoryInLambdaThenContextNotSavedInSession() throws Exception {
this.spring.register(NullSecurityContextRepositoryInLambdaConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(formLogin()).andReturn();
HttpSession session = mvcResult.getRequest().getSession(false);
assertThat(session).isNull();
}
@EnableWebSecurity
static class NullSecurityContextRepositoryInLambdaConfig extends WebSecurityConfigurerAdapter {

View File

@ -93,6 +93,127 @@ public class ServletApiConfigurerTests {
.postProcess(any(SecurityContextHolderAwareRequestFilter.class));
}
// SEC-2215
@Test
public void configureWhenUsingDefaultsThenAuthenticationManagerIsNotNull() {
this.spring.register(ServletApiConfig.class).autowire();
assertThat(this.spring.getContext().getBean("customAuthenticationManager")).isNotNull();
}
@Test
public void configureWhenUsingDefaultsThenAuthenticationEntryPointIsLogin() throws Exception {
this.spring.register(ServletApiConfig.class).autowire();
this.mvc.perform(formLogin()).andExpect(status().isFound());
}
// SEC-2926
@Test
public void configureWhenUsingDefaultsThenRolePrefixIsSet() throws Exception {
this.spring.register(ServletApiConfig.class, AdminController.class).autowire();
this.mvc.perform(
get("/admin").with(authentication(new TestingAuthenticationToken("user", "pass", "ROLE_ADMIN"))))
.andExpect(status().isOk());
}
@Test
public void requestWhenCustomAuthenticationEntryPointThenEntryPointUsed() throws Exception {
this.spring.register(CustomEntryPointConfig.class).autowire();
this.mvc.perform(get("/"));
verify(CustomEntryPointConfig.ENTRYPOINT).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@Test
public void servletApiWhenInvokedTwiceThenUsesOriginalRole() throws Exception {
this.spring.register(DuplicateInvocationsDoesNotOverrideConfig.class, AdminController.class).autowire();
this.mvc.perform(
get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("PERMISSION_ADMIN"))))
.andExpect(status().isOk());
this.mvc.perform(get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("ROLE_ADMIN"))))
.andExpect(status().isForbidden());
}
@Test
public void configureWhenSharedObjectTrustResolverThenTrustResolverUsed() throws Exception {
this.spring.register(SharedTrustResolverConfig.class).autowire();
this.mvc.perform(get("/"));
verify(SharedTrustResolverConfig.TR, atLeastOnce()).isAnonymous(any());
}
@Test
public void requestWhenServletApiWithDefaultsInLambdaThenUsesDefaultRolePrefix() throws Exception {
this.spring.register(ServletApiWithDefaultsInLambdaConfig.class, AdminController.class).autowire();
this.mvc.perform(get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("ROLE_ADMIN"))))
.andExpect(status().isOk());
}
@Test
public void requestWhenRolePrefixInLambdaThenUsesCustomRolePrefix() throws Exception {
this.spring.register(RolePrefixInLambdaConfig.class, AdminController.class).autowire();
this.mvc.perform(
get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("PERMISSION_ADMIN"))))
.andExpect(status().isOk());
this.mvc.perform(get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("ROLE_ADMIN"))))
.andExpect(status().isForbidden());
}
@Test
public void checkSecurityContextAwareAndLogoutFilterHasSameSizeAndHasLogoutSuccessEventPublishingLogoutHandler() {
this.spring.register(ServletApiWithLogoutConfig.class);
SecurityContextHolderAwareRequestFilter scaFilter = getFilter(SecurityContextHolderAwareRequestFilter.class);
LogoutFilter logoutFilter = getFilter(LogoutFilter.class);
LogoutHandler lfLogoutHandler = getFieldValue(logoutFilter, "handler");
assertThat(lfLogoutHandler).isInstanceOf(CompositeLogoutHandler.class);
List<LogoutHandler> scaLogoutHandlers = getFieldValue(scaFilter, "logoutHandlers");
List<LogoutHandler> lfLogoutHandlers = getFieldValue(lfLogoutHandler, "logoutHandlers");
assertThat(scaLogoutHandlers).hasSameSizeAs(lfLogoutHandlers);
assertThat(scaLogoutHandlers).hasAtLeastOneElementOfType(LogoutSuccessEventPublishingLogoutHandler.class);
assertThat(lfLogoutHandlers).hasAtLeastOneElementOfType(LogoutSuccessEventPublishingLogoutHandler.class);
}
@Test
public void logoutServletApiWhenCsrfDisabled() throws Exception {
ConfigurableWebApplicationContext context = this.spring.register(CsrfDisabledConfig.class).getContext();
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
MvcResult mvcResult = mockMvc.perform(get("/")).andReturn();
assertThat(mvcResult.getRequest().getSession(false)).isNull();
}
private <T extends Filter> T getFilter(Class<T> filterClass) {
return (T) getFilters().stream().filter(filterClass::isInstance).findFirst().orElse(null);
}
private List<Filter> getFilters() {
FilterChainProxy proxy = this.spring.getContext().getBean(FilterChainProxy.class);
return proxy.getFilters("/");
}
private <T> T getFieldValue(Object target, String fieldName) {
try {
return (T) FieldUtils.getFieldValue(target, fieldName);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
@ -122,31 +243,6 @@ public class ServletApiConfigurerTests {
}
// SEC-2215
@Test
public void configureWhenUsingDefaultsThenAuthenticationManagerIsNotNull() {
this.spring.register(ServletApiConfig.class).autowire();
assertThat(this.spring.getContext().getBean("customAuthenticationManager")).isNotNull();
}
@Test
public void configureWhenUsingDefaultsThenAuthenticationEntryPointIsLogin() throws Exception {
this.spring.register(ServletApiConfig.class).autowire();
this.mvc.perform(formLogin()).andExpect(status().isFound());
}
// SEC-2926
@Test
public void configureWhenUsingDefaultsThenRolePrefixIsSet() throws Exception {
this.spring.register(ServletApiConfig.class, AdminController.class).autowire();
this.mvc.perform(
get("/admin").with(authentication(new TestingAuthenticationToken("user", "pass", "ROLE_ADMIN"))))
.andExpect(status().isOk());
}
@EnableWebSecurity
static class ServletApiConfig extends WebSecurityConfigurerAdapter {
@ -166,16 +262,6 @@ public class ServletApiConfigurerTests {
}
@Test
public void requestWhenCustomAuthenticationEntryPointThenEntryPointUsed() throws Exception {
this.spring.register(CustomEntryPointConfig.class).autowire();
this.mvc.perform(get("/"));
verify(CustomEntryPointConfig.ENTRYPOINT).commence(any(HttpServletRequest.class),
any(HttpServletResponse.class), any(AuthenticationException.class));
}
@EnableWebSecurity
static class CustomEntryPointConfig extends WebSecurityConfigurerAdapter {
@ -206,18 +292,6 @@ public class ServletApiConfigurerTests {
}
@Test
public void servletApiWhenInvokedTwiceThenUsesOriginalRole() throws Exception {
this.spring.register(DuplicateInvocationsDoesNotOverrideConfig.class, AdminController.class).autowire();
this.mvc.perform(
get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("PERMISSION_ADMIN"))))
.andExpect(status().isOk());
this.mvc.perform(get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("ROLE_ADMIN"))))
.andExpect(status().isForbidden());
}
@EnableWebSecurity
static class DuplicateInvocationsDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@ -234,15 +308,6 @@ public class ServletApiConfigurerTests {
}
@Test
public void configureWhenSharedObjectTrustResolverThenTrustResolverUsed() throws Exception {
this.spring.register(SharedTrustResolverConfig.class).autowire();
this.mvc.perform(get("/"));
verify(SharedTrustResolverConfig.TR, atLeastOnce()).isAnonymous(any());
}
@EnableWebSecurity
static class SharedTrustResolverConfig extends WebSecurityConfigurerAdapter {
@ -258,14 +323,6 @@ public class ServletApiConfigurerTests {
}
@Test
public void requestWhenServletApiWithDefaultsInLambdaThenUsesDefaultRolePrefix() throws Exception {
this.spring.register(ServletApiWithDefaultsInLambdaConfig.class, AdminController.class).autowire();
this.mvc.perform(get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("ROLE_ADMIN"))))
.andExpect(status().isOk());
}
@EnableWebSecurity
static class ServletApiWithDefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -279,18 +336,6 @@ public class ServletApiConfigurerTests {
}
@Test
public void requestWhenRolePrefixInLambdaThenUsesCustomRolePrefix() throws Exception {
this.spring.register(RolePrefixInLambdaConfig.class, AdminController.class).autowire();
this.mvc.perform(
get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("PERMISSION_ADMIN"))))
.andExpect(status().isOk());
this.mvc.perform(get("/admin").with(user("user").authorities(AuthorityUtils.createAuthorityList("ROLE_ADMIN"))))
.andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RolePrefixInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -319,25 +364,6 @@ public class ServletApiConfigurerTests {
}
@Test
public void checkSecurityContextAwareAndLogoutFilterHasSameSizeAndHasLogoutSuccessEventPublishingLogoutHandler() {
this.spring.register(ServletApiWithLogoutConfig.class);
SecurityContextHolderAwareRequestFilter scaFilter = getFilter(SecurityContextHolderAwareRequestFilter.class);
LogoutFilter logoutFilter = getFilter(LogoutFilter.class);
LogoutHandler lfLogoutHandler = getFieldValue(logoutFilter, "handler");
assertThat(lfLogoutHandler).isInstanceOf(CompositeLogoutHandler.class);
List<LogoutHandler> scaLogoutHandlers = getFieldValue(scaFilter, "logoutHandlers");
List<LogoutHandler> lfLogoutHandlers = getFieldValue(lfLogoutHandler, "logoutHandlers");
assertThat(scaLogoutHandlers).hasSameSizeAs(lfLogoutHandlers);
assertThat(scaLogoutHandlers).hasAtLeastOneElementOfType(LogoutSuccessEventPublishingLogoutHandler.class);
assertThat(lfLogoutHandlers).hasAtLeastOneElementOfType(LogoutSuccessEventPublishingLogoutHandler.class);
}
@EnableWebSecurity
static class ServletApiWithLogoutConfig extends WebSecurityConfigurerAdapter {
@ -352,14 +378,6 @@ public class ServletApiConfigurerTests {
}
@Test
public void logoutServletApiWhenCsrfDisabled() throws Exception {
ConfigurableWebApplicationContext context = this.spring.register(CsrfDisabledConfig.class).getContext();
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
MvcResult mvcResult = mockMvc.perform(get("/")).andReturn();
assertThat(mvcResult.getRequest().getSession(false)).isNull();
}
@Configuration
@EnableWebSecurity
static class CsrfDisabledConfig extends WebSecurityConfigurerAdapter {
@ -386,22 +404,4 @@ public class ServletApiConfigurerTests {
}
private <T extends Filter> T getFilter(Class<T> filterClass) {
return (T) getFilters().stream().filter(filterClass::isInstance).findFirst().orElse(null);
}
private List<Filter> getFilters() {
FilterChainProxy proxy = this.spring.getContext().getBean(FilterChainProxy.class);
return proxy.getFilters("/");
}
private <T> T getFieldValue(Object target, String fieldName) {
try {
return (T) FieldUtils.getFieldValue(target, fieldName);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -103,6 +103,24 @@ public class SessionManagementConfigurerServlet31Tests {
assertThat(request.getSession().getAttribute("attribute1")).isEqualTo("value1");
}
private void loadConfig(Class<?>... classes) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(classes);
context.refresh();
this.context = context;
this.springSecurityFilterChain = this.context.getBean("springSecurityFilterChain", Filter.class);
}
private void login(Authentication auth) {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(this.request, this.response);
repo.loadContext(requestResponseHolder);
SecurityContextImpl securityContextImpl = new SecurityContextImpl();
securityContextImpl.setAuthentication(auth);
repo.saveContext(securityContextImpl, requestResponseHolder.getRequest(), requestResponseHolder.getResponse());
}
@EnableWebSecurity
static class SessionManagementDefaultSessionFixationServlet31Config extends WebSecurityConfigurerAdapter {
@ -127,22 +145,4 @@ public class SessionManagementConfigurerServlet31Tests {
}
private void loadConfig(Class<?>... classes) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(classes);
context.refresh();
this.context = context;
this.springSecurityFilterChain = this.context.getBean("springSecurityFilterChain", Filter.class);
}
private void login(Authentication auth) {
HttpSessionSecurityContextRepository repo = new HttpSessionSecurityContextRepository();
HttpRequestResponseHolder requestResponseHolder = new HttpRequestResponseHolder(this.request, this.response);
repo.loadContext(requestResponseHolder);
SecurityContextImpl securityContextImpl = new SecurityContextImpl();
securityContextImpl.setAuthentication(auth);
repo.saveContext(securityContextImpl, requestResponseHolder.getRequest(), requestResponseHolder.getResponse());
}
}

View File

@ -55,6 +55,26 @@ public class SessionManagementConfigurerSessionCreationPolicyTests {
assertThat(result.getRequest().getSession(false)).isNull();
}
@Test
public void getWhenUserSessionCreationPolicyConfigurationThenOverrides() throws Exception {
this.spring.register(StatelessCreateSessionUserConfig.class).autowire();
MvcResult result = this.mvc.perform(get("/")).andReturn();
assertThat(result.getRequest().getSession(false)).isNull();
}
@Test
public void getWhenDefaultsThenLoginChallengeCreatesSession() throws Exception {
this.spring.register(DefaultConfig.class, BasicController.class).autowire();
MvcResult result = this.mvc.perform(get("/")).andExpect(status().isUnauthorized()).andReturn();
assertThat(result.getRequest().getSession(false)).isNotNull();
}
@EnableWebSecurity
static class StatelessCreateSessionSharedObjectConfig extends WebSecurityConfigurerAdapter {
@ -66,16 +86,6 @@ public class SessionManagementConfigurerSessionCreationPolicyTests {
}
@Test
public void getWhenUserSessionCreationPolicyConfigurationThenOverrides() throws Exception {
this.spring.register(StatelessCreateSessionUserConfig.class).autowire();
MvcResult result = this.mvc.perform(get("/")).andReturn();
assertThat(result.getRequest().getSession(false)).isNull();
}
@EnableWebSecurity
static class StatelessCreateSessionUserConfig extends WebSecurityConfigurerAdapter {
@ -92,16 +102,6 @@ public class SessionManagementConfigurerSessionCreationPolicyTests {
}
@Test
public void getWhenDefaultsThenLoginChallengeCreatesSession() throws Exception {
this.spring.register(DefaultConfig.class, BasicController.class).autowire();
MvcResult result = this.mvc.perform(get("/")).andExpect(status().isUnauthorized()).andReturn();
assertThat(result.getRequest().getSession(false)).isNotNull();
}
@EnableWebSecurity
static class DefaultConfig extends WebSecurityConfigurerAdapter {

View File

@ -90,25 +90,6 @@ public class SessionManagementConfigurerTests {
any(HttpServletResponse.class));
}
@EnableWebSecurity
static class SessionManagementRequestCacheConfig extends WebSecurityConfigurerAdapter {
static RequestCache REQUEST_CACHE;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.requestCache()
.requestCache(REQUEST_CACHE)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// @formatter:on
}
}
@Test
public void sessionManagementWhenConfiguredThenDoesNotOverrideSecurityContextRepository() throws Exception {
SessionManagementSecurityContextRepositoryConfig.SECURITY_CONTEXT_REPO = mock(SecurityContextRepository.class);
@ -122,25 +103,6 @@ public class SessionManagementConfigurerTests {
.saveContext(any(SecurityContext.class), any(HttpServletRequest.class), any(HttpServletResponse.class));
}
@EnableWebSecurity
static class SessionManagementSecurityContextRepositoryConfig extends WebSecurityConfigurerAdapter {
static SecurityContextRepository SECURITY_CONTEXT_REPO;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.securityContext()
.securityContextRepository(SECURITY_CONTEXT_REPO)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// @formatter:on
}
}
@Test
public void sessionManagementWhenInvokedTwiceThenUsesOriginalSessionCreationPolicy() throws Exception {
this.spring.register(InvokeTwiceDoesNotOverride.class).autowire();
@ -151,22 +113,6 @@ public class SessionManagementConfigurerTests {
assertThat(session).isNull();
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.sessionManagement();
// @formatter:on
}
}
// SEC-2137
@Test
public void getWhenSessionFixationDisabledAndConcurrencyControlEnabledThenSessionIsNotInvalidated()
@ -181,32 +127,6 @@ public class SessionManagementConfigurerTests {
assertThat(mvcResult.getRequest().getSession().getId()).isEqualTo(sessionId);
}
@EnableWebSecurity
static class DisableSessionFixationEnableConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.sessionManagement()
.sessionFixation().none()
.maximumSessions(1);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void authenticateWhenNewSessionFixationProtectionInLambdaThenCreatesNewSession() throws Exception {
this.spring.register(SFPNewSessionInLambdaConfig.class).autowire();
@ -223,34 +143,6 @@ public class SessionManagementConfigurerTests {
assertThat(resultingSession.getAttribute("name")).isNull();
}
@EnableWebSecurity
static class SFPNewSessionInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.sessionManagement(sessionManagement ->
sessionManagement
.sessionFixation(sessionFixation ->
sessionFixation.newSession()
)
)
.httpBasic(withDefaults());
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void loginWhenUserLoggedInAndMaxSessionsIsOneThenLoginPrevented() throws Exception {
this.spring.register(ConcurrencyControlConfig.class).autowire();
@ -275,32 +167,6 @@ public class SessionManagementConfigurerTests {
.andExpect(status().isFound()).andExpect(redirectedUrl("/"));
}
@EnableWebSecurity
static class ConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.formLogin()
.and()
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void loginWhenUserLoggedInAndMaxSessionsOneInLambdaThenLoginPrevented() throws Exception {
this.spring.register(ConcurrencyControlInLambdaConfig.class).autowire();
@ -311,36 +177,6 @@ public class SessionManagementConfigurerTests {
.andExpect(status().isFound()).andExpect(redirectedUrl("/login?error"));
}
@EnableWebSecurity
static class ConcurrencyControlInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.formLogin(withDefaults())
.sessionManagement(sessionManagement ->
sessionManagement
.sessionConcurrency(sessionConcurrency ->
sessionConcurrency
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
)
);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@Test
public void requestWhenSessionCreationPolicyStateLessInLambdaThenNoSessionCreated() throws Exception {
this.spring.register(SessionCreationPolicyStateLessInLambdaConfig.class).autowire();
@ -351,22 +187,6 @@ public class SessionManagementConfigurerTests {
assertThat(session).isNull();
}
@EnableWebSecurity
static class SessionCreationPolicyStateLessInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.sessionManagement(sessionManagement ->
sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
);
// @formatter:on
}
}
@Test
public void configureWhenRegisteringObjectPostProcessorThenInvokedOnSessionManagementFilter() {
ObjectPostProcessorConfig.objectPostProcessor = spy(ReflectingObjectPostProcessor.class);
@ -419,6 +239,222 @@ public class SessionManagementConfigurerTests {
.postProcess(any(ChangeSessionIdAuthenticationStrategy.class));
}
@Test
public void getWhenAnonymousRequestAndTrustResolverSharedObjectReturnsAnonymousFalseThenSessionIsSaved()
throws Exception {
SharedTrustResolverConfig.TR = mock(AuthenticationTrustResolver.class);
when(SharedTrustResolverConfig.TR.isAnonymous(any())).thenReturn(false);
this.spring.register(SharedTrustResolverConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/")).andReturn();
assertThat(mvcResult.getRequest().getSession(false)).isNotNull();
}
@Test
public void whenOneSessionRegistryBeanThenUseIt() throws Exception {
SessionRegistryOneBeanConfig.SESSION_REGISTRY = mock(SessionRegistry.class);
this.spring.register(SessionRegistryOneBeanConfig.class).autowire();
MockHttpSession session = new MockHttpSession(this.spring.getContext().getServletContext());
this.mvc.perform(get("/").session(session));
verify(SessionRegistryOneBeanConfig.SESSION_REGISTRY).getSessionInformation(session.getId());
}
@Test
public void whenTwoSessionRegistryBeansThenUseNeither() throws Exception {
SessionRegistryTwoBeansConfig.SESSION_REGISTRY_ONE = mock(SessionRegistry.class);
SessionRegistryTwoBeansConfig.SESSION_REGISTRY_TWO = mock(SessionRegistry.class);
this.spring.register(SessionRegistryTwoBeansConfig.class).autowire();
MockHttpSession session = new MockHttpSession(this.spring.getContext().getServletContext());
this.mvc.perform(get("/").session(session));
verifyNoInteractions(SessionRegistryTwoBeansConfig.SESSION_REGISTRY_ONE);
verifyNoInteractions(SessionRegistryTwoBeansConfig.SESSION_REGISTRY_TWO);
}
@EnableWebSecurity
static class SessionManagementRequestCacheConfig extends WebSecurityConfigurerAdapter {
static RequestCache REQUEST_CACHE;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.requestCache()
.requestCache(REQUEST_CACHE)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// @formatter:on
}
}
@EnableWebSecurity
static class SessionManagementSecurityContextRepositoryConfig extends WebSecurityConfigurerAdapter {
static SecurityContextRepository SECURITY_CONTEXT_REPO;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.securityContext()
.securityContextRepository(SECURITY_CONTEXT_REPO)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
// @formatter:on
}
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverride extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.sessionManagement();
// @formatter:on
}
}
@EnableWebSecurity
static class DisableSessionFixationEnableConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic()
.and()
.sessionManagement()
.sessionFixation().none()
.maximumSessions(1);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class SFPNewSessionInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.sessionManagement(sessionManagement ->
sessionManagement
.sessionFixation(sessionFixation ->
sessionFixation.newSession()
)
)
.httpBasic(withDefaults());
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class ConcurrencyControlConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.formLogin()
.and()
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class ConcurrencyControlInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.formLogin(withDefaults())
.sessionManagement(sessionManagement ->
sessionManagement
.sessionConcurrency(sessionConcurrency ->
sessionConcurrency
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
)
);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication()
.withUser(PasswordEncodedUser.user());
// @formatter:on
}
}
@EnableWebSecurity
static class SessionCreationPolicyStateLessInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.sessionManagement(sessionManagement ->
sessionManagement
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
);
// @formatter:on
}
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
@ -449,18 +485,6 @@ public class SessionManagementConfigurerTests {
}
@Test
public void getWhenAnonymousRequestAndTrustResolverSharedObjectReturnsAnonymousFalseThenSessionIsSaved()
throws Exception {
SharedTrustResolverConfig.TR = mock(AuthenticationTrustResolver.class);
when(SharedTrustResolverConfig.TR.isAnonymous(any())).thenReturn(false);
this.spring.register(SharedTrustResolverConfig.class).autowire();
MvcResult mvcResult = this.mvc.perform(get("/")).andReturn();
assertThat(mvcResult.getRequest().getSession(false)).isNotNull();
}
@EnableWebSecurity
static class SharedTrustResolverConfig extends WebSecurityConfigurerAdapter {
@ -476,30 +500,6 @@ public class SessionManagementConfigurerTests {
}
@Test
public void whenOneSessionRegistryBeanThenUseIt() throws Exception {
SessionRegistryOneBeanConfig.SESSION_REGISTRY = mock(SessionRegistry.class);
this.spring.register(SessionRegistryOneBeanConfig.class).autowire();
MockHttpSession session = new MockHttpSession(this.spring.getContext().getServletContext());
this.mvc.perform(get("/").session(session));
verify(SessionRegistryOneBeanConfig.SESSION_REGISTRY).getSessionInformation(session.getId());
}
@Test
public void whenTwoSessionRegistryBeansThenUseNeither() throws Exception {
SessionRegistryTwoBeansConfig.SESSION_REGISTRY_ONE = mock(SessionRegistry.class);
SessionRegistryTwoBeansConfig.SESSION_REGISTRY_TWO = mock(SessionRegistry.class);
this.spring.register(SessionRegistryTwoBeansConfig.class).autowire();
MockHttpSession session = new MockHttpSession(this.spring.getContext().getServletContext());
this.mvc.perform(get("/").session(session));
verifyNoInteractions(SessionRegistryTwoBeansConfig.SESSION_REGISTRY_ONE);
verifyNoInteractions(SessionRegistryTwoBeansConfig.SESSION_REGISTRY_TWO);
}
@EnableWebSecurity
static class SessionRegistryOneBeanConfig extends WebSecurityConfigurerAdapter {

View File

@ -98,41 +98,6 @@ public class UrlAuthorizationConfigurerTests {
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
http
.httpBasic().and()
.apply(new UrlAuthorizationConfigurer(getApplicationContext())).getRegistry()
.mvcMatchers("/path").hasRole("ADMIN");
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@Test
public void mvcMatcherServletPath() throws Exception {
loadConfig(MvcMatcherServletPathConfig.class, LegacyMvcMatchingConfig.class);
@ -176,6 +141,55 @@ public class UrlAuthorizationConfigurerTests {
assertThat(this.response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
}
@Test
public void anonymousUrlAuthorization() {
loadConfig(AnonymousUrlAuthorizationConfig.class);
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.setServletContext(new MockServletContext());
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
static class MvcMatcherConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.httpBasic().and()
.apply(new UrlAuthorizationConfigurer(getApplicationContext())).getRegistry()
.mvcMatchers("/path").hasRole("ADMIN");
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@RestController
static class PathController {
@RequestMapping("/path")
public String path() {
return "path";
}
}
}
@EnableWebSecurity
@Configuration
@EnableWebMvc
@ -211,11 +225,6 @@ public class UrlAuthorizationConfigurerTests {
}
@Test
public void anonymousUrlAuthorization() {
loadConfig(AnonymousUrlAuthorizationConfig.class);
}
@EnableWebSecurity
@Configuration
static class AnonymousUrlAuthorizationConfig extends WebSecurityConfigurerAdapter {
@ -241,13 +250,4 @@ public class UrlAuthorizationConfigurerTests {
}
public void loadConfig(Class<?>... configs) {
this.context = new AnnotationConfigWebApplicationContext();
this.context.register(configs);
this.context.setServletContext(new MockServletContext());
this.context.refresh();
this.context.getAutowireCapableBeanFactory().autowireBean(this);
}
}

View File

@ -103,25 +103,6 @@ public class UrlAuthorizationsTests {
this.mvc.perform(get("/role-admin")).andExpect(status().isForbidden());
}
@EnableWebSecurity
static class RoleConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/role-user-authority").hasAnyAuthority("ROLE_USER")
.antMatchers("/role-admin-authority").hasAnyAuthority("ROLE_ADMIN")
.antMatchers("/role-user-admin-authority").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")
.antMatchers("/role-user").hasAnyRole("USER")
.antMatchers("/role-admin").hasAnyRole("ADMIN")
.antMatchers("/role-user-admin").hasAnyRole("USER", "ADMIN");
// @formatter:on
}
}
@Test
public void configureWhenNoAccessDecisionManagerThenDefaultsToAffirmativeBased() {
this.spring.register(NoSpecificAccessDecisionManagerConfig.class).autowire();
@ -142,6 +123,25 @@ public class UrlAuthorizationsTests {
return null;
}
@EnableWebSecurity
static class RoleConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.antMatchers("/role-user-authority").hasAnyAuthority("ROLE_USER")
.antMatchers("/role-admin-authority").hasAnyAuthority("ROLE_ADMIN")
.antMatchers("/role-user-admin-authority").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")
.antMatchers("/role-user").hasAnyRole("USER")
.antMatchers("/role-admin").hasAnyRole("ADMIN")
.antMatchers("/role-user-admin").hasAnyRole("USER", "ADMIN");
// @formatter:on
}
}
@EnableWebSecurity
static class NoSpecificAccessDecisionManagerConfig extends WebSecurityConfigurerAdapter {

View File

@ -65,6 +65,40 @@ public class X509ConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(X509AuthenticationFilter.class));
}
@Test
public void x509WhenInvokedTwiceThenUsesOriginalSubjectPrincipalRegex() throws Exception {
this.spring.register(DuplicateDoesNotOverrideConfig.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/").with(x509(certificate))).andExpect(authenticated().withUsername("rod"));
}
@Test
public void x509WhenConfiguredInLambdaThenUsesDefaults() throws Exception {
this.spring.register(DefaultsInLambdaConfig.class).autowire();
X509Certificate certificate = loadCert("rod.cer");
this.mvc.perform(get("/").with(x509(certificate))).andExpect(authenticated().withUsername("rod"));
}
@Test
public void x509WhenSubjectPrincipalRegexInLambdaThenUsesRegexToExtractPrincipal() throws Exception {
this.spring.register(SubjectPrincipalRegexInLambdaConfig.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/").with(x509(certificate))).andExpect(authenticated().withUsername("rod"));
}
private <T extends Certificate> T loadCert(String location) {
try (InputStream is = new ClassPathResource(location).getInputStream()) {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
return (T) certFactory.generateCertificate(is);
}
catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
@ -94,14 +128,6 @@ public class X509ConfigurerTests {
}
@Test
public void x509WhenInvokedTwiceThenUsesOriginalSubjectPrincipalRegex() throws Exception {
this.spring.register(DuplicateDoesNotOverrideConfig.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/").with(x509(certificate))).andExpect(authenticated().withUsername("rod"));
}
@EnableWebSecurity
static class DuplicateDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@ -127,14 +153,6 @@ public class X509ConfigurerTests {
}
@Test
public void x509WhenConfiguredInLambdaThenUsesDefaults() throws Exception {
this.spring.register(DefaultsInLambdaConfig.class).autowire();
X509Certificate certificate = loadCert("rod.cer");
this.mvc.perform(get("/").with(x509(certificate))).andExpect(authenticated().withUsername("rod"));
}
@EnableWebSecurity
static class DefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -157,14 +175,6 @@ public class X509ConfigurerTests {
}
@Test
public void x509WhenSubjectPrincipalRegexInLambdaThenUsesRegexToExtractPrincipal() throws Exception {
this.spring.register(SubjectPrincipalRegexInLambdaConfig.class).autowire();
X509Certificate certificate = loadCert("rodatexampledotcom.cer");
this.mvc.perform(get("/").with(x509(certificate))).andExpect(authenticated().withUsername("rod"));
}
@EnableWebSecurity
static class SubjectPrincipalRegexInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -190,14 +200,4 @@ public class X509ConfigurerTests {
}
private <T extends Certificate> T loadCert(String location) {
try (InputStream is = new ClassPathResource(location).getInputStream()) {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
return (T) certFactory.generateCertificate(is);
}
catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
}

View File

@ -584,6 +584,37 @@ public class OAuth2LoginConfigurerTests {
.scope(scopes).build();
}
private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> createOauth2AccessTokenResponseClient() {
return request -> {
Map<String, Object> additionalParameters = new HashMap<>();
if (request.getAuthorizationExchange().getAuthorizationRequest().getScopes().contains("openid")) {
additionalParameters.put(OidcParameterNames.ID_TOKEN, "token123");
}
return OAuth2AccessTokenResponse.withToken("accessToken123").tokenType(OAuth2AccessToken.TokenType.BEARER)
.additionalParameters(additionalParameters).build();
};
}
private static OAuth2UserService<OAuth2UserRequest, OAuth2User> createOauth2UserService() {
Map<String, Object> userAttributes = Collections.singletonMap("name", "spring");
return request -> new DefaultOAuth2User(Collections.singleton(new OAuth2UserAuthority(userAttributes)),
userAttributes, "name");
}
private static OAuth2UserService<OidcUserRequest, OidcUser> createOidcUserService() {
OidcIdToken idToken = idToken().build();
return request -> new DefaultOidcUser(Collections.singleton(new OidcUserAuthority(idToken)), idToken);
}
private static GrantedAuthoritiesMapper createGrantedAuthoritiesMapper() {
return authorities -> {
boolean isOidc = OidcUserAuthority.class.isInstance(authorities.iterator().next());
List<GrantedAuthority> mappedAuthorities = new ArrayList<>(authorities);
mappedAuthorities.add(new SimpleGrantedAuthority(isOidc ? "ROLE_OIDC_USER" : "ROLE_OAUTH2_USER"));
return mappedAuthorities;
};
}
@EnableWebSecurity
static class OAuth2LoginConfig extends CommonWebSecurityConfigurerAdapter
implements ApplicationListener<AuthenticationSuccessEvent> {
@ -985,35 +1016,4 @@ public class OAuth2LoginConfigurerTests {
}
private static OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> createOauth2AccessTokenResponseClient() {
return request -> {
Map<String, Object> additionalParameters = new HashMap<>();
if (request.getAuthorizationExchange().getAuthorizationRequest().getScopes().contains("openid")) {
additionalParameters.put(OidcParameterNames.ID_TOKEN, "token123");
}
return OAuth2AccessTokenResponse.withToken("accessToken123").tokenType(OAuth2AccessToken.TokenType.BEARER)
.additionalParameters(additionalParameters).build();
};
}
private static OAuth2UserService<OAuth2UserRequest, OAuth2User> createOauth2UserService() {
Map<String, Object> userAttributes = Collections.singletonMap("name", "spring");
return request -> new DefaultOAuth2User(Collections.singleton(new OAuth2UserAuthority(userAttributes)),
userAttributes, "name");
}
private static OAuth2UserService<OidcUserRequest, OidcUser> createOidcUserService() {
OidcIdToken idToken = idToken().build();
return request -> new DefaultOidcUser(Collections.singleton(new OidcUserAuthority(idToken)), idToken);
}
private static GrantedAuthoritiesMapper createGrantedAuthoritiesMapper() {
return authorities -> {
boolean isOidc = OidcUserAuthority.class.isInstance(authorities.iterator().next());
List<GrantedAuthority> mappedAuthorities = new ArrayList<>(authorities);
mappedAuthorities.add(new SimpleGrantedAuthority(isOidc ? "ROLE_OIDC_USER" : "ROLE_OAUTH2_USER"));
return mappedAuthorities;
};
}
}

View File

@ -1327,7 +1327,89 @@ public class OAuth2ResourceServerConfigurerTests {
.isInstanceOf(NoUniqueBeanDefinitionException.class);
}
// -- support
private static <T> void registerMockBean(GenericApplicationContext context, String name, Class<T> clazz) {
context.registerBean(name, clazz, () -> mock(clazz));
}
private static BearerTokenRequestPostProcessor bearerToken(String token) {
return new BearerTokenRequestPostProcessor(token);
}
private static ResultMatcher invalidRequestHeader(String message) {
return header().string(HttpHeaders.WWW_AUTHENTICATE,
AllOf.allOf(new StringStartsWith("Bearer " + "error=\"invalid_request\", " + "error_description=\""),
new StringContains(message),
new StringEndsWith(", " + "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\"")));
}
private static ResultMatcher invalidTokenHeader(String message) {
return header().string(HttpHeaders.WWW_AUTHENTICATE,
AllOf.allOf(new StringStartsWith("Bearer " + "error=\"invalid_token\", " + "error_description=\""),
new StringContains(message),
new StringEndsWith(", " + "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\"")));
}
private static ResultMatcher insufficientScopeHeader() {
return header().string(HttpHeaders.WWW_AUTHENTICATE, "Bearer " + "error=\"insufficient_scope\""
+ ", error_description=\"The request requires higher privileges than provided by the access token.\""
+ ", error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\"");
}
private String jwkSet() {
return new JWKSet(new RSAKey.Builder(TestKeys.DEFAULT_PUBLIC_KEY).keyID("1").build()).toString();
}
private String jwtFromIssuer(String issuer) throws Exception {
Map<String, Object> claims = new HashMap<>();
claims.put(ISS, issuer);
claims.put(SUB, "test-subject");
claims.put("scope", "message:read");
JWSObject jws = new JWSObject(new JWSHeader.Builder(JWSAlgorithm.RS256).keyID("1").build(),
new Payload(new JSONObject(claims)));
jws.sign(new RSASSASigner(TestKeys.DEFAULT_PRIVATE_KEY));
return jws.serialize();
}
private void mockWebServer(String response) {
this.web.enqueue(new MockResponse().setResponseCode(200)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).setBody(response));
}
private void mockRestOperations(String response) {
RestOperations rest = this.spring.getContext().getBean(RestOperations.class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> entity = new ResponseEntity<>(response, headers, HttpStatus.OK);
when(rest.exchange(any(RequestEntity.class), eq(String.class))).thenReturn(entity);
}
private <T> T bean(Class<T> beanClass) {
return this.spring.getContext().getBean(beanClass);
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
private String json(String name) throws IOException {
return resource(name + ".json");
}
private String jwks(String name) throws IOException {
return resource(name + ".jwks");
}
private String token(String name) throws IOException {
return resource(name + ".token");
}
private String resource(String suffix) throws IOException {
String name = this.getClass().getSimpleName() + "-" + suffix;
ClassPathResource resource = new ClassPathResource(name, this.getClass());
try (BufferedReader reader = new BufferedReader(new FileReader(resource.getFile()))) {
return reader.lines().collect(Collectors.joining());
}
}
@EnableWebSecurity
static class DefaultConfig extends WebSecurityConfigurerAdapter {
@ -2293,10 +2375,6 @@ public class OAuth2ResourceServerConfigurerTests {
}
private static <T> void registerMockBean(GenericApplicationContext context, String name, Class<T> clazz) {
context.registerBean(name, clazz, () -> mock(clazz));
}
private static class BearerTokenRequestPostProcessor implements RequestPostProcessor {
private boolean asRequestParameter;
@ -2326,84 +2404,4 @@ public class OAuth2ResourceServerConfigurerTests {
}
private static BearerTokenRequestPostProcessor bearerToken(String token) {
return new BearerTokenRequestPostProcessor(token);
}
private static ResultMatcher invalidRequestHeader(String message) {
return header().string(HttpHeaders.WWW_AUTHENTICATE,
AllOf.allOf(new StringStartsWith("Bearer " + "error=\"invalid_request\", " + "error_description=\""),
new StringContains(message),
new StringEndsWith(", " + "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\"")));
}
private static ResultMatcher invalidTokenHeader(String message) {
return header().string(HttpHeaders.WWW_AUTHENTICATE,
AllOf.allOf(new StringStartsWith("Bearer " + "error=\"invalid_token\", " + "error_description=\""),
new StringContains(message),
new StringEndsWith(", " + "error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\"")));
}
private static ResultMatcher insufficientScopeHeader() {
return header().string(HttpHeaders.WWW_AUTHENTICATE, "Bearer " + "error=\"insufficient_scope\""
+ ", error_description=\"The request requires higher privileges than provided by the access token.\""
+ ", error_uri=\"https://tools.ietf.org/html/rfc6750#section-3.1\"");
}
private String jwkSet() {
return new JWKSet(new RSAKey.Builder(TestKeys.DEFAULT_PUBLIC_KEY).keyID("1").build()).toString();
}
private String jwtFromIssuer(String issuer) throws Exception {
Map<String, Object> claims = new HashMap<>();
claims.put(ISS, issuer);
claims.put(SUB, "test-subject");
claims.put("scope", "message:read");
JWSObject jws = new JWSObject(new JWSHeader.Builder(JWSAlgorithm.RS256).keyID("1").build(),
new Payload(new JSONObject(claims)));
jws.sign(new RSASSASigner(TestKeys.DEFAULT_PRIVATE_KEY));
return jws.serialize();
}
private void mockWebServer(String response) {
this.web.enqueue(new MockResponse().setResponseCode(200)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).setBody(response));
}
private void mockRestOperations(String response) {
RestOperations rest = this.spring.getContext().getBean(RestOperations.class);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
ResponseEntity<String> entity = new ResponseEntity<>(response, headers, HttpStatus.OK);
when(rest.exchange(any(RequestEntity.class), eq(String.class))).thenReturn(entity);
}
private <T> T bean(Class<T> beanClass) {
return this.spring.getContext().getBean(beanClass);
}
private <T> T verifyBean(Class<T> beanClass) {
return verify(this.spring.getContext().getBean(beanClass));
}
private String json(String name) throws IOException {
return resource(name + ".json");
}
private String jwks(String name) throws IOException {
return resource(name + ".jwks");
}
private String token(String name) throws IOException {
return resource(name + ".token");
}
private String resource(String suffix) throws IOException {
String name = this.getClass().getSimpleName() + "-" + suffix;
ClassPathResource resource = new ClassPathResource(name, this.getClass());
try (BufferedReader reader = new BufferedReader(new FileReader(resource.getFile()))) {
return reader.lines().collect(Collectors.joining());
}
}
}

View File

@ -83,35 +83,6 @@ public class OpenIDLoginConfigurerTests {
verify(ObjectPostProcessorConfig.objectPostProcessor).postProcess(any(OpenIDAuthenticationProvider.class));
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.openidLogin();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@Test
public void openidLoginWhenInvokedTwiceThenUsesOriginalLoginPage() throws Exception {
this.spring.register(InvokeTwiceDoesNotOverrideConfig.class).autowire();
@ -120,33 +91,6 @@ public class OpenIDLoginConfigurerTests {
.andExpect(redirectedUrl("http://localhost/login/custom"));
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.openidLogin()
.loginPage("/login/custom")
.and()
.openidLogin();
// @formatter:on
}
}
@Test
public void requestWhenOpenIdLoginPageInLambdaThenRedirectsToLoginPAge() throws Exception {
this.spring.register(OpenIdLoginPageInLambdaConfig.class).autowire();
@ -155,26 +99,6 @@ public class OpenIDLoginConfigurerTests {
.andExpect(redirectedUrl("http://localhost/login/custom"));
}
@EnableWebSecurity
static class OpenIdLoginPageInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.anyRequest().authenticated()
)
.openidLogin(openIdLogin ->
openIdLogin
.loginPage("/login/custom")
);
// @formatter:on
}
}
@Test
public void requestWhenAttributeExchangeConfiguredThenFetchAttributesMatchAttributeList() throws Exception {
OpenIdAttributesInLambdaConfig.CONSUMER_MANAGER = mock(ConsumerManager.class);
@ -213,6 +137,113 @@ public class OpenIDLoginConfigurerTests {
}
}
@Test
public void requestWhenAttributeNameNotSpecifiedThenAttributeNameDefaulted() throws Exception {
OpenIdAttributesNullNameConfig.CONSUMER_MANAGER = mock(ConsumerManager.class);
AuthRequest mockAuthRequest = mock(AuthRequest.class);
DiscoveryInformation mockDiscoveryInformation = mock(DiscoveryInformation.class);
when(mockAuthRequest.getDestinationUrl(anyBoolean())).thenReturn("mockUrl");
when(OpenIdAttributesNullNameConfig.CONSUMER_MANAGER.associate(any())).thenReturn(mockDiscoveryInformation);
when(OpenIdAttributesNullNameConfig.CONSUMER_MANAGER.authenticate(any(DiscoveryInformation.class), any(),
any())).thenReturn(mockAuthRequest);
this.spring.register(OpenIdAttributesNullNameConfig.class).autowire();
try (MockWebServer server = new MockWebServer()) {
String endpoint = server.url("/").toString();
server.enqueue(new MockResponse().addHeader(YADIS_XRDS_LOCATION, endpoint));
server.enqueue(new MockResponse()
.setBody(String.format("<XRDS><XRD><Service><URI>%s</URI></Service></XRD></XRDS>", endpoint)));
MvcResult mvcResult = this.mvc.perform(
get("/login/openid").param(OpenIDAuthenticationFilter.DEFAULT_CLAIMED_IDENTITY_FIELD, endpoint))
.andExpect(status().isFound()).andReturn();
Object attributeObject = mvcResult.getRequest().getSession()
.getAttribute("SPRING_SECURITY_OPEN_ID_ATTRIBUTES_FETCH_LIST");
assertThat(attributeObject).isInstanceOf(List.class);
List<OpenIDAttribute> attributeList = (List<OpenIDAttribute>) attributeObject;
assertThat(attributeList).hasSize(1);
assertThat(attributeList.get(0).getName()).isEqualTo("default-attribute");
}
}
@EnableWebSecurity
static class ObjectPostProcessorConfig extends WebSecurityConfigurerAdapter {
static ObjectPostProcessor<Object> objectPostProcessor;
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.openidLogin();
// @formatter:on
}
@Bean
static ObjectPostProcessor<Object> objectPostProcessor() {
return objectPostProcessor;
}
}
static class ReflectingObjectPostProcessor implements ObjectPostProcessor<Object> {
@Override
public <O> O postProcess(O object) {
return object;
}
}
@EnableWebSecurity
static class InvokeTwiceDoesNotOverrideConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth
.inMemoryAuthentication();
// @formatter:on
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.openidLogin()
.loginPage("/login/custom")
.and()
.openidLogin();
// @formatter:on
}
}
@EnableWebSecurity
static class OpenIdLoginPageInLambdaConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests(authorizeRequests ->
authorizeRequests
.anyRequest().authenticated()
)
.openidLogin(openIdLogin ->
openIdLogin
.loginPage("/login/custom")
);
// @formatter:on
}
}
@EnableWebSecurity
static class OpenIdAttributesInLambdaConfig extends WebSecurityConfigurerAdapter {
@ -251,37 +282,6 @@ public class OpenIDLoginConfigurerTests {
}
@Test
public void requestWhenAttributeNameNotSpecifiedThenAttributeNameDefaulted() throws Exception {
OpenIdAttributesNullNameConfig.CONSUMER_MANAGER = mock(ConsumerManager.class);
AuthRequest mockAuthRequest = mock(AuthRequest.class);
DiscoveryInformation mockDiscoveryInformation = mock(DiscoveryInformation.class);
when(mockAuthRequest.getDestinationUrl(anyBoolean())).thenReturn("mockUrl");
when(OpenIdAttributesNullNameConfig.CONSUMER_MANAGER.associate(any())).thenReturn(mockDiscoveryInformation);
when(OpenIdAttributesNullNameConfig.CONSUMER_MANAGER.authenticate(any(DiscoveryInformation.class), any(),
any())).thenReturn(mockAuthRequest);
this.spring.register(OpenIdAttributesNullNameConfig.class).autowire();
try (MockWebServer server = new MockWebServer()) {
String endpoint = server.url("/").toString();
server.enqueue(new MockResponse().addHeader(YADIS_XRDS_LOCATION, endpoint));
server.enqueue(new MockResponse()
.setBody(String.format("<XRDS><XRD><Service><URI>%s</URI></Service></XRD></XRDS>", endpoint)));
MvcResult mvcResult = this.mvc.perform(
get("/login/openid").param(OpenIDAuthenticationFilter.DEFAULT_CLAIMED_IDENTITY_FIELD, endpoint))
.andExpect(status().isFound()).andReturn();
Object attributeObject = mvcResult.getRequest().getSession()
.getAttribute("SPRING_SECURITY_OPEN_ID_ATTRIBUTES_FETCH_LIST");
assertThat(attributeObject).isInstanceOf(List.class);
List<OpenIDAttribute> attributeList = (List<OpenIDAttribute>) attributeObject;
assertThat(attributeList).hasSize(1);
assertThat(attributeList.get(0).getName()).isEqualTo("default-attribute");
}
}
@EnableWebSecurity
static class OpenIdAttributesNullNameConfig extends WebSecurityConfigurerAdapter {

View File

@ -241,6 +241,44 @@ public class Saml2LoginConfigurerTests {
.hasToString(expected);
}
private static org.apache.commons.codec.binary.Base64 BASE64 = new org.apache.commons.codec.binary.Base64(0,
new byte[] { '\n' });
private static byte[] samlDecode(String s) {
return BASE64.decode(s);
}
private static String samlInflate(byte[] b) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InflaterOutputStream iout = new InflaterOutputStream(out, new Inflater(true));
iout.write(b);
iout.finish();
return new String(out.toByteArray(), UTF_8);
}
catch (IOException e) {
throw new Saml2Exception("Unable to inflate string", e);
}
}
private static AuthenticationManager getAuthenticationManagerMock(String role) {
return new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (!supports(authentication.getClass())) {
throw new AuthenticationServiceException("not supported");
}
return new Saml2Authentication(() -> "auth principal", "saml2 response",
Collections.singletonList(new SimpleGrantedAuthority(role)));
}
public boolean supports(Class<?> authentication) {
return authentication.isAssignableFrom(Saml2AuthenticationToken.class);
}
};
}
@EnableWebSecurity
@Import(Saml2LoginConfigBeans.class)
static class Saml2LoginConfigWithCustomAuthenticationManager extends WebSecurityConfigurerAdapter {
@ -339,24 +377,6 @@ public class Saml2LoginConfigurerTests {
}
private static AuthenticationManager getAuthenticationManagerMock(String role) {
return new AuthenticationManager() {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (!supports(authentication.getClass())) {
throw new AuthenticationServiceException("not supported");
}
return new Saml2Authentication(() -> "auth principal", "saml2 response",
Collections.singletonList(new SimpleGrantedAuthority(role)));
}
public boolean supports(Class<?> authentication) {
return authentication.isAssignableFrom(Saml2AuthenticationToken.class);
}
};
}
static class Saml2LoginConfigBeans {
@Bean
@ -373,24 +393,4 @@ public class Saml2LoginConfigurerTests {
}
private static org.apache.commons.codec.binary.Base64 BASE64 = new org.apache.commons.codec.binary.Base64(0,
new byte[] { '\n' });
private static byte[] samlDecode(String s) {
return BASE64.decode(s);
}
private static String samlInflate(byte[] b) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InflaterOutputStream iout = new InflaterOutputStream(out, new Inflater(true));
iout.write(b);
iout.finish();
return new String(out.toByteArray(), UTF_8);
}
catch (IOException e) {
throw new Saml2Exception("Unable to inflate string", e);
}
}
}

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