Reformat code using spring-javaformat
Run `./gradlew format` to reformat all java files. Issue gh-8945
This commit is contained in:
+5
-6
@@ -46,7 +46,8 @@ import org.springframework.util.Assert;
|
||||
* </li>
|
||||
* <li>The test is ran. When used with {@link MockMvc} it is typically used with
|
||||
* {@link SecurityMockMvcRequestPostProcessors#testSecurityContext()}. Which ensures the
|
||||
* {@link SecurityContext} from {@link TestSecurityContextHolder} is properly populated.</li>
|
||||
* {@link SecurityContext} from {@link TestSecurityContextHolder} is properly
|
||||
* populated.</li>
|
||||
* <li>After the test is executed, the {@link TestSecurityContextHolder} and the
|
||||
* {@link SecurityContextHolder} are cleared out</li>
|
||||
* </ul>
|
||||
@@ -71,7 +72,6 @@ public final class TestSecurityContextHolder {
|
||||
|
||||
/**
|
||||
* Gets the {@link SecurityContext} from {@link TestSecurityContextHolder}.
|
||||
*
|
||||
* @return the {@link SecurityContext} from {@link TestSecurityContextHolder}.
|
||||
*/
|
||||
public static SecurityContext getContext() {
|
||||
@@ -97,10 +97,9 @@ public final class TestSecurityContextHolder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SecurityContext} with the given {@link Authentication}.
|
||||
* The {@link SecurityContext} is set on {@link TestSecurityContextHolder} and
|
||||
* Creates a new {@link SecurityContext} with the given {@link Authentication}. The
|
||||
* {@link SecurityContext} is set on {@link TestSecurityContextHolder} and
|
||||
* {@link SecurityContextHolder}.
|
||||
*
|
||||
* @param authentication the {@link Authentication} to use
|
||||
* @since 5.1.1
|
||||
*/
|
||||
@@ -114,7 +113,6 @@ public final class TestSecurityContextHolder {
|
||||
/**
|
||||
* Gets the default {@link SecurityContext} by delegating to the
|
||||
* {@link SecurityContextHolder}
|
||||
*
|
||||
* @return the default {@link SecurityContext}
|
||||
*/
|
||||
private static SecurityContext getDefaultContext() {
|
||||
@@ -123,4 +121,5 @@ public final class TestSecurityContextHolder {
|
||||
|
||||
private TestSecurityContextHolder() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+7
-7
@@ -28,11 +28,10 @@ import org.springframework.security.test.context.support.WithSecurityContextTest
|
||||
import org.springframework.test.context.TestExecutionListeners;
|
||||
|
||||
/**
|
||||
* There are many times a user may want to use Spring Security's test support
|
||||
* (i.e. WithMockUser) but have no need for any other
|
||||
* {@link TestExecutionListeners} (i.e. no need to setup an
|
||||
* {@link ApplicationContext}). This annotation is a meta annotation that only
|
||||
* enables Spring Security's {@link TestExecutionListeners}.
|
||||
* There are many times a user may want to use Spring Security's test support (i.e.
|
||||
* WithMockUser) but have no need for any other {@link TestExecutionListeners} (i.e. no
|
||||
* need to setup an {@link ApplicationContext}). This annotation is a meta annotation that
|
||||
* only enables Spring Security's {@link TestExecutionListeners}.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 4.0.2
|
||||
@@ -43,7 +42,8 @@ import org.springframework.test.context.TestExecutionListeners;
|
||||
@Inherited
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@TestExecutionListeners(inheritListeners = false, listeners = {WithSecurityContextTestExecutionListener.class,
|
||||
ReactorContextTestExecutionListener.class})
|
||||
@TestExecutionListeners(inheritListeners = false,
|
||||
listeners = { WithSecurityContextTestExecutionListener.class, ReactorContextTestExecutionListener.class })
|
||||
public @interface SecurityTestExecutionListeners {
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -25,8 +25,7 @@ import org.springframework.util.Assert;
|
||||
* @author Rob Winch
|
||||
* @since 5.0
|
||||
*/
|
||||
class DelegatingTestExecutionListener
|
||||
extends AbstractTestExecutionListener {
|
||||
class DelegatingTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
private final TestExecutionListener delegate;
|
||||
|
||||
@@ -69,4 +68,5 @@ class DelegatingTestExecutionListener
|
||||
public void afterTestClass(TestContext testContext) throws Exception {
|
||||
delegate.afterTestClass(testContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+16
-9
@@ -40,10 +40,10 @@ import reactor.util.context.Context;
|
||||
* @see WithSecurityContextTestExecutionListener
|
||||
* @see org.springframework.security.test.context.annotation.SecurityTestExecutionListeners
|
||||
*/
|
||||
public class ReactorContextTestExecutionListener
|
||||
extends DelegatingTestExecutionListener {
|
||||
public class ReactorContextTestExecutionListener extends DelegatingTestExecutionListener {
|
||||
|
||||
private static final String HOOKS_CLASS_NAME = "reactor.core.publisher.Hooks";
|
||||
|
||||
private static final String CONTEXT_OPERATOR_KEY = SecurityContext.class.getName();
|
||||
|
||||
public ReactorContextTestExecutionListener() {
|
||||
@@ -51,16 +51,18 @@ public class ReactorContextTestExecutionListener
|
||||
}
|
||||
|
||||
private static TestExecutionListener createDelegate() {
|
||||
return ClassUtils.isPresent(HOOKS_CLASS_NAME, ReactorContextTestExecutionListener.class.getClassLoader()) ?
|
||||
new DelegateTestExecutionListener() :
|
||||
new AbstractTestExecutionListener() {};
|
||||
return ClassUtils.isPresent(HOOKS_CLASS_NAME, ReactorContextTestExecutionListener.class.getClassLoader())
|
||||
? new DelegateTestExecutionListener() : new AbstractTestExecutionListener() {
|
||||
};
|
||||
}
|
||||
|
||||
private static class DelegateTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
@Override
|
||||
public void beforeTestMethod(TestContext testContext) {
|
||||
SecurityContext securityContext = TestSecurityContextHolder.getContext();
|
||||
Hooks.onLastOperator(CONTEXT_OPERATOR_KEY, Operators.lift((s, sub) -> new SecuritySubContext<>(sub, securityContext)));
|
||||
Hooks.onLastOperator(CONTEXT_OPERATOR_KEY,
|
||||
Operators.lift((s, sub) -> new SecuritySubContext<>(sub, securityContext)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,9 +71,12 @@ public class ReactorContextTestExecutionListener
|
||||
}
|
||||
|
||||
private static class SecuritySubContext<T> implements CoreSubscriber<T> {
|
||||
private static String CONTEXT_DEFAULTED_ATTR_NAME = SecuritySubContext.class.getName().concat(".CONTEXT_DEFAULTED_ATTR_NAME");
|
||||
|
||||
private static String CONTEXT_DEFAULTED_ATTR_NAME = SecuritySubContext.class.getName()
|
||||
.concat(".CONTEXT_DEFAULTED_ATTR_NAME");
|
||||
|
||||
private final CoreSubscriber<T> delegate;
|
||||
|
||||
private final SecurityContext securityContext;
|
||||
|
||||
SecuritySubContext(CoreSubscriber<T> delegate, SecurityContext securityContext) {
|
||||
@@ -90,8 +95,7 @@ public class ReactorContextTestExecutionListener
|
||||
if (authentication == null) {
|
||||
return context;
|
||||
}
|
||||
Context toMerge = ReactiveSecurityContextHolder.withSecurityContext(
|
||||
Mono.just(this.securityContext));
|
||||
Context toMerge = ReactiveSecurityContextHolder.withSecurityContext(Mono.just(this.securityContext));
|
||||
return toMerge.putAll(context);
|
||||
}
|
||||
|
||||
@@ -114,7 +118,9 @@ public class ReactorContextTestExecutionListener
|
||||
public void onComplete() {
|
||||
delegate.onComplete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,4 +130,5 @@ public class ReactorContextTestExecutionListener
|
||||
public int getOrder() {
|
||||
return 11000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+8
-3
@@ -19,20 +19,25 @@ package org.springframework.security.test.context.support;
|
||||
import org.springframework.test.context.TestContext;
|
||||
|
||||
/**
|
||||
* Represents the events on the methods of {@link org.springframework.test.context.TestExecutionListener}
|
||||
* Represents the events on the methods of
|
||||
* {@link org.springframework.test.context.TestExecutionListener}
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 5.1
|
||||
*/
|
||||
public enum TestExecutionEvent {
|
||||
|
||||
/**
|
||||
* Associated to {@link org.springframework.test.context.TestExecutionListener#beforeTestMethod(TestContext)}
|
||||
* Associated to
|
||||
* {@link org.springframework.test.context.TestExecutionListener#beforeTestMethod(TestContext)}
|
||||
* event.
|
||||
*/
|
||||
TEST_METHOD,
|
||||
/**
|
||||
* Associated to {@link org.springframework.test.context.TestExecutionListener#beforeTestExecution(TestContext)}
|
||||
* Associated to
|
||||
* {@link org.springframework.test.context.TestExecutionListener#beforeTestExecution(TestContext)}
|
||||
* event.
|
||||
*/
|
||||
TEST_EXECUTION
|
||||
|
||||
}
|
||||
|
||||
+8
-8
@@ -28,12 +28,12 @@ import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.test.context.TestContext;
|
||||
|
||||
/**
|
||||
* When used with {@link WithSecurityContextTestExecutionListener} this
|
||||
* annotation can be added to a test method to emulate running with an anonymous
|
||||
* user. The {@link SecurityContext} that is used will contain an
|
||||
* {@link AnonymousAuthenticationToken}. This is useful when a user wants to run
|
||||
* a majority of tests as a specific user and wishes to override a few methods
|
||||
* to be anonymous. For example:
|
||||
* When used with {@link WithSecurityContextTestExecutionListener} this annotation can be
|
||||
* added to a test method to emulate running with an anonymous user. The
|
||||
* {@link SecurityContext} that is used will contain an
|
||||
* {@link AnonymousAuthenticationToken}. This is useful when a user wants to run a
|
||||
* majority of tests as a specific user and wishes to override a few methods to be
|
||||
* anonymous. For example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
@@ -47,8 +47,7 @@ import org.springframework.test.context.TestContext;
|
||||
*
|
||||
* // ... lots of tests ran with a default user ...
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
* </code> </pre>
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 4.1
|
||||
@@ -69,4 +68,5 @@ public @interface WithAnonymousUser {
|
||||
*/
|
||||
@AliasFor(annotation = WithSecurityContext.class)
|
||||
TestExecutionEvent setupBefore() default TestExecutionEvent.TEST_METHOD;
|
||||
|
||||
}
|
||||
|
||||
+4
-5
@@ -25,17 +25,15 @@ import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* A {@link WithAnonymousUserSecurityContextFactory} that runs with an {@link AnonymousAuthenticationToken}.
|
||||
* .
|
||||
* A {@link WithAnonymousUserSecurityContextFactory} that runs with an
|
||||
* {@link AnonymousAuthenticationToken}. .
|
||||
*
|
||||
* @see WithUserDetails
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 4.1
|
||||
*/
|
||||
|
||||
final class WithAnonymousUserSecurityContextFactory implements
|
||||
WithSecurityContextFactory<WithAnonymousUser> {
|
||||
final class WithAnonymousUserSecurityContextFactory implements WithSecurityContextFactory<WithAnonymousUser> {
|
||||
|
||||
public SecurityContext createSecurityContext(WithAnonymousUser withUser) {
|
||||
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS");
|
||||
@@ -44,4 +42,5 @@ final class WithAnonymousUserSecurityContextFactory implements
|
||||
context.setAuthentication(authentication);
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
+4
-3
@@ -56,6 +56,7 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
@Documented
|
||||
@WithSecurityContext(factory = WithMockUserSecurityContextFactory.class)
|
||||
public @interface WithMockUser {
|
||||
|
||||
/**
|
||||
* Convenience mechanism for specifying the username. The default is "user". If
|
||||
* {@link #username()} is specified it will be used instead of {@link #value()}
|
||||
@@ -78,9 +79,9 @@ public @interface WithMockUser {
|
||||
* with "ROLE_". For example, the default will result in "ROLE_USER" being used.
|
||||
* </p>
|
||||
* <p>
|
||||
* If {@link #authorities()} is specified this property cannot be changed from the default.
|
||||
* If {@link #authorities()} is specified this property cannot be changed from the
|
||||
* default.
|
||||
* </p>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String[] roles() default { "USER" };
|
||||
@@ -94,7 +95,6 @@ public @interface WithMockUser {
|
||||
* If this property is specified then {@link #roles()} is not used. This differs from
|
||||
* {@link #roles()} in that it does not prefix the values passed in automatically.
|
||||
* </p>
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String[] authorities() default {};
|
||||
@@ -114,4 +114,5 @@ public @interface WithMockUser {
|
||||
*/
|
||||
@AliasFor(annotation = WithSecurityContext.class)
|
||||
TestExecutionEvent setupBefore() default TestExecutionEvent.TEST_METHOD;
|
||||
|
||||
}
|
||||
|
||||
+13
-14
@@ -35,15 +35,13 @@ import org.springframework.util.StringUtils;
|
||||
* @since 4.0
|
||||
* @see WithMockUser
|
||||
*/
|
||||
final class WithMockUserSecurityContextFactory implements
|
||||
WithSecurityContextFactory<WithMockUser> {
|
||||
final class WithMockUserSecurityContextFactory implements WithSecurityContextFactory<WithMockUser> {
|
||||
|
||||
public SecurityContext createSecurityContext(WithMockUser withUser) {
|
||||
String username = StringUtils.hasLength(withUser.username()) ? withUser
|
||||
.username() : withUser.value();
|
||||
String username = StringUtils.hasLength(withUser.username()) ? withUser.username() : withUser.value();
|
||||
if (username == null) {
|
||||
throw new IllegalArgumentException(withUser
|
||||
+ " cannot have null username on both username and value properties");
|
||||
throw new IllegalArgumentException(
|
||||
withUser + " cannot have null username on both username and value properties");
|
||||
}
|
||||
|
||||
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
|
||||
@@ -54,21 +52,22 @@ final class WithMockUserSecurityContextFactory implements
|
||||
if (grantedAuthorities.isEmpty()) {
|
||||
for (String role : withUser.roles()) {
|
||||
if (role.startsWith("ROLE_")) {
|
||||
throw new IllegalArgumentException("roles cannot start with ROLE_ Got "
|
||||
+ role);
|
||||
throw new IllegalArgumentException("roles cannot start with ROLE_ Got " + role);
|
||||
}
|
||||
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_" + role));
|
||||
}
|
||||
} else if (!(withUser.roles().length == 1 && "USER".equals(withUser.roles()[0]))) {
|
||||
throw new IllegalStateException("You cannot define roles attribute "+ Arrays.asList(withUser.roles())+" with authorities attribute "+ Arrays.asList(withUser.authorities()));
|
||||
}
|
||||
else if (!(withUser.roles().length == 1 && "USER".equals(withUser.roles()[0]))) {
|
||||
throw new IllegalStateException("You cannot define roles attribute " + Arrays.asList(withUser.roles())
|
||||
+ " with authorities attribute " + Arrays.asList(withUser.authorities()));
|
||||
}
|
||||
|
||||
User principal = new User(username, withUser.password(), true, true, true, true,
|
||||
grantedAuthorities);
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(
|
||||
principal, principal.getPassword(), principal.getAuthorities());
|
||||
User principal = new User(username, withUser.password(), true, true, true, true, grantedAuthorities);
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(),
|
||||
principal.getAuthorities());
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
context.setAuthentication(authentication);
|
||||
return context;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -54,11 +54,11 @@ import org.springframework.test.context.TestContext;
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface WithSecurityContext {
|
||||
|
||||
/**
|
||||
* The {@link WithUserDetailsSecurityContextFactory} to use to create the
|
||||
* {@link SecurityContext}. It can contain {@link Autowired} and other Spring
|
||||
* annotations.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Class<? extends WithSecurityContextFactory<? extends Annotation>> factory();
|
||||
|
||||
+1
-2
@@ -25,7 +25,6 @@ import org.springframework.security.test.context.TestSecurityContextHolder;
|
||||
* {@link SecurityContext} that is populated in the {@link TestSecurityContextHolder}.
|
||||
*
|
||||
* @author Rob Winch
|
||||
*
|
||||
* @param <A>
|
||||
* @see WithSecurityContext
|
||||
* @see WithMockUser
|
||||
@@ -36,10 +35,10 @@ public interface WithSecurityContextFactory<A extends Annotation> {
|
||||
|
||||
/**
|
||||
* Create a {@link SecurityContext} given an Annotation.
|
||||
*
|
||||
* @param annotation the {@link Annotation} to create the {@link SecurityContext}
|
||||
* from. Cannot be null.
|
||||
* @return the {@link SecurityContext} to use. Cannot be null.
|
||||
*/
|
||||
SecurityContext createSecurityContext(A annotation);
|
||||
|
||||
}
|
||||
+31
-37
@@ -47,10 +47,10 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
* @see ReactorContextTestExecutionListener
|
||||
* @see org.springframework.security.test.context.annotation.SecurityTestExecutionListeners
|
||||
*/
|
||||
public class WithSecurityContextTestExecutionListener
|
||||
extends AbstractTestExecutionListener {
|
||||
public class WithSecurityContextTestExecutionListener extends AbstractTestExecutionListener {
|
||||
|
||||
static final String SECURITY_CONTEXT_ATTR_NAME = WithSecurityContextTestExecutionListener.class.getName().concat(".SECURITY_CONTEXT");
|
||||
static final String SECURITY_CONTEXT_ATTR_NAME = WithSecurityContextTestExecutionListener.class.getName()
|
||||
.concat(".SECURITY_CONTEXT");
|
||||
|
||||
/**
|
||||
* Sets up the {@link SecurityContext} for each test method. First the specific method
|
||||
@@ -60,21 +60,19 @@ public class WithSecurityContextTestExecutionListener
|
||||
*/
|
||||
@Override
|
||||
public void beforeTestMethod(TestContext testContext) {
|
||||
TestSecurityContext testSecurityContext = createTestSecurityContext(
|
||||
testContext.getTestMethod(), testContext);
|
||||
TestSecurityContext testSecurityContext = createTestSecurityContext(testContext.getTestMethod(), testContext);
|
||||
if (testSecurityContext == null) {
|
||||
testSecurityContext = createTestSecurityContext(testContext.getTestClass(),
|
||||
testContext);
|
||||
testSecurityContext = createTestSecurityContext(testContext.getTestClass(), testContext);
|
||||
}
|
||||
if (testSecurityContext == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Supplier<SecurityContext> supplier = testSecurityContext
|
||||
.getSecurityContextSupplier();
|
||||
Supplier<SecurityContext> supplier = testSecurityContext.getSecurityContextSupplier();
|
||||
if (testSecurityContext.getTestExecutionEvent() == TestExecutionEvent.TEST_METHOD) {
|
||||
TestSecurityContextHolder.setContext(supplier.get());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
testContext.setAttribute(SECURITY_CONTEXT_ATTR_NAME, supplier);
|
||||
}
|
||||
}
|
||||
@@ -92,19 +90,17 @@ public class WithSecurityContextTestExecutionListener
|
||||
}
|
||||
}
|
||||
|
||||
private TestSecurityContext createTestSecurityContext(AnnotatedElement annotated,
|
||||
TestContext context) {
|
||||
WithSecurityContext withSecurityContext = AnnotatedElementUtils
|
||||
.findMergedAnnotation(annotated, WithSecurityContext.class);
|
||||
private TestSecurityContext createTestSecurityContext(AnnotatedElement annotated, TestContext context) {
|
||||
WithSecurityContext withSecurityContext = AnnotatedElementUtils.findMergedAnnotation(annotated,
|
||||
WithSecurityContext.class);
|
||||
return createTestSecurityContext(annotated, withSecurityContext, context);
|
||||
}
|
||||
|
||||
private TestSecurityContext createTestSecurityContext(Class<?> annotated,
|
||||
TestContext context) {
|
||||
private TestSecurityContext createTestSecurityContext(Class<?> annotated, TestContext context) {
|
||||
MetaAnnotationUtils.AnnotationDescriptor<WithSecurityContext> withSecurityContextDescriptor = MetaAnnotationUtils
|
||||
.findAnnotationDescriptor(annotated, WithSecurityContext.class);
|
||||
WithSecurityContext withSecurityContext = withSecurityContextDescriptor == null
|
||||
? null : withSecurityContextDescriptor.getAnnotation();
|
||||
WithSecurityContext withSecurityContext = withSecurityContextDescriptor == null ? null
|
||||
: withSecurityContextDescriptor.getAnnotation();
|
||||
return createTestSecurityContext(annotated, withSecurityContext, context);
|
||||
}
|
||||
|
||||
@@ -114,35 +110,32 @@ public class WithSecurityContextTestExecutionListener
|
||||
if (withSecurityContext == null) {
|
||||
return null;
|
||||
}
|
||||
withSecurityContext = AnnotationUtils
|
||||
.synthesizeAnnotation(withSecurityContext, annotated);
|
||||
withSecurityContext = AnnotationUtils.synthesizeAnnotation(withSecurityContext, annotated);
|
||||
WithSecurityContextFactory factory = createFactory(withSecurityContext, context);
|
||||
Class<? extends Annotation> type = (Class<? extends Annotation>) GenericTypeResolver
|
||||
.resolveTypeArgument(factory.getClass(),
|
||||
WithSecurityContextFactory.class);
|
||||
.resolveTypeArgument(factory.getClass(), WithSecurityContextFactory.class);
|
||||
Annotation annotation = findAnnotation(annotated, type);
|
||||
Supplier<SecurityContext> supplier = () -> {
|
||||
try {
|
||||
return factory.createSecurityContext(annotation);
|
||||
} catch (RuntimeException e) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to create SecurityContext using " + annotation, e);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw new IllegalStateException("Unable to create SecurityContext using " + annotation, e);
|
||||
}
|
||||
};
|
||||
TestExecutionEvent initialize = withSecurityContext.setupBefore();
|
||||
return new TestSecurityContext(supplier, initialize);
|
||||
}
|
||||
|
||||
private Annotation findAnnotation(AnnotatedElement annotated,
|
||||
Class<? extends Annotation> type) {
|
||||
private Annotation findAnnotation(AnnotatedElement annotated, Class<? extends Annotation> type) {
|
||||
Annotation findAnnotation = AnnotationUtils.findAnnotation(annotated, type);
|
||||
if (findAnnotation != null) {
|
||||
return findAnnotation;
|
||||
}
|
||||
Annotation[] allAnnotations = AnnotationUtils.getAnnotations(annotated);
|
||||
for (Annotation annotationToTest : allAnnotations) {
|
||||
WithSecurityContext withSecurityContext = AnnotationUtils.findAnnotation(
|
||||
annotationToTest.annotationType(), WithSecurityContext.class);
|
||||
WithSecurityContext withSecurityContext = AnnotationUtils.findAnnotation(annotationToTest.annotationType(),
|
||||
WithSecurityContext.class);
|
||||
if (withSecurityContext != null) {
|
||||
return annotationToTest;
|
||||
}
|
||||
@@ -150,13 +143,11 @@ public class WithSecurityContextTestExecutionListener
|
||||
return null;
|
||||
}
|
||||
|
||||
private WithSecurityContextFactory<? extends Annotation> createFactory(
|
||||
WithSecurityContext withSecurityContext, TestContext testContext) {
|
||||
Class<? extends WithSecurityContextFactory<? extends Annotation>> clazz = withSecurityContext
|
||||
.factory();
|
||||
private WithSecurityContextFactory<? extends Annotation> createFactory(WithSecurityContext withSecurityContext,
|
||||
TestContext testContext) {
|
||||
Class<? extends WithSecurityContextFactory<? extends Annotation>> clazz = withSecurityContext.factory();
|
||||
try {
|
||||
return testContext.getApplicationContext().getAutowireCapableBeanFactory()
|
||||
.createBean(clazz);
|
||||
return testContext.getApplicationContext().getAutowireCapableBeanFactory().createBean(clazz);
|
||||
}
|
||||
catch (IllegalStateException e) {
|
||||
return BeanUtils.instantiateClass(clazz);
|
||||
@@ -184,11 +175,12 @@ public class WithSecurityContextTestExecutionListener
|
||||
}
|
||||
|
||||
static class TestSecurityContext {
|
||||
|
||||
private final Supplier<SecurityContext> securityContextSupplier;
|
||||
|
||||
private final TestExecutionEvent testExecutionEvent;
|
||||
|
||||
TestSecurityContext(Supplier<SecurityContext> securityContextSupplier,
|
||||
TestExecutionEvent testExecutionEvent) {
|
||||
TestSecurityContext(Supplier<SecurityContext> securityContextSupplier, TestExecutionEvent testExecutionEvent) {
|
||||
this.securityContextSupplier = securityContextSupplier;
|
||||
this.testExecutionEvent = testExecutionEvent;
|
||||
}
|
||||
@@ -200,5 +192,7 @@ public class WithSecurityContextTestExecutionListener
|
||||
public TestExecutionEvent getTestExecutionEvent() {
|
||||
return this.testExecutionEvent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -55,18 +55,17 @@ import org.springframework.test.web.servlet.MockMvc;
|
||||
@Documented
|
||||
@WithSecurityContext(factory = WithUserDetailsSecurityContextFactory.class)
|
||||
public @interface WithUserDetails {
|
||||
|
||||
/**
|
||||
* The username to look up in the {@link UserDetailsService}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String value() default "user";
|
||||
|
||||
/**
|
||||
* The bean name for the {@link UserDetailsService} to use. If this is not
|
||||
* provided, then the lookup is done by type and expects only a single
|
||||
* The bean name for the {@link UserDetailsService} to use. If this is not provided,
|
||||
* then the lookup is done by type and expects only a single
|
||||
* {@link UserDetailsService} bean to be exposed.
|
||||
*
|
||||
* @return the bean name for the {@link UserDetailsService} to use.
|
||||
* @since 4.1
|
||||
*/
|
||||
@@ -81,4 +80,5 @@ public @interface WithUserDetails {
|
||||
*/
|
||||
@AliasFor(annotation = WithSecurityContext.class)
|
||||
TestExecutionEvent setupBefore() default TestExecutionEvent.TEST_METHOD;
|
||||
|
||||
}
|
||||
|
||||
+17
-18
@@ -36,15 +36,14 @@ import org.springframework.util.StringUtils;
|
||||
* .
|
||||
*
|
||||
* @see WithUserDetails
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 4.0
|
||||
*/
|
||||
|
||||
final class WithUserDetailsSecurityContextFactory implements
|
||||
WithSecurityContextFactory<WithUserDetails> {
|
||||
final class WithUserDetailsSecurityContextFactory implements WithSecurityContextFactory<WithUserDetails> {
|
||||
|
||||
private static final boolean reactorPresent = ClassUtils.isPresent("reactor.core.publisher.Mono", WithUserDetailsSecurityContextFactory.class.getClassLoader());
|
||||
private static final boolean reactorPresent = ClassUtils.isPresent("reactor.core.publisher.Mono",
|
||||
WithUserDetailsSecurityContextFactory.class.getClassLoader());
|
||||
|
||||
private BeanFactory beans;
|
||||
|
||||
@@ -59,8 +58,8 @@ final class WithUserDetailsSecurityContextFactory implements
|
||||
String username = withUser.value();
|
||||
Assert.hasLength(username, "value() must be non empty String");
|
||||
UserDetails principal = userDetailsService.loadUserByUsername(username);
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(
|
||||
principal, principal.getPassword(), principal.getAuthorities());
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(principal, principal.getPassword(),
|
||||
principal.getAuthorities());
|
||||
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||
context.setAuthentication(authentication);
|
||||
return context;
|
||||
@@ -73,35 +72,35 @@ final class WithUserDetailsSecurityContextFactory implements
|
||||
return reactive;
|
||||
}
|
||||
}
|
||||
return StringUtils.hasLength(beanName)
|
||||
? this.beans.getBean(beanName, UserDetailsService.class)
|
||||
: this.beans.getBean(UserDetailsService.class);
|
||||
return StringUtils.hasLength(beanName) ? this.beans.getBean(beanName, UserDetailsService.class)
|
||||
: this.beans.getBean(UserDetailsService.class);
|
||||
}
|
||||
|
||||
public UserDetailsService findAndAdaptReactiveUserDetailsService(String beanName) {
|
||||
try {
|
||||
ReactiveUserDetailsService reactiveUserDetailsService = StringUtils
|
||||
.hasLength(beanName) ?
|
||||
this.beans.getBean(beanName, ReactiveUserDetailsService.class) :
|
||||
this.beans.getBean(ReactiveUserDetailsService.class);
|
||||
ReactiveUserDetailsService reactiveUserDetailsService = StringUtils.hasLength(beanName)
|
||||
? this.beans.getBean(beanName, ReactiveUserDetailsService.class)
|
||||
: this.beans.getBean(ReactiveUserDetailsService.class);
|
||||
return new ReactiveUserDetailsServiceAdapter(reactiveUserDetailsService);
|
||||
} catch(NoSuchBeanDefinitionException | BeanNotOfRequiredTypeException notReactive) {
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException | BeanNotOfRequiredTypeException notReactive) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class ReactiveUserDetailsServiceAdapter implements UserDetailsService {
|
||||
|
||||
private final ReactiveUserDetailsService userDetailsService;
|
||||
|
||||
private ReactiveUserDetailsServiceAdapter(
|
||||
ReactiveUserDetailsService userDetailsService) {
|
||||
private ReactiveUserDetailsServiceAdapter(ReactiveUserDetailsService userDetailsService) {
|
||||
this.userDetailsService = userDetailsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username)
|
||||
throws UsernameNotFoundException {
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
return this.userDetailsService.findByUsername(username).block();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+221
-229
File diff suppressed because it is too large
Load Diff
+26
-28
@@ -42,7 +42,6 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
/**
|
||||
* Creates a request (including any necessary {@link CsrfToken}) that will submit a
|
||||
* form based login to POST "/login".
|
||||
*
|
||||
* @return the FormLoginRequestBuilder for further customizations
|
||||
*/
|
||||
public static FormLoginRequestBuilder formLogin() {
|
||||
@@ -52,9 +51,7 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
/**
|
||||
* Creates a request (including any necessary {@link CsrfToken}) that will submit a
|
||||
* form based login to POST {@code loginProcessingUrl}.
|
||||
*
|
||||
* @param loginProcessingUrl the URL to POST to
|
||||
*
|
||||
* @return the FormLoginRequestBuilder for further customizations
|
||||
*/
|
||||
public static FormLoginRequestBuilder formLogin(String loginProcessingUrl) {
|
||||
@@ -63,7 +60,6 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
|
||||
/**
|
||||
* Creates a logout request.
|
||||
*
|
||||
* @return the LogoutRequestBuilder for additional customizations
|
||||
*/
|
||||
public static LogoutRequestBuilder logout() {
|
||||
@@ -73,9 +69,7 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
/**
|
||||
* Creates a logout request (including any necessary {@link CsrfToken}) to the
|
||||
* specified {@code logoutUrl}
|
||||
*
|
||||
* @param logoutUrl the logout request URL
|
||||
*
|
||||
* @return the LogoutRequestBuilder for additional customizations
|
||||
*/
|
||||
public static LogoutRequestBuilder logout(String logoutUrl) {
|
||||
@@ -89,14 +83,17 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final class LogoutRequestBuilder implements RequestBuilder, Mergeable {
|
||||
|
||||
private String logoutUrl = "/logout";
|
||||
|
||||
private RequestPostProcessor postProcessor = csrf();
|
||||
|
||||
private Mergeable parent;
|
||||
|
||||
@Override
|
||||
public MockHttpServletRequest buildRequest(ServletContext servletContext) {
|
||||
MockHttpServletRequestBuilder logoutRequest = post(this.logoutUrl)
|
||||
.accept(MediaType.TEXT_HTML, MediaType.ALL);
|
||||
MockHttpServletRequestBuilder logoutRequest = post(this.logoutUrl).accept(MediaType.TEXT_HTML,
|
||||
MediaType.ALL);
|
||||
|
||||
if (this.parent != null) {
|
||||
logoutRequest = (MockHttpServletRequestBuilder) logoutRequest.merge(this.parent);
|
||||
@@ -110,7 +107,6 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
|
||||
/**
|
||||
* Specifies the logout URL to POST to. Defaults to "/logout".
|
||||
*
|
||||
* @param logoutUrl the logout URL to POST to. Defaults to "/logout".
|
||||
* @return the {@link LogoutRequestBuilder} for additional customizations
|
||||
*/
|
||||
@@ -121,14 +117,12 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
|
||||
/**
|
||||
* Specifies the logout URL to POST to.
|
||||
*
|
||||
* @param logoutUrl the logout URL to POST to.
|
||||
* @param uriVars the URI variables
|
||||
* @return the {@link LogoutRequestBuilder} for additional customizations
|
||||
*/
|
||||
public LogoutRequestBuilder logoutUrl(String logoutUrl, Object... uriVars) {
|
||||
this.logoutUrl = UriComponentsBuilder.fromPath(logoutUrl)
|
||||
.buildAndExpand(uriVars).encode().toString();
|
||||
this.logoutUrl = UriComponentsBuilder.fromPath(logoutUrl).buildAndExpand(uriVars).encode().toString();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -145,13 +139,15 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
if (parent instanceof Mergeable) {
|
||||
this.parent = (Mergeable) parent;
|
||||
return this;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Cannot merge with [" + parent.getClass().getName() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private LogoutRequestBuilder() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,22 +157,27 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final class FormLoginRequestBuilder implements RequestBuilder, Mergeable {
|
||||
|
||||
private String usernameParam = "username";
|
||||
|
||||
private String passwordParam = "password";
|
||||
|
||||
private String username = "user";
|
||||
|
||||
private String password = "password";
|
||||
|
||||
private String loginProcessingUrl = "/login";
|
||||
|
||||
private MediaType acceptMediaType = MediaType.APPLICATION_FORM_URLENCODED;
|
||||
|
||||
private Mergeable parent;
|
||||
|
||||
private RequestPostProcessor postProcessor = csrf();
|
||||
|
||||
@Override
|
||||
public MockHttpServletRequest buildRequest(ServletContext servletContext) {
|
||||
MockHttpServletRequestBuilder loginRequest = post(this.loginProcessingUrl)
|
||||
.accept(this.acceptMediaType)
|
||||
.param(this.usernameParam, this.username)
|
||||
.param(this.passwordParam, this.password);
|
||||
MockHttpServletRequestBuilder loginRequest = post(this.loginProcessingUrl).accept(this.acceptMediaType)
|
||||
.param(this.usernameParam, this.username).param(this.passwordParam, this.password);
|
||||
|
||||
if (this.parent != null) {
|
||||
loginRequest = (MockHttpServletRequestBuilder) loginRequest.merge(this.parent);
|
||||
@@ -190,7 +191,6 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
|
||||
/**
|
||||
* Specifies the URL to POST to. Default is "/login"
|
||||
*
|
||||
* @param loginProcessingUrl the URL to POST to. Default is "/login"
|
||||
* @return the {@link FormLoginRequestBuilder} for additional customizations
|
||||
*/
|
||||
@@ -201,14 +201,13 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
|
||||
/**
|
||||
* Specifies the URL to POST to.
|
||||
*
|
||||
* @param loginProcessingUrl the URL to POST to
|
||||
* @param uriVars the URI variables
|
||||
* @return the {@link FormLoginRequestBuilder} for additional customizations
|
||||
*/
|
||||
public FormLoginRequestBuilder loginProcessingUrl(String loginProcessingUrl, Object... uriVars) {
|
||||
this.loginProcessingUrl = UriComponentsBuilder.fromPath(loginProcessingUrl)
|
||||
.buildAndExpand(uriVars).encode().toString();
|
||||
this.loginProcessingUrl = UriComponentsBuilder.fromPath(loginProcessingUrl).buildAndExpand(uriVars).encode()
|
||||
.toString();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -256,14 +255,12 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
|
||||
/**
|
||||
* Specify both the password parameter name and the password.
|
||||
*
|
||||
* @param passwordParameter the HTTP parameter to place the password. Default is
|
||||
* "password".
|
||||
* @param password the value of the password parameter. Default is "password".
|
||||
* @return the {@link FormLoginRequestBuilder} for additional customizations
|
||||
*/
|
||||
public FormLoginRequestBuilder password(String passwordParameter,
|
||||
String password) {
|
||||
public FormLoginRequestBuilder password(String passwordParameter, String password) {
|
||||
passwordParam(passwordParameter);
|
||||
this.password = password;
|
||||
return this;
|
||||
@@ -271,7 +268,6 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
|
||||
/**
|
||||
* Specify both the password parameter name and the password.
|
||||
*
|
||||
* @param usernameParameter the HTTP parameter to place the username. Default is
|
||||
* "username".
|
||||
* @param username the value of the username parameter. Default is "user".
|
||||
@@ -285,7 +281,6 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
|
||||
/**
|
||||
* Specify a media type to set as the Accept header in the request.
|
||||
*
|
||||
* @param acceptMediaType the {@link MediaType} to set the Accept header to.
|
||||
* Default is: MediaType.APPLICATION_FORM_URLENCODED
|
||||
* @return the {@link FormLoginRequestBuilder} for additional customizations
|
||||
@@ -305,18 +300,21 @@ public final class SecurityMockMvcRequestBuilders {
|
||||
if (parent == null) {
|
||||
return this;
|
||||
}
|
||||
if (parent instanceof Mergeable ) {
|
||||
if (parent instanceof Mergeable) {
|
||||
this.parent = (Mergeable) parent;
|
||||
return this;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Cannot merge with [" + parent.getClass().getName() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private FormLoginRequestBuilder() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private SecurityMockMvcRequestBuilders() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+216
-257
File diff suppressed because it is too large
Load Diff
+24
-39
@@ -46,7 +46,6 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
/**
|
||||
* {@link ResultMatcher} that verifies that a specified user is authenticated.
|
||||
*
|
||||
* @return the {@link AuthenticatedMatcher} to use
|
||||
*/
|
||||
public static AuthenticatedMatcher authenticated() {
|
||||
@@ -55,23 +54,20 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
/**
|
||||
* {@link ResultMatcher} that verifies that no user is authenticated.
|
||||
*
|
||||
* @return the {@link AuthenticatedMatcher} to use
|
||||
*/
|
||||
public static ResultMatcher unauthenticated() {
|
||||
return new UnAuthenticatedMatcher();
|
||||
}
|
||||
|
||||
private static abstract class AuthenticationMatcher<T extends AuthenticationMatcher<T>>
|
||||
implements ResultMatcher {
|
||||
private static abstract class AuthenticationMatcher<T extends AuthenticationMatcher<T>> implements ResultMatcher {
|
||||
|
||||
protected SecurityContext load(MvcResult result) {
|
||||
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(
|
||||
result.getRequest(), result.getResponse());
|
||||
SecurityContextRepository repository = WebTestUtils
|
||||
.getSecurityContextRepository(result.getRequest());
|
||||
HttpRequestResponseHolder holder = new HttpRequestResponseHolder(result.getRequest(), result.getResponse());
|
||||
SecurityContextRepository repository = WebTestUtils.getSecurityContextRepository(result.getRequest());
|
||||
return repository.loadContext(holder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,14 +77,18 @@ public final class SecurityMockMvcResultMatchers {
|
||||
* @author Rob Winch
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final class AuthenticatedMatcher
|
||||
extends AuthenticationMatcher<AuthenticatedMatcher> {
|
||||
public static final class AuthenticatedMatcher extends AuthenticationMatcher<AuthenticatedMatcher> {
|
||||
|
||||
private SecurityContext expectedContext;
|
||||
|
||||
private Authentication expectedAuthentication;
|
||||
|
||||
private Object expectedAuthenticationPrincipal;
|
||||
|
||||
private String expectedAuthenticationName;
|
||||
|
||||
private Collection<? extends GrantedAuthority> expectedGrantedAuthorities;
|
||||
|
||||
private Consumer<Authentication> assertAuthentication;
|
||||
|
||||
@Override
|
||||
@@ -104,25 +104,20 @@ public final class SecurityMockMvcResultMatchers {
|
||||
}
|
||||
|
||||
if (this.expectedContext != null) {
|
||||
assertEquals(this.expectedContext + " does not equal " + context,
|
||||
this.expectedContext, context);
|
||||
assertEquals(this.expectedContext + " does not equal " + context, this.expectedContext, context);
|
||||
}
|
||||
|
||||
if (this.expectedAuthentication != null) {
|
||||
assertEquals(
|
||||
this.expectedAuthentication + " does not equal "
|
||||
+ context.getAuthentication(),
|
||||
assertEquals(this.expectedAuthentication + " does not equal " + context.getAuthentication(),
|
||||
this.expectedAuthentication, context.getAuthentication());
|
||||
}
|
||||
|
||||
if (this.expectedAuthenticationPrincipal != null) {
|
||||
assertTrue("Authentication cannot be null",
|
||||
context.getAuthentication() != null);
|
||||
assertTrue("Authentication cannot be null", context.getAuthentication() != null);
|
||||
assertEquals(
|
||||
this.expectedAuthenticationPrincipal + " does not equal "
|
||||
+ context.getAuthentication().getPrincipal(),
|
||||
this.expectedAuthenticationPrincipal,
|
||||
context.getAuthentication().getPrincipal());
|
||||
this.expectedAuthenticationPrincipal, context.getAuthentication().getPrincipal());
|
||||
}
|
||||
|
||||
if (this.expectedAuthenticationName != null) {
|
||||
@@ -134,14 +129,10 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
if (this.expectedGrantedAuthorities != null) {
|
||||
assertTrue("Authentication cannot be null", auth != null);
|
||||
Collection<? extends GrantedAuthority> authorities = auth
|
||||
.getAuthorities();
|
||||
assertTrue(
|
||||
authorities + " does not contain the same authorities as "
|
||||
+ this.expectedGrantedAuthorities,
|
||||
Collection<? extends GrantedAuthority> authorities = auth.getAuthorities();
|
||||
assertTrue(authorities + " does not contain the same authorities as " + this.expectedGrantedAuthorities,
|
||||
authorities.containsAll(this.expectedGrantedAuthorities));
|
||||
assertTrue(this.expectedGrantedAuthorities
|
||||
+ " does not contain the same authorities as " + authorities,
|
||||
assertTrue(this.expectedGrantedAuthorities + " does not contain the same authorities as " + authorities,
|
||||
this.expectedGrantedAuthorities.containsAll(authorities));
|
||||
}
|
||||
}
|
||||
@@ -158,7 +149,6 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
/**
|
||||
* Specifies the expected username
|
||||
*
|
||||
* @param expected the expected username
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
@@ -168,7 +158,6 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
/**
|
||||
* Specifies the expected {@link SecurityContext}
|
||||
*
|
||||
* @param expected the expected {@link SecurityContext}
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
@@ -179,7 +168,6 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
/**
|
||||
* Specifies the expected {@link Authentication}
|
||||
*
|
||||
* @param expected the expected {@link Authentication}
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
@@ -190,7 +178,6 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
/**
|
||||
* Specifies the expected principal
|
||||
*
|
||||
* @param expected the expected principal
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
@@ -201,7 +188,6 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
/**
|
||||
* Specifies the expected {@link Authentication#getName()}
|
||||
*
|
||||
* @param expected the expected {@link Authentication#getName()}
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
@@ -212,19 +198,16 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
/**
|
||||
* Specifies the {@link Authentication#getAuthorities()}
|
||||
*
|
||||
* @param expected the {@link Authentication#getAuthorities()}
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
public AuthenticatedMatcher withAuthorities(
|
||||
Collection<? extends GrantedAuthority> expected) {
|
||||
public AuthenticatedMatcher withAuthorities(Collection<? extends GrantedAuthority> expected) {
|
||||
this.expectedGrantedAuthorities = expected;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the {@link Authentication#getAuthorities()}
|
||||
*
|
||||
* @param roles the roles. Each value is automatically prefixed with "ROLE_"
|
||||
* @return the {@link AuthenticatedMatcher} for further customization
|
||||
*/
|
||||
@@ -238,6 +221,7 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
AuthenticatedMatcher() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,8 +231,8 @@ public final class SecurityMockMvcResultMatchers {
|
||||
* @author Rob Winch
|
||||
* @since 4.0
|
||||
*/
|
||||
private static final class UnAuthenticatedMatcher
|
||||
extends AuthenticationMatcher<UnAuthenticatedMatcher> {
|
||||
private static final class UnAuthenticatedMatcher extends AuthenticationMatcher<UnAuthenticatedMatcher> {
|
||||
|
||||
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
||||
|
||||
@Override
|
||||
@@ -257,14 +241,15 @@ public final class SecurityMockMvcResultMatchers {
|
||||
|
||||
Authentication authentication = context.getAuthentication();
|
||||
assertTrue("Expected anonymous Authentication got " + context,
|
||||
authentication == null
|
||||
|| this.trustResolver.isAnonymous(authentication));
|
||||
authentication == null || this.trustResolver.isAnonymous(authentication));
|
||||
}
|
||||
|
||||
private UnAuthenticatedMatcher() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private SecurityMockMvcResultMatchers() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-19
@@ -41,6 +41,7 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock
|
||||
* @since 4.0
|
||||
*/
|
||||
final class SecurityMockMvcConfigurer extends MockMvcConfigurerAdapter {
|
||||
|
||||
private final DelegateFilter delegateFilter;
|
||||
|
||||
/**
|
||||
@@ -64,25 +65,20 @@ final class SecurityMockMvcConfigurer extends MockMvcConfigurerAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestPostProcessor beforeMockMvcCreated(
|
||||
ConfigurableMockMvcBuilder<?> builder, WebApplicationContext context) {
|
||||
public RequestPostProcessor beforeMockMvcCreated(ConfigurableMockMvcBuilder<?> builder,
|
||||
WebApplicationContext context) {
|
||||
String securityBeanId = BeanIds.SPRING_SECURITY_FILTER_CHAIN;
|
||||
if (getSpringSecurityFilterChain() == null
|
||||
&& context.containsBean(securityBeanId)) {
|
||||
setSpringSecurityFitlerChain(context.getBean(securityBeanId,
|
||||
Filter.class));
|
||||
if (getSpringSecurityFilterChain() == null && context.containsBean(securityBeanId)) {
|
||||
setSpringSecurityFitlerChain(context.getBean(securityBeanId, Filter.class));
|
||||
}
|
||||
|
||||
if (getSpringSecurityFilterChain() == null) {
|
||||
throw new IllegalStateException(
|
||||
"springSecurityFilterChain cannot be null. Ensure a Bean with the name "
|
||||
+ securityBeanId
|
||||
+ " implementing Filter is present or inject the Filter to be used.");
|
||||
throw new IllegalStateException("springSecurityFilterChain cannot be null. Ensure a Bean with the name "
|
||||
+ securityBeanId + " implementing Filter is present or inject the Filter to be used.");
|
||||
}
|
||||
|
||||
// This is used by other test support to obtain the FilterChainProxy
|
||||
context.getServletContext().setAttribute(BeanIds.SPRING_SECURITY_FILTER_CHAIN,
|
||||
getSpringSecurityFilterChain());
|
||||
context.getServletContext().setAttribute(BeanIds.SPRING_SECURITY_FILTER_CHAIN, getSpringSecurityFilterChain());
|
||||
|
||||
return testSecurityContext();
|
||||
}
|
||||
@@ -96,11 +92,13 @@ final class SecurityMockMvcConfigurer extends MockMvcConfigurerAdapter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows adding in {@link #afterConfigurerAdded(ConfigurableMockMvcBuilder)} to preserve Filter order and then
|
||||
* lazily set the delegate in {@link #beforeMockMvcCreated(ConfigurableMockMvcBuilder, WebApplicationContext)}.
|
||||
* Allows adding in {@link #afterConfigurerAdded(ConfigurableMockMvcBuilder)} to
|
||||
* preserve Filter order and then lazily set the delegate in
|
||||
* {@link #beforeMockMvcCreated(ConfigurableMockMvcBuilder, WebApplicationContext)}.
|
||||
*
|
||||
* {@link org.springframework.web.filter.DelegatingFilterProxy} is not used because it is not easy to lazily set
|
||||
* the delegate or get the delegate which is necessary for the test infrastructure.
|
||||
* {@link org.springframework.web.filter.DelegatingFilterProxy} is not used because it
|
||||
* is not easy to lazily set the delegate or get the delegate which is necessary for
|
||||
* the test infrastructure.
|
||||
*/
|
||||
static class DelegateFilter implements Filter {
|
||||
|
||||
@@ -120,9 +118,9 @@ final class SecurityMockMvcConfigurer extends MockMvcConfigurerAdapter {
|
||||
Filter getDelegate() {
|
||||
Filter result = this.delegate;
|
||||
if (result == null) {
|
||||
throw new IllegalStateException("delegate cannot be null. Ensure a Bean with the name "
|
||||
+ BeanIds.SPRING_SECURITY_FILTER_CHAIN
|
||||
+ " implementing Filter is present or inject the Filter to be used.");
|
||||
throw new IllegalStateException(
|
||||
"delegate cannot be null. Ensure a Bean with the name " + BeanIds.SPRING_SECURITY_FILTER_CHAIN
|
||||
+ " implementing Filter is present or inject the Filter to be used.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -157,5 +155,7 @@ final class SecurityMockMvcConfigurer extends MockMvcConfigurerAdapter {
|
||||
public String toString() {
|
||||
return getDelegate().toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-5
@@ -28,6 +28,7 @@ import javax.servlet.Filter;
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public final class SecurityMockMvcConfigurers {
|
||||
|
||||
/**
|
||||
* Configures the MockMvcBuilder for use with Spring Security. Specifically the
|
||||
* configurer adds the Spring Bean named "springSecurityFilterChain" as a Filter. It
|
||||
@@ -35,7 +36,6 @@ public final class SecurityMockMvcConfigurers {
|
||||
* by applying
|
||||
* {@link org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors#testSecurityContext()}
|
||||
* .
|
||||
*
|
||||
* @return the {@link org.springframework.test.web.servlet.setup.MockMvcConfigurer} to
|
||||
* use
|
||||
*/
|
||||
@@ -49,15 +49,13 @@ public final class SecurityMockMvcConfigurers {
|
||||
* TestSecurityContextHolder is leveraged for each request by applying
|
||||
* {@link org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors#testSecurityContext()}
|
||||
* .
|
||||
*
|
||||
* @param springSecurityFilterChain the Filter to be added
|
||||
*
|
||||
* @return the {@link org.springframework.test.web.servlet.setup.MockMvcConfigurer} to
|
||||
* use
|
||||
*/
|
||||
public static MockMvcConfigurer springSecurity(Filter springSecurityFilterChain) {
|
||||
Assert.notNull(springSecurityFilterChain,
|
||||
"springSecurityFilterChain cannot be null");
|
||||
Assert.notNull(springSecurityFilterChain, "springSecurityFilterChain cannot be null");
|
||||
return new SecurityMockMvcConfigurer(springSecurityFilterChain);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+12
-22
@@ -41,23 +41,22 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
* @since 4.0
|
||||
*/
|
||||
public abstract class WebTestUtils {
|
||||
|
||||
private static final SecurityContextRepository DEFAULT_CONTEXT_REPO = new HttpSessionSecurityContextRepository();
|
||||
|
||||
private static final CsrfTokenRepository DEFAULT_TOKEN_REPO = new HttpSessionCsrfTokenRepository();
|
||||
|
||||
/**
|
||||
* Gets the {@link SecurityContextRepository} for the specified
|
||||
* {@link HttpServletRequest}. If one is not found, a default
|
||||
* {@link HttpSessionSecurityContextRepository} is used.
|
||||
*
|
||||
* @param request the {@link HttpServletRequest} to obtain the
|
||||
* {@link SecurityContextRepository}
|
||||
* @return the {@link SecurityContextRepository} for the specified
|
||||
* {@link HttpServletRequest}
|
||||
*/
|
||||
public static SecurityContextRepository getSecurityContextRepository(
|
||||
HttpServletRequest request) {
|
||||
SecurityContextPersistenceFilter filter = findFilter(request,
|
||||
SecurityContextPersistenceFilter.class);
|
||||
public static SecurityContextRepository getSecurityContextRepository(HttpServletRequest request) {
|
||||
SecurityContextPersistenceFilter filter = findFilter(request, SecurityContextPersistenceFilter.class);
|
||||
if (filter == null) {
|
||||
return DEFAULT_CONTEXT_REPO;
|
||||
}
|
||||
@@ -67,15 +66,13 @@ public abstract class WebTestUtils {
|
||||
/**
|
||||
* Sets the {@link SecurityContextRepository} for the specified
|
||||
* {@link HttpServletRequest}.
|
||||
*
|
||||
* @param request the {@link HttpServletRequest} to obtain the
|
||||
* {@link SecurityContextRepository}
|
||||
* @param securityContextRepository the {@link SecurityContextRepository} to set
|
||||
*/
|
||||
public static void setSecurityContextRepository(HttpServletRequest request,
|
||||
SecurityContextRepository securityContextRepository) {
|
||||
SecurityContextPersistenceFilter filter = findFilter(request,
|
||||
SecurityContextPersistenceFilter.class);
|
||||
SecurityContextPersistenceFilter filter = findFilter(request, SecurityContextPersistenceFilter.class);
|
||||
if (filter != null) {
|
||||
ReflectionTestUtils.setField(filter, "repo", securityContextRepository);
|
||||
}
|
||||
@@ -84,7 +81,6 @@ public abstract class WebTestUtils {
|
||||
/**
|
||||
* Gets the {@link CsrfTokenRepository} for the specified {@link HttpServletRequest}.
|
||||
* If one is not found, the default {@link HttpSessionCsrfTokenRepository} is used.
|
||||
*
|
||||
* @param request the {@link HttpServletRequest} to obtain the
|
||||
* {@link CsrfTokenRepository}
|
||||
* @return the {@link CsrfTokenRepository} for the specified
|
||||
@@ -95,19 +91,16 @@ public abstract class WebTestUtils {
|
||||
if (filter == null) {
|
||||
return DEFAULT_TOKEN_REPO;
|
||||
}
|
||||
return (CsrfTokenRepository) ReflectionTestUtils.getField(filter,
|
||||
"tokenRepository");
|
||||
return (CsrfTokenRepository) ReflectionTestUtils.getField(filter, "tokenRepository");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link CsrfTokenRepository} for the specified {@link HttpServletRequest}.
|
||||
*
|
||||
* @param request the {@link HttpServletRequest} to obtain the
|
||||
* {@link CsrfTokenRepository}
|
||||
* @param repository the {@link CsrfTokenRepository} to set
|
||||
*/
|
||||
public static void setCsrfTokenRepository(HttpServletRequest request,
|
||||
CsrfTokenRepository repository) {
|
||||
public static void setCsrfTokenRepository(HttpServletRequest request, CsrfTokenRepository repository) {
|
||||
CsrfFilter filter = findFilter(request, CsrfFilter.class);
|
||||
if (filter != null) {
|
||||
ReflectionTestUtils.setField(filter, "tokenRepository", repository);
|
||||
@@ -115,15 +108,13 @@ public abstract class WebTestUtils {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T extends Filter> T findFilter(HttpServletRequest request,
|
||||
Class<T> filterClass) {
|
||||
static <T extends Filter> T findFilter(HttpServletRequest request, Class<T> filterClass) {
|
||||
ServletContext servletContext = request.getServletContext();
|
||||
Filter springSecurityFilterChain = getSpringSecurityFilterChain(servletContext);
|
||||
if (springSecurityFilterChain == null) {
|
||||
return null;
|
||||
}
|
||||
List<Filter> filters = ReflectionTestUtils
|
||||
.invokeMethod(springSecurityFilterChain, "getFilters", request);
|
||||
List<Filter> filters = ReflectionTestUtils.invokeMethod(springSecurityFilterChain, "getFilters", request);
|
||||
if (filters == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -136,8 +127,7 @@ public abstract class WebTestUtils {
|
||||
}
|
||||
|
||||
private static Filter getSpringSecurityFilterChain(ServletContext servletContext) {
|
||||
Filter result = (Filter) servletContext
|
||||
.getAttribute(BeanIds.SPRING_SECURITY_FILTER_CHAIN);
|
||||
Filter result = (Filter) servletContext.getAttribute(BeanIds.SPRING_SECURITY_FILTER_CHAIN);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
@@ -145,8 +135,7 @@ public abstract class WebTestUtils {
|
||||
.getWebApplicationContext(servletContext);
|
||||
if (webApplicationContext != null) {
|
||||
try {
|
||||
return webApplicationContext.getBean(
|
||||
AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME,
|
||||
return webApplicationContext.getBean(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME,
|
||||
Filter.class);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException notFound) {
|
||||
@@ -157,4 +146,5 @@ public abstract class WebTestUtils {
|
||||
|
||||
private WebTestUtils() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user