@AuthenticationPrincipal object return value

@AuthenticationPrincipal returns the previous value stored in the session.

Spring boot + spring protection oauth REST Server. https://github.com/legshort/spring-boot-sample

These two REST methods are in the controller. The problem is that the last argument of userDetailsImpl to deleteUser () has the same meaning as userDetailsImpl on updateUser () when I run the test code.

@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);
}

      

Below is the control code of the controller

I don't know how, but the second request, which is testDeleteUser (), has a session value and is the same user who used the previous test. so I even thought at the beginning of deleteUser () to check the access token and load the rights of the new user, but somehow the wrong user created at the beginning of testUpdateUser () has a real value for userDetailsImpl.

@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
}

      

This is the UserDetailService implementation, when it comes to loadUserByUserName () to test the access token, it loads the proper user from the database and returns the new user that was just created at the start of each test method (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);
    }
}

      

I tried to disconnect the session which I failed, seems fine with configuration and test code to me. Is there a good practical example for spring-security-oauth?


UPDATED

  • As far as I understand in mockMvc, it clears all settings and creates a lot of new mock server each time using the setUp () method. Hence the token access store should be flushed every time, but in a sense, the token store maintains authenticated tokens.

  • By requesting the access token requested with "/ oauth / token" that was skipped during the test, the following describes how the InMemoryTokenStore is called.


Testing process log

  • testUpdateUser () -> POST: / oauth / token -> store token
    token: 50b10897-9e15-4859-aeb0-43d0802ba42c
    user: id = 2

  • testUpdateUser () -> PUT: / users / 2 -> read token
    token: 50b10897-9e15-4859-aeb0-43d0802ba42c
    user: id = 2

  • testUpdateUserWithWrongUserId () -> GET: / oauth / token -> store token
    token: 50b10897-9e15-4859-aeb0-43d0802ba42c -> already exists in token
    user: id = 2 -> id = 4: user was updated new

  • testUpdateUserWithWrongUserId () -> PUT: / users / 0 -> read token
    token: 50b10897-9e15-4859-aeb0-43d0802ba42c
    user: id = 2

  • testDeleteUser () -> GET: / oauth / token -> does not store the token the token should store

  • testDeleteUser () -> DELETE: / users / 5 -> read token
    token: 50b10897-9e15-4859-aeb0-43d0802ba42c
    user: id = 2 -> user must have id = 5 which was created with userSignUp ()


Questions
How do I clear the InMemoryTokenStore of each test method using mockMvc?

+3


source to share


1 answer


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

      



0


source







All Articles