Способ тестирования Безопасность, как проверить @PreAuthorize ("# user.id! = Authentication.principal.id")? - PullRequest
0 голосов
/ 23 мая 2019

Я пытаюсь проверить метод в моем UserController с именем update, который выглядит следующим образом:

@RequestMapping(path = "/update", method = RequestMethod.PUT)
@PreAuthorize("#user.id != authentication.principal.id")
public ResponseEntity<User> update(@RequestBody final User user) {
    return new ResponseEntity<>(userService.saveElement(user), HttpStatus.OK);
}

, но я не могу получить доступ к идентификатору ("# user.id!= authentication.principal.id ") в тесте

Когда я удаляю @PreAuthorize (" # user.id! = authentication.principal.id "), тест становится зеленым.Я пытался добавить

    @Test
    @WithMockUser(roles = {"ADMIN"}, id={"1"})
    ...
    }

или другие модификаторы тоже, но это не сработало

UserController.java

@Controller
@RequestMapping(API_PATH)
public class UserController {

    public static final String API_PATH = "/api/user";
    private final UserService userService;

    @Autowired
    public UserController(final UserService userService) {
        this.userService = userService;
    }

    @RequestMapping(path = "/update", method = RequestMethod.PUT)
    @PreAuthorize("#user.id != authentication.principal.id")
    public ResponseEntity<User> update(@RequestBody final User user) {
        return new ResponseEntity<>(userService.saveElement(user), HttpStatus.OK);
    }
}

UserControllerTest.java

@ExtendWith(SpringExtension.class)
@SpringBootTest
@ContextConfiguration(classes = {TestContextConfiguration.class})
@WebAppConfiguration
class UserControllerTest {

    private MockMvc mvc;

    @Autowired
    private WebApplicationContext context;

    @MockBean
    private UserService userServiceMock;

    @BeforeEach
    void initTest() {
        MockitoAnnotations.initMocks(this);
        mvc = MockMvcBuilders.webAppContextSetup(context).apply(springSecurity()).build();
    }

    @Test
    @WithMockUser(roles = {"ADMIN"})
    void update() throws Exception {
        final String apiPath = UserController.API_PATH + "/update";
        final User user = new User();
        final String userAsJsonString = TestUtils.getObjectAsJsonString(user);

        mvc.perform(put(apiPath).contentType(MediaType.APPLICATION_JSON).content(userAsJsonString)).andExpect(status().isOk());

        Mockito.verify(userServiceMock).saveElement(ArgumentMatchers.any(User.class));
    }
}

1 Ответ

0 голосов
/ 24 мая 2019

при некоторой помощи друзей проблема решена.

Одна проблема заключалась в том, что я пытался протестировать 2 случая с помощью одного теста и что предоставленный мною пользователь был пустым для метода testMethod.

Вот мое решение:

    @Test
@WithMockUser(roles = {"ADMIN"})
void updateOwnAccount() throws Exception {

    final User user = TestUtils.createUser();
    user.setId(17);

    final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authentication);

    mvc.perform(put(UserController.API_PATH + "/update").contentType(MediaType.APPLICATION_JSON).content(TestUtils.getObjectAsJsonString(user))).andExpect(
            status().isInternalServerError());
}

@Test
@WithMockUser(roles = {"ADMIN"})
void updateAnotherAccount() throws Exception {

    final User userToChange = TestUtils.createUser();
    userToChange.setId(17);
    final User userToLogin = TestUtils.createUser();
    userToLogin.setId(18);

    final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userToLogin, null, userToLogin.getAuthorities());
    SecurityContextHolder.getContext().setAuthentication(authentication);

    mvc.perform(put(UserController.API_PATH + "/update").contentType(MediaType.APPLICATION_JSON).content(TestUtils.getObjectAsJsonString(userToChange)))
            .andExpect(status().isOk());

    Mockito.verify(userServiceMock).saveElement(ArgumentMatchers.any(User.class));
}
...