Spring @WithMockUser не забирает OAuth2Authentication из Spring Security для тестирования (но работает при запуске) - PullRequest
0 голосов
/ 02 июля 2019

У меня есть примечание @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());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...