测试方法安全性,如何测试@PreAuthorize("#user.id != authentication.principal.id")?
Testing Method Security, how to test @PreAuthorize("#user.id != authentication.principal.id")?
我正在尝试在我的 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);
}
但我似乎无法访问测试中的id("#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));
}
}
在朋友的帮助下,问题解决了。
一个问题是我试图用一个测试来测试 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));
}
我正在尝试在我的 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);
}
但我似乎无法访问测试中的id("#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));
}
}
在朋友的帮助下,问题解决了。
一个问题是我试图用一个测试来测试 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));
}