温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - Testing Spring Security protected Controllers with MockMvc possible?
spring-boot integration-testing mockmvc

其他 - 可以使用MockMvc测试受Spring Security保护的控制器吗?

发布于 2020-03-29 21:28:11

我想弄清楚,什么是测试Spring Boot应用程序安全性配置的最佳方法。我的目标是进行两个测试:

  • 给定用户A,可以在401中访问资源/测试结果
  • 给定用户B,访问资源/测试的结果为200

在开始研究时,我发现的所有教程都指向“ MockMvc”,但我无法编写2种以这种方式工作的测试。在几乎所有情况下,我似乎都完全忽略了安全性(即使没有提供任何用户,MockMvc也会返回200)。

假设我有以下设置,作为一个简单示例:

安全配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
    }

}

控制器:

@RestController
public class TestController {

    @GetMapping("/test")
    public String getTest() {
        return "hello";
    }

}

特性:

spring.security.user.name=testuser
spring.security.user.password=testpassword

我可以像这样使用“ TestRestTemplate”成功测试此:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class DemoApplicationTests {

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    void when_userIsValid_should_return200() throws Exception {
        String res = testRestTemplate
                .withBasicAuth("testuser", "testpassword")
                .getForEntity("/test", String.class)
                .getBody();
        Assert.assertEquals("hello", res);
    }

    @Test
    void when_userIsInvalid_should_return401() throws Exception {
        HttpStatus res = testRestTemplate
                .withBasicAuth("foo", "bar")
                .getForEntity("/test", String.class)
                .getStatusCode();
        Assert.assertEquals(HttpStatus.UNAUTHORIZED, res);
    }

}

所以我的问题是:这是“前进的道路”吗?如果选择MockMvc作为工具,能否请您提供一个可行的示例?我已经尝试了30种来自Tutorials和Stackoverflow的解决方案,但都没有起作用(要么MockMvc为null,安全性被完全忽略,不再检测到Controller Method,但是我太愚蠢而无法使它们起作用:/)

先感谢您!

查看更多

提问者
andreas
被浏览
156
Beppe C 2020-01-31 22:22

您可以使用它WebMvcTest来仅初始化Controller层(它不会创建/注入所有其他定义为服务/存储库的Spring Bean,等等),但是在测试Controller逻辑时它是合适的(并且更快)。

这是一个例子

@AutoConfigureMockMvc
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = MainController.class)
public class ControllerTest  {

@Autowired
private MockMvc mockMvc;

//@MockBean
//Service service; // mock service dependencies if needed

@Test
public void invalidCredentials() throws Exception {

    this.mockMvc
            .perform(get("/test").header(HttpHeaders.AUTHORIZATION,
                    "Basic " + Base64Utils.encodeToString("testuser:WRONGpassword".getBytes())))
            .andExpect(status().isOk());
}