gpt4 book ai didi

spring - @AuthenticationPrincipal 对象返回 session 值

转载 作者:行者123 更新时间:2023-12-02 14:15:37 25 4
gpt4 key购买 nike

@AuthenticationPrincipal 对象返回存储在 session 中的先前值。

Spring boot + spring security oauth REST 服务器。 https://github.com/legshort/spring-boot-sample

这两个REST方法都在 Controller 中。问题是,当我运行测试代码时,deleteUser() 处的最后一个参数 userDetailsImpl 与 updateUser() 处的 userDetailsImpl 的值相同。

@RequestMapping(method = RequestMethod.PUT, value = "/users/{userId}")
public ResponseEntity updateUser(@PathVariable Long userId,
@AuthenticationPrincipal UserDetailsImpl userDetailsImpl,
@Valid @RequestBody UserUpdateForm userUpdateForm,
BindingResult bindingResult) {
logger.info("UserUpdate: " + userUpdateForm);

User updatedUser = userService.updateUser(userUpdateForm
.createUser(userId));

return new ResponseEntity(updatedUser, HttpStatus.OK);
}

@RequestMapping(method = RequestMethod.DELETE, value = "/users/{userId}")
public ResponseEntity deleteUser(@PathVariable Long userId,
@AuthenticationPrincipal UserDetailsImpl userDetailsImpl) {
logger.info("UserDelete: " + userId);

User requestedUser = new User(userId);
userService.deleteUser(requestedUser);

return new ResponseEntity(HttpStatus.NO_CONTENT);
}

下面是 Controller 测试代码

我不知道如何,但第二个请求 testDeleteUser() 具有 session 值,并且它与使用先前测试的用户是同一用户。因此,即使在 deleteUser() 开始时考虑验证访问 token 并加载正确的新用户,但不知何故 userDetailsImpl 的实际值具有在 testUpdateUser() 开始时创建的错误用户。

@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(filterChainProxy).build();
}

@Test
public void testUpdateUser() throws Exception {
User savedUser = signUpUser();

// @formatter:off
mockMvc.perform(
put("/users/" + savedUser.getId())
.header(HeaderUtil.AUTHORIZATION, getAuthorizationWithAccessToken())
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(UserUpdateFormFactory.newInstance())))
.andExpect(status().isOk())
.andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.id", is(greaterThan(NumberUtils.INTEGER_ZERO))))
.andExpect(jsonPath("$.name", is(equalTo(StringUtil.NEW + UserFactory.NAME))));
// @formatter:on
}

@Test
public void testDeleteUser() throws Exception {
User savedUser = signUpUser();
String authorization = getAuthorizationWithAccessToken();

// @formatter:off
mockMvc.perform(
delete("/users/" + savedUser.getId())
.header(HeaderUtil.AUTHORIZATION, authorization)
.contentType(TestUtil.APPLICATION_JSON_UTF8))
.andDo(print())
.andExpect(status().isNoContent());
// @formatter:on
}

这是 UserDetailService 实现,当涉及到 loadUserByUserName() 来验证访问 token 时,它会从数据库加载正确的用户并返回刚刚在每个测试方法 (signUpUser()) 开始时创建的新用户。

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired
private UserService userService;

@Override
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException {

User requestedUser = new User();
requestedUser.setEmail(email);

User savedUser = userService.findByEmail(requestedUser);

return new UserDetailsImpl(savedUser);
}
}

我尝试禁用 session ,但失败了,对我来说配置和测试代码似乎很好。spring-security-oauth 有什么好的实际例子吗?

<小时/>

已更新

  1. 据我对mockMvc的了解,它会清除所有设置,并且每次使用setUp()方法都会创建几乎新的模拟服务器。因此,每次都应该清除访问 token 存储,但 token 存储会以某种方式维护经过身份验证的 token 。

  2. 在测试期间询问使用“/oauth/token”请求的访问 token ,以下是调用 InMemoryTokenStore 的方法。

<小时/>

测试过程日志

  1. testUpdateUser() -> POST:/oauth/token -> 存储 token
    token :50b10897-9e15-4859-aeb0-43d0802ba42c
    用户:id=2

  2. testUpdateUser() -> PUT:/users/2 -> 读取 token
    token :50b10897-9e15-4859-aeb0-43d0802ba42c
    用户:id=2

  3. testUpdateUserWithWrongUserId() -> GET:/oauth/token -> 存储 token
    token :50b10897-9e15-4859-aeb0-43d0802ba42c -> token 中已存在​​
    user: id=2 -> id=4: 用户已更新为新用户

  4. testUpdateUserWithWrongUserId() -> PUT:/users/0 -> 读取 token
    token :50b10897-9e15-4859-aeb0-43d0802ba42c
    用户:id=2

  5. testDeleteUser() -> GET:/oauth/token -> 未存储 token ,应该存储 token

  6. testDeleteUser() -> 删除:/users/5 -> 读取 token
    token :50b10897-9e15-4859-aeb0-43d0802ba42c
    user: id=2 -> 用户应该是 id=5,它是使用 userSignUp() 创建的

<小时/>

问题
如何用mockMvc清除InMemoryTokenStore每个测试方法?

最佳答案

    // ignore spring security session
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);

关于spring - @AuthenticationPrincipal 对象返回 session 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26523694/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com