| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | [[test-mockmvc-securitycontextholder]]= Running a Test as a User in Spring MVC TestIt 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>>* <<test-mockmvc-withmockuser,Running as a User in Spring MVC Test with Annotations>>[[test-mockmvc-securitycontextholder-rpp]]== Running as a User in Spring MVC Test with RequestPostProcessorYou 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 AnnotationsAs 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@WithMockUserpublic void requestProtectedUrlWithUser() throws Exception {mvc		.perform(get("/"))		...}----Kotlin::+[source,kotlin,role="secondary"]----@Test@WithMockUserfun 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("/")        // ...}----======
 |