From 327695ab0c1bf69c355400f7508b4fdf33cec5fb Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Thu, 20 Aug 2015 09:30:24 -0500 Subject: [PATCH] SEC-3084: Doc SecurityContextRequestPostProcessorSupport & SecurityContextHolder --- .../src/docs/asciidoc/_includes/test.adoc | 13 ++++- .../SecurityMockMvcRequestPostProcessors.java | 56 ++++++++++++++++++- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/docs/manual/src/docs/asciidoc/_includes/test.adoc b/docs/manual/src/docs/asciidoc/_includes/test.adoc index 0d21746ed2..c1c994006b 100644 --- a/docs/manual/src/docs/asciidoc/_includes/test.adoc +++ b/docs/manual/src/docs/asciidoc/_includes/test.adoc @@ -371,9 +371,20 @@ There are two simple ways of populating the user: [[test-mockmvc-securitycontextholder-rpp]] ==== Running as a User in Spring MVC Test with RequestPostProcessor -There are a number of options available to populate a test user. +There are a number of options available to associate a user to the current `HttpServletRequest`. For example, the following will run as a user (which does not need to exist) with the username "user", the password "password", and the role "ROLE_USER": +[NOTE] +==== +The support works by associating the user to the `HttpServletRequest`. +To associate the request to the `SecurityContextHolder` you need to ensure that the `SecurityContextPersistenceFilter` is associated with the `MockMvc` instance. +A few ways to do this are: + +* Invoking <> +* Adding Spring Security's `FilterChainProxy` to `MockMvc` +* Manually adding `SecurityContextPersistenceFilter` to the `MockMvc` instance may make sense when using `MockMvcBuilders.standaloneSetup` +==== + [source,java] ---- mvc diff --git a/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java b/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java index c5e28a9ec4..b9fe009776 100644 --- a/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java +++ b/test/src/main/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessors.java @@ -45,8 +45,10 @@ import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.codec.Base64; import org.springframework.security.test.context.TestSecurityContextHolder; +import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers; import org.springframework.security.test.web.support.WebTestUtils; import org.springframework.security.web.context.HttpRequestResponseHolder; +import org.springframework.security.web.context.SecurityContextPersistenceFilter; import org.springframework.security.web.context.SecurityContextRepository; import org.springframework.security.web.csrf.CsrfToken; import org.springframework.security.web.csrf.CsrfTokenRepository; @@ -139,10 +141,24 @@ public final class SecurityMockMvcRequestPostProcessors { * Establish a {@link SecurityContext} that has a * {@link UsernamePasswordAuthenticationToken} for the * {@link Authentication#getPrincipal()} and a {@link User} for the - * {@link UsernamePasswordAuthenticationToken#getPrincipal()}. All details are - * declarative and do not require that the user actually exists. + * {@link UsernamePasswordAuthenticationToken#getPrincipal()}. All details + * are declarative and do not require that the user actually exists. * - * @param username the username to populate + *

+ * The support works by associating the user to the HttpServletRequest. To + * associate the request to the SecurityContextHolder you need to ensure + * that the SecurityContextPersistenceFilter is associated with the + * MockMvc instance. A few ways to do this are: + *

+ * + * + * + * @param username + * the username to populate * @return the {@link UserRequestPostProcessor} for additional customization */ public static UserRequestPostProcessor user(String username) { @@ -156,6 +172,19 @@ public final class SecurityMockMvcRequestPostProcessors { * {@link UsernamePasswordAuthenticationToken#getPrincipal()}. All details are * declarative and do not require that the user actually exists. * + *

+ * The support works by associating the user to the HttpServletRequest. To + * associate the request to the SecurityContextHolder you need to ensure + * that the SecurityContextPersistenceFilter is associated with the + * MockMvc instance. A few ways to do this are: + *

+ * + * + * * @param user the UserDetails to populate * @return the {@link RequestPostProcessor} to use */ @@ -168,6 +197,19 @@ public final class SecurityMockMvcRequestPostProcessors { * for the {@link Authentication#getPrincipal()} and a custom {@link UserDetails}. All * details are declarative and do not require that the user actually exists. * + *

+ * The support works by associating the user to the HttpServletRequest. To + * associate the request to the SecurityContextHolder you need to ensure + * that the SecurityContextPersistenceFilter is associated with the + * MockMvc instance. A few ways to do this are: + *

+ * + * + * * @param authentication the Authentication to populate * @return the {@link RequestPostProcessor} to use */ @@ -177,6 +219,14 @@ public final class SecurityMockMvcRequestPostProcessors { /** * Establish the specified {@link SecurityContext} to be used. + * + *

+ * This works by associating the user to the {@link HttpServletRequest}. To + * associate the request to the {@link SecurityContextHolder} you need to + * ensure that the {@link SecurityContextPersistenceFilter} (i.e. Spring + * Security's FilterChainProxy will typically do this) is associated with + * the {@link MockMvc} instance. + *

*/ public static RequestPostProcessor securityContext(SecurityContext securityContext) { return new SecurityContextRequestPostProcessor(securityContext);