| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | 
							- [[test-mockmvc-securitycontextholder]]
 
- = Running a Test as a User in Spring MVC Test
 
- It is often desirable to run tests as a specific user.
 
- There are two simple ways to populate the user:
 
- * <<test-mockmvc-securitycontextholder-rpp,Running as a User in Spring MVC Test with RequestPostProcessor>>
 
- * <<running-as-a-user-in-spring-mvc-test-with-annotations,Running as a User in Spring MVC Test with Annotations>>
 
- [[test-mockmvc-securitycontextholder-rpp]]
 
- == Running as a User in Spring MVC Test with RequestPostProcessor
 
- You have a number of options to associate a user to the current `HttpServletRequest`.
 
- The following example runs as a user (which does not need to exist) whose username is `user`, whose password is `password`, and whose role is `ROLE_USER`:
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- mvc
 
- 	.perform(get("/").with(user("user")))
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- mvc.get("/") {
 
-     with(user("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.
 
- You can do so in a number of ways:
 
- * Invoking xref:servlet/test/mockmvc/setup.adoc#test-mockmvc-setup[`apply(springSecurity())`]
 
- * Adding Spring Security's `FilterChainProxy` to `MockMvc`
 
- * Manually adding `SecurityContextPersistenceFilter` to the `MockMvc` instance may make sense when using `MockMvcBuilders.standaloneSetup`
 
- ====
 
- You can easily make customizations.
 
- For example, the following will run as a user (which does not need to exist) with the username "admin", the password "pass", and the roles "ROLE_USER" and "ROLE_ADMIN".
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- mvc
 
- 	.perform(get("/admin").with(user("admin").password("pass").roles("USER","ADMIN")))
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- mvc.get("/admin") {
 
-     with(user("admin").password("pass").roles("USER","ADMIN"))
 
- }
 
- ----
 
- ======
 
- If you have a custom `UserDetails` that you would like to use, you can easily specify that as well.
 
- For example, the following will use the specified `UserDetails` (which does not need to exist) to run with a `UsernamePasswordAuthenticationToken` that has a principal of the specified `UserDetails`:
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- mvc
 
- 	.perform(get("/").with(user(userDetails)))
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- mvc.get("/") {
 
-     with(user(userDetails))
 
- }
 
- ----
 
- ======
 
- You can run as anonymous user using the following:
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- mvc
 
- 	.perform(get("/").with(anonymous()))
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- mvc.get("/") {
 
-     with(anonymous())
 
- }
 
- ----
 
- ======
 
- This is especially useful if you are running with a default user and wish to process a few requests as an anonymous user.
 
- If you want a custom `Authentication` (which does not need to exist) you can do so using the following:
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- mvc
 
- 	.perform(get("/").with(authentication(authentication)))
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- mvc.get("/") {
 
-     with(authentication(authentication))
 
- }
 
- ----
 
- ======
 
- You can even customize the `SecurityContext` using the following:
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- mvc
 
- 	.perform(get("/").with(securityContext(securityContext)))
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- mvc.get("/") {
 
-     with(securityContext(securityContext))
 
- }
 
- ----
 
- ======
 
- We can also ensure to run as a specific user for every request by using ``MockMvcBuilders``'s default request.
 
- For example, the following will run as a user (which does not need to exist) with the username "admin", the password "password", and the role "ROLE_ADMIN":
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- mvc = MockMvcBuilders
 
- 		.webAppContextSetup(context)
 
- 		.defaultRequest(get("/").with(user("user").roles("ADMIN")))
 
- 		.apply(springSecurity())
 
- 		.build();
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- mvc = MockMvcBuilders
 
-     .webAppContextSetup(context)
 
-     .defaultRequest<DefaultMockMvcBuilder>(get("/").with(user("user").roles("ADMIN")))
 
-     .apply<DefaultMockMvcBuilder>(springSecurity())
 
-     .build()
 
- ----
 
- ======
 
- If you find you are using the same user in many of your tests, it is recommended to move the user to a method.
 
- For example, you can specify the following in your own class named `CustomSecurityMockMvcRequestPostProcessors`:
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- public static RequestPostProcessor rob() {
 
- 	return user("rob").roles("ADMIN");
 
- }
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- fun rob(): RequestPostProcessor {
 
-     return user("rob").roles("ADMIN")
 
- }
 
- ----
 
- ======
 
- Now you can perform a static import on `CustomSecurityMockMvcRequestPostProcessors` and use that within your tests:
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- import static sample.CustomSecurityMockMvcRequestPostProcessors.*;
 
- ...
 
- mvc
 
- 	.perform(get("/").with(rob()))
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- import sample.CustomSecurityMockMvcRequestPostProcessors.*
 
- //...
 
- mvc.get("/") {
 
-     with(rob())
 
- }
 
- ----
 
- ======
 
- [[test-mockmvc-withmockuser]]
 
- == Running as a User in Spring MVC Test with Annotations
 
- As an alternative to using a `RequestPostProcessor` to create your user, you can use annotations described in xref:servlet/test/method.adoc[Testing Method Security].
 
- For example, the following will run the test with the user with username "user", password "password", and role "ROLE_USER":
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- @Test
 
- @WithMockUser
 
- public void requestProtectedUrlWithUser() throws Exception {
 
- mvc
 
- 		.perform(get("/"))
 
- 		...
 
- }
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Test
 
- @WithMockUser
 
- fun requestProtectedUrlWithUser() {
 
-     mvc
 
-         .get("/")
 
-         // ...
 
- }
 
- ----
 
- ======
 
- Alternatively, the following will run the test with the user with username "user", password "password", and role "ROLE_ADMIN":
 
- [tabs]
 
- ======
 
- Java::
 
- +
 
- [source,java,role="primary"]
 
- ----
 
- @Test
 
- @WithMockUser(roles="ADMIN")
 
- public void requestProtectedUrlWithUser() throws Exception {
 
- mvc
 
- 		.perform(get("/"))
 
- 		...
 
- }
 
- ----
 
- Kotlin::
 
- +
 
- [source,kotlin,role="secondary"]
 
- ----
 
- @Test
 
- @WithMockUser(roles = ["ADMIN"])
 
- fun requestProtectedUrlWithUser() {
 
-     mvc
 
-         .get("/")
 
-         // ...
 
- }
 
- ----
 
- ======
 
 
  |