Search code examples
spring-security-test

Change authorized user in tests


I want to test access to a method for a group of users with different roles in one test. I am trying to change the logged in user like this:

@Test
void allMenusAuthorizePermissions() throws Exception {

        for (User user : ALL_ROLES_USERS) {
            Authentication authentication = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), user.getAuthorities());
            SecurityContextHolder.clearContext();
            SecurityContextHolder.getContext().setAuthentication(authentication);

            log.debug("User role: " + user.getAuthorities());

            if (user == ADMIN || user == EDITOR) {
                perform(get(MenuEditorController.MENU_EDITOR_URL).principal(authentication))
                        .andExpect(status().isOk());
            }else{
                perform(get(MenuEditorController.MENU_EDITOR_URL).principal(authentication))
                        .andExpect(status().isForbidden());
            }

        }
}

But no matter how hard I try, perform(get (...)) is always performed from the first user from the ALL_ROLES_USERS array. This can be seen from the log:

o.s.s.a.i.a.MethodSecurityInterceptor    : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e74255f0: Principal: +79990200001; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: CLIENT

-the same user in every iteration!

Any idea why this might be happening? Maybe perform(get(...)) is passing the JSESSIONID of the first user? I don't know where to dig anymore


Solution

  • You need to use:

    @Test
        void allMenusAuthorizePermissions() throws Exception {
    
            for (User user : ALL_ROLES_USERS) {
                log.debug("User role: " + user.getAuthorities());
    
                if (user == ADMIN || user == EDITOR) {
    //              perform(get(MenuEditorController.MENU_EDITOR_URL).with(SecurityMockMvcRequestPostProcessors.user(user.getUsername()).authorities(user.getAuthorities())))
                    perform(get(MenuEditorController.MENU_EDITOR_URL).with(SecurityMockMvcRequestPostProcessors.user(user)))
                            .andExpect(status().isOk());
                }else{
                    perform(get(MenuEditorController.MENU_EDITOR_URL).with(SecurityMockMvcRequestPostProcessors.user(user)))
                            .andExpect(status().isForbidden());
                }
    
            }
        }
    

    How to Mock the security context in Spring MVC for testing