我已经设置了oauth2,并且正在生产中。在控制器的方法中:
fun setCars(@RequestBody carsData: CarsData, authentication: Authentication?) 该authentication参数被正确喷射。但是当我跑步@WebMvcTest去做
mockMvc.perform( put("/api/...") .with(authentication(anAuthentication)) .content("""...""") .contentType(MediaType.APPLICATION_JSON_UTF8) 然后,在控制器的方法中,该authentication参数为null。如何在Web MVC测试中通过身份验证对象?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Spring Boot应用中,使用@WebMvcTest
进行单元测试时,通常只加载与MVC相关的配置,如控制器、服务和一些模拟的Bean,而安全上下文(如OAuth2的认证信息)默认是不被加载的。因此,在执行测试时,你需要手动设置或模拟SecurityContext以便让测试中的请求能够携带认证信息。
要解决你的问题,你可以通过以下步骤来确保在@WebMvcTest
中正确注入Authentication对象:
导入SecurityMockMvcConfigurer: 首先,确保你已经导入了必要的测试工具类,特别是那些可以帮助你配置Security上下文的类。这通常包括org.springframework.security.test.context.support.WithMockUser
注解或者直接使用SecurityMockMvcRequestPostProcessors
。
使用SecurityMockMvcRequestPostProcessors: 在你的测试代码中,利用SecurityMockMvcRequestPostProcessors
来添加认证信息到请求中。这个类提供了多种方法来模拟不同的认证场景,比如匿名用户、特定用户等。
修改你的测试代码如下:
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors
mockMvc.perform(
put("/api/...")
.with(SecurityMockMvcRequestPostProcessors.authentication(anAuthentication)) // 这里用实际的认证信息替换anAuthentication
.content("""...""")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
这里的anAuthentication
应该是一个代表已认证用户的Authentication
对象。如果你只是想模拟一个简单的用户登录状态,可以使用withUser()
方法简化操作:
mockMvc.perform(
put("/api/...")
.with(SecurityMockMvcRequestPostProcessors.user("username").password("password").roles("ROLE_USER"))
.content("""...""")
.contentType(MediaType.APPLICATION_JSON_UTF8)
)
如果需要自定义的Authentication细节,你可能需要创建一个具体的Authentication
实例,并将其传递给.with()
方法。这通常涉及到构造一个实现了Authentication
接口的具体类,比如UsernamePasswordAuthenticationToken
。
考虑使用@SpringBootTest: 如果你发现仅通过@WebMvcTest
难以完全模拟安全上下文,且你的测试确实需要完整的Spring环境(包括安全配置),可以考虑使用@SpringBootTest
注解来启动整个应用上下文,同时结合@AutoConfigureMockMvc
来专注于MVC层的测试。但请注意,这种方法会启动更多的组件,使得测试运行速度变慢。
通过上述方法,你应该能够在Web MVC测试中成功地通过并验证Authentication对象。