Add SecurityContextHolderStrategy Java Configuration for Method Security
Issue gh-11061
This commit is contained in:
parent
7a9c873d7d
commit
74d646f569
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -73,6 +73,8 @@ import org.springframework.security.config.annotation.ObjectPostProcessor;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,6 +103,9 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||||
|
.getContextHolderStrategy();
|
||||||
|
|
||||||
private DefaultMethodSecurityExpressionHandler defaultMethodExpressionHandler = new DefaultMethodSecurityExpressionHandler();
|
private DefaultMethodSecurityExpressionHandler defaultMethodExpressionHandler = new DefaultMethodSecurityExpressionHandler();
|
||||||
|
|
||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
|
@ -143,6 +148,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
|
||||||
this.methodSecurityInterceptor.setAccessDecisionManager(accessDecisionManager());
|
this.methodSecurityInterceptor.setAccessDecisionManager(accessDecisionManager());
|
||||||
this.methodSecurityInterceptor.setAfterInvocationManager(afterInvocationManager());
|
this.methodSecurityInterceptor.setAfterInvocationManager(afterInvocationManager());
|
||||||
this.methodSecurityInterceptor.setSecurityMetadataSource(methodSecurityMetadataSource);
|
this.methodSecurityInterceptor.setSecurityMetadataSource(methodSecurityMetadataSource);
|
||||||
|
this.methodSecurityInterceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
|
||||||
RunAsManager runAsManager = runAsManager();
|
RunAsManager runAsManager = runAsManager();
|
||||||
if (runAsManager != null) {
|
if (runAsManager != null) {
|
||||||
this.methodSecurityInterceptor.setRunAsManager(runAsManager);
|
this.methodSecurityInterceptor.setRunAsManager(runAsManager);
|
||||||
|
@ -411,6 +417,12 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
|
||||||
this.expressionHandler = handlers.get(0);
|
this.expressionHandler = handlers.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
|
||||||
|
Assert.notNull(securityContextHolderStrategy, "securityContextHolderStrategy cannot be null");
|
||||||
|
this.securityContextHolderStrategy = securityContextHolderStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||||
this.context = beanFactory;
|
this.context = beanFactory;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -25,6 +25,8 @@ import org.springframework.context.annotation.Role;
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||||
import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
|
import org.springframework.security.authorization.method.Jsr250AuthorizationManager;
|
||||||
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Configuration} for enabling JSR-250 Spring Security Method Security.
|
* {@link Configuration} for enabling JSR-250 Spring Security Method Security.
|
||||||
|
@ -40,10 +42,16 @@ final class Jsr250MethodSecurityConfiguration {
|
||||||
|
|
||||||
private final Jsr250AuthorizationManager jsr250AuthorizationManager = new Jsr250AuthorizationManager();
|
private final Jsr250AuthorizationManager jsr250AuthorizationManager = new Jsr250AuthorizationManager();
|
||||||
|
|
||||||
|
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||||
|
.getContextHolderStrategy();
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
Advisor jsr250AuthorizationMethodInterceptor() {
|
Advisor jsr250AuthorizationMethodInterceptor() {
|
||||||
return AuthorizationManagerBeforeMethodInterceptor.jsr250(this.jsr250AuthorizationManager);
|
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor
|
||||||
|
.jsr250(this.jsr250AuthorizationManager);
|
||||||
|
interceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
|
||||||
|
return interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
|
@ -51,4 +59,9 @@ final class Jsr250MethodSecurityConfiguration {
|
||||||
this.jsr250AuthorizationManager.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
|
this.jsr250AuthorizationManager.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
|
||||||
|
this.securityContextHolderStrategy = securityContextHolderStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.springframework.security.authorization.method.PostFilterAuthorization
|
||||||
import org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager;
|
import org.springframework.security.authorization.method.PreAuthorizeAuthorizationManager;
|
||||||
import org.springframework.security.authorization.method.PreFilterAuthorizationMethodInterceptor;
|
import org.springframework.security.authorization.method.PreFilterAuthorizationMethodInterceptor;
|
||||||
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base {@link Configuration} for enabling Spring Security Method Security.
|
* Base {@link Configuration} for enabling Spring Security Method Security.
|
||||||
|
@ -109,6 +110,14 @@ final class PrePostMethodSecurityConfiguration {
|
||||||
this.postFilterAuthorizationMethodInterceptor.setExpressionHandler(methodSecurityExpressionHandler);
|
this.postFilterAuthorizationMethodInterceptor.setExpressionHandler(methodSecurityExpressionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
void setSecurityContextHolderStrategy(SecurityContextHolderStrategy strategy) {
|
||||||
|
this.preFilterAuthorizationMethodInterceptor.setSecurityContextHolderStrategy(strategy);
|
||||||
|
this.preAuthorizeAuthorizationMethodInterceptor.setSecurityContextHolderStrategy(strategy);
|
||||||
|
this.postAuthorizeAuthorizaitonMethodInterceptor.setSecurityContextHolderStrategy(strategy);
|
||||||
|
this.postFilterAuthorizationMethodInterceptor.setSecurityContextHolderStrategy(strategy);
|
||||||
|
}
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
void setGrantedAuthorityDefaults(GrantedAuthorityDefaults grantedAuthorityDefaults) {
|
void setGrantedAuthorityDefaults(GrantedAuthorityDefaults grantedAuthorityDefaults) {
|
||||||
this.expressionHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
|
this.expressionHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,12 +17,15 @@
|
||||||
package org.springframework.security.config.annotation.method.configuration;
|
package org.springframework.security.config.annotation.method.configuration;
|
||||||
|
|
||||||
import org.springframework.aop.Advisor;
|
import org.springframework.aop.Advisor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Role;
|
import org.springframework.context.annotation.Role;
|
||||||
import org.springframework.security.access.annotation.Secured;
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Configuration} for enabling {@link Secured} Spring Security Method Security.
|
* {@link Configuration} for enabling {@link Secured} Spring Security Method Security.
|
||||||
|
@ -36,10 +39,20 @@ import org.springframework.security.authorization.method.AuthorizationManagerBef
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
final class SecuredMethodSecurityConfiguration {
|
final class SecuredMethodSecurityConfiguration {
|
||||||
|
|
||||||
|
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
|
||||||
|
.getContextHolderStrategy();
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
Advisor securedAuthorizationMethodInterceptor() {
|
Advisor securedAuthorizationMethodInterceptor() {
|
||||||
return AuthorizationManagerBeforeMethodInterceptor.secured();
|
AuthorizationManagerBeforeMethodInterceptor interceptor = AuthorizationManagerBeforeMethodInterceptor.secured();
|
||||||
|
interceptor.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
|
||||||
|
return interceptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {
|
||||||
|
this.securityContextHolderStrategy = securityContextHolderStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,19 +50,24 @@ import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.authorization.method.AuthorizationInterceptorsOrder;
|
import org.springframework.security.authorization.method.AuthorizationInterceptorsOrder;
|
||||||
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
|
||||||
import org.springframework.security.authorization.method.MethodInvocationResult;
|
import org.springframework.security.authorization.method.MethodInvocationResult;
|
||||||
|
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
||||||
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
import org.springframework.security.config.core.GrantedAuthorityDefaults;
|
||||||
import org.springframework.security.config.test.SpringTestContext;
|
import org.springframework.security.config.test.SpringTestContext;
|
||||||
import org.springframework.security.config.test.SpringTestContextExtension;
|
import org.springframework.security.config.test.SpringTestContextExtension;
|
||||||
|
import org.springframework.security.config.test.SpringTestParentApplicationContextExecutionListener;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolderStrategy;
|
||||||
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
|
|
||||||
import org.springframework.security.test.context.support.WithAnonymousUser;
|
import org.springframework.security.test.context.support.WithAnonymousUser;
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.TestExecutionListeners;
|
||||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.atLeastOnce;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
@ -73,7 +78,9 @@ import static org.mockito.Mockito.verify;
|
||||||
* @author Josh Cummings
|
* @author Josh Cummings
|
||||||
*/
|
*/
|
||||||
@ExtendWith({ SpringExtension.class, SpringTestContextExtension.class })
|
@ExtendWith({ SpringExtension.class, SpringTestContextExtension.class })
|
||||||
@SecurityTestExecutionListeners
|
@ContextConfiguration(classes = SecurityContextChangedListenerConfig.class)
|
||||||
|
@TestExecutionListeners(listeners = { WithSecurityContextTestExecutionListener.class,
|
||||||
|
SpringTestParentApplicationContextExecutionListener.class })
|
||||||
public class PrePostMethodSecurityConfigurationTests {
|
public class PrePostMethodSecurityConfigurationTests {
|
||||||
|
|
||||||
public final SpringTestContext spring = new SpringTestContext(this);
|
public final SpringTestContext spring = new SpringTestContext(this);
|
||||||
|
@ -137,6 +144,8 @@ public class PrePostMethodSecurityConfigurationTests {
|
||||||
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
|
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
|
||||||
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::securedUser)
|
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::securedUser)
|
||||||
.withMessage("Access Denied");
|
.withMessage("Access Denied");
|
||||||
|
SecurityContextHolderStrategy strategy = this.spring.getContext().getBean(SecurityContextHolderStrategy.class);
|
||||||
|
verify(strategy, atLeastOnce()).getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@WithMockUser
|
@WithMockUser
|
||||||
|
@ -162,6 +171,15 @@ public class PrePostMethodSecurityConfigurationTests {
|
||||||
this.methodSecurityService.preAuthorizeAdmin();
|
this.methodSecurityService.preAuthorizeAdmin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WithMockUser(roles = "ADMIN")
|
||||||
|
@Test
|
||||||
|
public void preAuthorizeAdminWhenSecurityContextHolderStrategyThenUses() {
|
||||||
|
this.spring.register(MethodSecurityServiceConfig.class).autowire();
|
||||||
|
this.methodSecurityService.preAuthorizeAdmin();
|
||||||
|
SecurityContextHolderStrategy strategy = this.spring.getContext().getBean(SecurityContextHolderStrategy.class);
|
||||||
|
verify(strategy, atLeastOnce()).getContext();
|
||||||
|
}
|
||||||
|
|
||||||
@WithMockUser(authorities = "PREFIX_ADMIN")
|
@WithMockUser(authorities = "PREFIX_ADMIN")
|
||||||
@Test
|
@Test
|
||||||
public void preAuthorizeAdminWhenRoleAdminAndCustomPrefixThenPasses() {
|
public void preAuthorizeAdminWhenRoleAdminAndCustomPrefixThenPasses() {
|
||||||
|
@ -285,6 +303,8 @@ public class PrePostMethodSecurityConfigurationTests {
|
||||||
this.spring.register(BusinessServiceConfig.class).autowire();
|
this.spring.register(BusinessServiceConfig.class).autowire();
|
||||||
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.businessService::rolesAllowedUser)
|
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.businessService::rolesAllowedUser)
|
||||||
.withMessage("Access Denied");
|
.withMessage("Access Denied");
|
||||||
|
SecurityContextHolderStrategy strategy = this.spring.getContext().getBean(SecurityContextHolderStrategy.class);
|
||||||
|
verify(strategy, atLeastOnce()).getContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@WithMockUser
|
@WithMockUser
|
||||||
|
@ -480,12 +500,15 @@ public class PrePostMethodSecurityConfigurationTests {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
Advisor customBeforeAdvice() {
|
Advisor customBeforeAdvice(SecurityContextHolderStrategy strategy) {
|
||||||
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
|
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
|
||||||
pointcut.setPattern(".*MethodSecurityServiceImpl.*securedUser");
|
pointcut.setPattern(".*MethodSecurityServiceImpl.*securedUser");
|
||||||
AuthorizationManager<MethodInvocation> authorizationManager = (a,
|
AuthorizationManager<MethodInvocation> authorizationManager = (a,
|
||||||
o) -> new AuthorizationDecision("bob".equals(a.get().getName()));
|
o) -> new AuthorizationDecision("bob".equals(a.get().getName()));
|
||||||
return new AuthorizationManagerBeforeMethodInterceptor(pointcut, authorizationManager);
|
AuthorizationManagerBeforeMethodInterceptor before = new AuthorizationManagerBeforeMethodInterceptor(
|
||||||
|
pointcut, authorizationManager);
|
||||||
|
before.setSecurityContextHolderStrategy(strategy);
|
||||||
|
return before;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -495,11 +518,11 @@ public class PrePostMethodSecurityConfigurationTests {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||||
Advisor customAfterAdvice() {
|
Advisor customAfterAdvice(SecurityContextHolderStrategy strategy) {
|
||||||
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
|
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
|
||||||
pointcut.setPattern(".*MethodSecurityServiceImpl.*securedUser");
|
pointcut.setPattern(".*MethodSecurityServiceImpl.*securedUser");
|
||||||
MethodInterceptor interceptor = (mi) -> {
|
MethodInterceptor interceptor = (mi) -> {
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Authentication auth = strategy.getContext().getAuthentication();
|
||||||
if ("bob".equals(auth.getName())) {
|
if ("bob".equals(auth.getName())) {
|
||||||
return "granted";
|
return "granted";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2017 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,6 +19,7 @@ package org.springframework.security.config.test;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import jakarta.servlet.Filter;
|
import jakarta.servlet.Filter;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
|
@ -56,6 +57,8 @@ public class SpringTestContext implements Closeable {
|
||||||
|
|
||||||
private List<Filter> filters = new ArrayList<>();
|
private List<Filter> filters = new ArrayList<>();
|
||||||
|
|
||||||
|
private List<Consumer<ConfigurableWebApplicationContext>> postProcessors = new ArrayList<>();
|
||||||
|
|
||||||
public SpringTestContext(Object test) {
|
public SpringTestContext(Object test) {
|
||||||
setTest(test);
|
setTest(test);
|
||||||
}
|
}
|
||||||
|
@ -104,6 +107,11 @@ public class SpringTestContext implements Closeable {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SpringTestContext postProcessor(Consumer<ConfigurableWebApplicationContext> contextConsumer) {
|
||||||
|
this.postProcessors.add(contextConsumer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public SpringTestContext mockMvcAfterSpringSecurityOk() {
|
public SpringTestContext mockMvcAfterSpringSecurityOk() {
|
||||||
return addFilter(new OncePerRequestFilter() {
|
return addFilter(new OncePerRequestFilter() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -131,6 +139,9 @@ public class SpringTestContext implements Closeable {
|
||||||
public void autowire() {
|
public void autowire() {
|
||||||
this.context.setServletContext(new MockServletContext());
|
this.context.setServletContext(new MockServletContext());
|
||||||
this.context.setServletConfig(new MockServletConfig());
|
this.context.setServletConfig(new MockServletConfig());
|
||||||
|
for (Consumer<ConfigurableWebApplicationContext> postProcessor : this.postProcessors) {
|
||||||
|
postProcessor.accept(this.context);
|
||||||
|
}
|
||||||
this.context.refresh();
|
this.context.refresh();
|
||||||
if (this.context.containsBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN)) {
|
if (this.context.containsBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN)) {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2022 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.security.config.test;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.test.context.TestContext;
|
||||||
|
import org.springframework.test.context.TestExecutionListener;
|
||||||
|
|
||||||
|
public class SpringTestParentApplicationContextExecutionListener implements TestExecutionListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTestMethod(TestContext testContext) throws Exception {
|
||||||
|
ApplicationContext parent = testContext.getApplicationContext();
|
||||||
|
Object testInstance = testContext.getTestInstance();
|
||||||
|
getContexts(testInstance).forEach((springTestContext) -> springTestContext
|
||||||
|
.postProcessor((applicationContext) -> applicationContext.setParent(parent)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<SpringTestContext> getContexts(Object test) throws IllegalAccessException {
|
||||||
|
Field[] declaredFields = test.getClass().getDeclaredFields();
|
||||||
|
List<SpringTestContext> result = new ArrayList<>();
|
||||||
|
for (Field field : declaredFields) {
|
||||||
|
if (SpringTestContext.class.isAssignableFrom(field.getType())) {
|
||||||
|
result.add((SpringTestContext) field.get(test));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue