Disable Spring Security config class for @WebMvcTest in Spring Boot
Solution 1
You can set secure=false in the @WebMvcTest annoation. It will skip the spring security MockMvc auto configuration in your Test
@WebMvcTest(controllers = SomeController.class, secure = false)
public class SomeControllerTest {
Note by the author: As of 2021, this answer has been obsolete for a few years and it probably won't work for you.
Solution 2
For me in Spring Boot 2.2.4 (JUnit5) the below seems to have worked and bypass the security filter.
@ExtendWith(SpringExtension.class)
@WebMvcTest(SomeController.class)
@AutoConfigureMockMvc(addFilters = false)
public class SomeControllerTest {
...
Note: this simply disables any filters in the SpringSecurity configuration. It won't disable the security completely. In other words it will still bootstrap security without loading any filters.
Solution 3
In Spring Boot 2.2.6, @WebMvcTest is meta annotated with @AutoConfigureWebMvc which auto-configure org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration as you can see in spring.factories of spring-boot-test-autoconfigure.jar
So you just have to exclude SecurityAutoConfiguration in your test to disable Spring Security :
@WebMvcTest(excludeAutoConfiguration = SecurityAutoConfiguration.class)
Solution 4
With Spring Security 4+, I find @WithMockUser
annotation to be very handy. It provides a mock user and password to test spring security methods annotated with @PreAuthorize or @PostAuthorize. All you need to do is annotate the test method with @WithMockUser
. The default role for the user is USER
. You can override the default username and role too.
//default
@Test
@WithMockUser
public void getProfile() {
//your test here
}
//with username and roles
@Test
@WithMockUser(username = "john", roles={"ADMIN"})
public void getProfile() {
//your test here
}
NOTE: This annotation can be used for classes.
@WithMockUser(username = "john", roles={"ADMIN"})
public class UsersAdminSecurityTest {
}
Solution 5
In Spring Boot 2.4 both secure
flags were removed and none of the answers here actually work.
I ended up excluding all the security myself and wrapping it around in a custom annotation.
import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration;
import org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;
import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
import java.lang.annotation.*;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@WebMvcTest(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = WebSecurityConfigurer.class)},
excludeAutoConfiguration = {SecurityAutoConfiguration.class,
SecurityFilterAutoConfiguration.class,
OAuth2ClientAutoConfiguration.class,
OAuth2ResourceServerAutoConfiguration.class})
public @interface UnsecuredWebMvcTest {
@AliasFor(annotation = WebMvcTest.class, attribute = "controllers")
Class<?>[] value() default {};
@AliasFor(annotation = WebMvcTest.class, attribute = "controllers")
Class<?>[] controllers() default {};
}
Johan
Updated on October 12, 2021Comments
-
Johan over 2 years
Recently I have added Spring Security to my Spring Boot project using the following class:
@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class MySecurityConfig { }
as result, by default all my URLs are now protected with authentication and a self-generated password.
The problem is that all tests in a @WebMvcTest class that I used for unit-testing a controller:
@RunWith(SpringRunner.class) @WebMvcTest(SomeController.class) public class SomeControllerTest {...}
are now failing everywhere because of lack of authorization.
Question: can I tell @Test methods to ignore authorization so they keep succeeding as before?
How can I prevent the @EnableWebSecurity config class from being picked on a specific @WebMvcTest unit testing class?
I would like the tests already in place to be able to still go through and to test the authentication features separately later on.
So far I have tried to use a nested config class in the testing class in order to exclude security configs:
@RunWith(SpringRunner.class) @WebMvcTest(SomeController.class) public class SomeControllerTest { @Configuration @EnableAutoConfiguration(exclude = { SecurityAutoConfiguration.class}) static class ContextConfiguration { } ....}
but it seems not to work.
NOTE : I am using Spring Boot 1.5.8