Spring 集成测试 - 未注入 AuthenticationPrincipal
Spring integration test - AuthenticationPrincipal not injected
我正在尝试在我的项目中使用 kotlin,它是服务于 angularjs 前端的 REST API 端点。我将 spring rest doc 用于我们的 api 文档。
迁移时,我发现我的安全上下文没有注入测试用例。
使用 mockito-kotlin 测试 class(主要由 Intellij 转换):
@RunWith(SpringJUnit4ClassRunner::class)
@ContextConfiguration(classes = arrayOf(MockAppConfig::class))
@WebAppConfiguration
class UserLoginDocumentation {
@get:Rule
var restDocumentation = JUnitRestDocumentation("target/generated-snippets")
private var mockMvc: MockMvc? = null
@Autowired
private val context: WebApplicationContext? = null
@Before
fun setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context!!)
.apply<DefaultMockMvcBuilder>(documentationConfiguration(this.restDocumentation)
.uris().withScheme("https").withHost("myhost.com").withPort(443)).build()
val authentication = TestingAuthenticationToken(MyUserDetailsService.MyUserDetails(1L), null)
SecurityContextHolder.getContext().authentication = authentication
}
@Autowired
lateinit var userLoginService: UserLoginService
@Test
@Throws(Exception::class)
fun loginTest() {
whenever(userLoginService!!.getUserInfo(any(), any(), any())).thenReturn(LoginUserInfo())
this.mockMvc!!.perform(post("/myloginURL/user")//the remaining is not important....
控制器:
@RequestMapping("/myloginURL")
@RestController
class UserLoginController
@Autowired constructor(
val userLoginService: UserLoginService) {
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/user", method = arrayOf(RequestMethod.POST), produces = arrayOf(MediaType.APPLICATION_JSON_VALUE))
fun getUser(@AuthenticationPrincipal userDetail: MyUserDetails,
request: HttpServletRequest, @RequestParam lang: String): LoginUserInfo? {
return userLoginService.getUserInfo(userDetail.userId, request.getHeader("Authorization"), lang)
}
}
这里userDetail
不为空,userDetail.userId
为空。所以看起来测试 class 中的身份验证没有注入到控制器调用中。
我是不是做错了什么,或者如何解决?
我应该使用 MockMvcBuilders.webAppContextSetup(this.context!!)
.apply(springSecurity(springSecurityFilterChain))
springSecurityFilterChain
与 @EnableWebSecurity
自动装配
之后我可以使用 csrf 和我想要的用户,userDetail 被注入到控制器中。
我正在尝试在我的项目中使用 kotlin,它是服务于 angularjs 前端的 REST API 端点。我将 spring rest doc 用于我们的 api 文档。
迁移时,我发现我的安全上下文没有注入测试用例。
使用 mockito-kotlin 测试 class(主要由 Intellij 转换):
@RunWith(SpringJUnit4ClassRunner::class)
@ContextConfiguration(classes = arrayOf(MockAppConfig::class))
@WebAppConfiguration
class UserLoginDocumentation {
@get:Rule
var restDocumentation = JUnitRestDocumentation("target/generated-snippets")
private var mockMvc: MockMvc? = null
@Autowired
private val context: WebApplicationContext? = null
@Before
fun setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context!!)
.apply<DefaultMockMvcBuilder>(documentationConfiguration(this.restDocumentation)
.uris().withScheme("https").withHost("myhost.com").withPort(443)).build()
val authentication = TestingAuthenticationToken(MyUserDetailsService.MyUserDetails(1L), null)
SecurityContextHolder.getContext().authentication = authentication
}
@Autowired
lateinit var userLoginService: UserLoginService
@Test
@Throws(Exception::class)
fun loginTest() {
whenever(userLoginService!!.getUserInfo(any(), any(), any())).thenReturn(LoginUserInfo())
this.mockMvc!!.perform(post("/myloginURL/user")//the remaining is not important....
控制器:
@RequestMapping("/myloginURL")
@RestController
class UserLoginController
@Autowired constructor(
val userLoginService: UserLoginService) {
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/user", method = arrayOf(RequestMethod.POST), produces = arrayOf(MediaType.APPLICATION_JSON_VALUE))
fun getUser(@AuthenticationPrincipal userDetail: MyUserDetails,
request: HttpServletRequest, @RequestParam lang: String): LoginUserInfo? {
return userLoginService.getUserInfo(userDetail.userId, request.getHeader("Authorization"), lang)
}
}
这里userDetail
不为空,userDetail.userId
为空。所以看起来测试 class 中的身份验证没有注入到控制器调用中。
我是不是做错了什么,或者如何解决?
我应该使用 MockMvcBuilders.webAppContextSetup(this.context!!)
.apply(springSecurity(springSecurityFilterChain))
springSecurityFilterChain
与 @EnableWebSecurity
之后我可以使用 csrf 和我想要的用户,userDetail 被注入到控制器中。