Spring @WithMockUser不会从Spring Security获取OAuth2Authentication进行测试(但是在运行时可以运行)

时间:2019-07-02 11:49:45

标签: java spring spring-boot spring-mvc spring-security

我在控制器方法上有一个@PreAuthorize批注,以使所有角色为“ ADMIN”的用户以及您自己的用户(也称为其身份验证主体)都可以使用它。

这与运行应用程序时的预期效果完全相同,但不适用于其测试:

  

控制器

 @GetMapping("/{username}/role")
 @PreAuthorize("hasRole('ADMIN') || #username == authentication.principal")
 public String getOneUserRoleByUsername(final @PathVariable String username) { ... }

我在测试中使用@WithMockUser,这对于测试“ ADMIN”角色非常有用,但不适用于用户名检查。

  

问题

响应是一个403 HTTP错误。

当我在测试中查看Spring Security的当前主体时,它会显示正确的用户名,因此

SecurityContextHolder.getContext().getAuthentication().getPrincipal();

在测试中是“用户”,应该是这样。

在测试中,getAuthentication()返回一个UsernamePasswordAuthenticationToken,而正在运行的应用程序返回一个OAuth2Authentication对象。它们具有不同的结构,其中OAuth对象具有userAuthentication对象(其中包含principal),而UsernamePasswordAuthenticationToken直接具有principal

authentication.principal更改为authentication.principal.username可以使测试工作,但不适用于正在运行的应用程序:

正在测试中,运行时会中断:

@PreAuthorize("hasRole('ADMIN') || #username == authentication.principal.username")

运行时正常运行,但无法通过测试:

@PreAuthorize("hasRole('ADMIN') || #username == authentication.principal")

  

将访问权限测试为“ ADMIN”-正常运行

@Test
@WithMockUser(username = "ABC", roles = {UserRole.ADMIN})
public void testGetOneUserRoleByUsername_asAdmin() throws Exception {
    UserEntity userToSearch = new UserEntity("user", "password", UserRole.USER);
    MvcResult result = mvc
        .perform(get("/user/" + userToSearch.getUsername() + "/role"))
        .andExpect(status().isOk())
        .andReturn();

    assertEquals(userToSearch.getRole(), result.getResponse().getContentAsString());
}
  

测试自己用户的访问权限-不起作用

@Test
@WithUserDetails("user") // Tried this one, too..
@WithMockUser("user")
// or  @WithMockUser(username = "user")
public void testGetOneUserRoleByUsername_forOwnUser() throws Exception {
    UserEntity userToSearch = new UserEntity("user", "password", UserRole.USER);

    MvcResult result = mvc
        .perform(get("/user/" + userToSearch.getUsername() + "/role"))
        .andExpect(status().isOk())
        .andReturn();

    assertEquals(userToSearch.getRole(), result.getResponse().getContentAsString());
}

0 个答案:

没有答案