如何测试受保护的 Spring 控制器
How to test a Spring Controller that is secured
我目前有一个使用 Spring Boot 2、Spring MVC、Spring Data/JPA 和 Thymeleaf 构建的应用程序。
我正在编写一些 unit/integration 测试,我想测试控制器,它由 Spring 由注册用户数据库支持的安全性保护。
最好的测试方法是什么?我尝试了其中一些失败,例如使用 @WithMockUser
.
之类的注释
编辑:提醒一下,我不是在测试 @RestController
s。我直接在我的测试 class 上注入 @Controller
并调用它的方法。它在没有 Spring 安全性的情况下工作得很好。
一个例子:
@Controller
public class SecuredController {
@GetMapping("/")
public String index() {
return "index";
}
}
/
路径受 Spring 安全保护,通常会重定向到 /login
以验证用户。
我的单元测试应该是这样的:
@WebMvcTest(controllers = SecuredController.class)
class SecuredControllerTest {
@Autowired
private SecuredController controller;
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser(username = "user", password = "pass", roles = {"USER"})
public void testAuthenticatedIndex() throws Exception {
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andDo(print());
}
}
我得到的第一个错误是要求我注入我的 UserDetailsService 实现,这是我想避免的事情。但是,如果我确实注入了该服务,则测试有效,但是 returns 404 而不是 200.
有什么想法吗?
在测试中class,使用注释
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
在设置测试方法中
@Before
实测方法
@WithMockUser("spring")
@Test
像这些例子一样测试Spring安全性
https://spring.io/blog/2014/05/23/preview-spring-security-test-web-security
您需要通过导入 WebSecurityConfigurerAdapter
class.
将您的安全配置添加到 Spring 上下文
@WebMvcTest(controllers = SecuredController.class)
@Import(SecuredControllerTest.Config.class)
class SecuredControllerTest {
@Configuration
@EnableWebSecurity
static class Config extends MyWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("pa$$").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("pa$$").roles("ADMIN");
}
}
...
}
嵌入的 static class Config
只是为了改变我们从哪里获取用户,在这种情况下 inMemoryAuthentication
就足够了。
我目前有一个使用 Spring Boot 2、Spring MVC、Spring Data/JPA 和 Thymeleaf 构建的应用程序。
我正在编写一些 unit/integration 测试,我想测试控制器,它由 Spring 由注册用户数据库支持的安全性保护。
最好的测试方法是什么?我尝试了其中一些失败,例如使用 @WithMockUser
.
编辑:提醒一下,我不是在测试 @RestController
s。我直接在我的测试 class 上注入 @Controller
并调用它的方法。它在没有 Spring 安全性的情况下工作得很好。
一个例子:
@Controller
public class SecuredController {
@GetMapping("/")
public String index() {
return "index";
}
}
/
路径受 Spring 安全保护,通常会重定向到 /login
以验证用户。
我的单元测试应该是这样的:
@WebMvcTest(controllers = SecuredController.class)
class SecuredControllerTest {
@Autowired
private SecuredController controller;
@Autowired
private MockMvc mockMvc;
@Test
@WithMockUser(username = "user", password = "pass", roles = {"USER"})
public void testAuthenticatedIndex() throws Exception {
mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andDo(print());
}
}
我得到的第一个错误是要求我注入我的 UserDetailsService 实现,这是我想避免的事情。但是,如果我确实注入了该服务,则测试有效,但是 returns 404 而不是 200.
有什么想法吗?
在测试中class,使用注释
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
在设置测试方法中
@Before
实测方法
@WithMockUser("spring")
@Test
像这些例子一样测试Spring安全性
https://spring.io/blog/2014/05/23/preview-spring-security-test-web-security
您需要通过导入 WebSecurityConfigurerAdapter
class.
@WebMvcTest(controllers = SecuredController.class)
@Import(SecuredControllerTest.Config.class)
class SecuredControllerTest {
@Configuration
@EnableWebSecurity
static class Config extends MyWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user").password("pa$$").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("pa$$").roles("ADMIN");
}
}
...
}
嵌入的 static class Config
只是为了改变我们从哪里获取用户,在这种情况下 inMemoryAuthentication
就足够了。