pise
pise

Reputation: 865

org.springframework.security.core.userdetails.User cannot be cast to MyUserDetails (Junit 5)

I am testing web application using Junit 5, every thing working fine except

SecurityContextHolder.getContext().getAuthentication().getPrincipal()

line in controller class while running test case above code of line return object of

org.springframework.security.core.userdetails.User instead of MyUserDetails (While running application in spring boot return object is MyUserDetails and code works well)

My Test case class

@ExtendWith(SpringExtension.class)
@WebMvcTest(VendorController.class)
@AutoConfigureMockMvc
class VendorControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    void test() throws Exception {
    mvc.perform(MockMvcRequestBuilders.post("/vendor/user/getVendorList").with(csrf().asHeader())
            .param("iDisplayStart","0")
            .param("iDisplayLength", "10")
            .param("iSortCol_0", "0")
            .param("sSortDir_0", "asc")
            .param("sSearch","")
            .with(user("username").password("password").roles("2"))).andExpect(status().isOk());
     }
}

What code I am missing so that it is return org.springframework.security.core.userdetails.User object while running test case using Junit 5 but working properly if I run project through spring boot.

Adding UserDetailsService implementation code

@Service("userDetailsService")

public class MyUserDetailsService implements UserDetailsService {

@Autowired

private UserSvc userSvc;

@Transactional(readOnly=true)

@Override

public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {

    com.esociety.entity.UserEntity userEntity = userSvc.findByUserName(username);

    List<GrantedAuthority> authorities = buildUserAuthority(userEntity.getUserType());

    return buildUserForAuthentication(userEntity, authorities);

}

private User buildUserForAuthentication(com.esociety.entity.UserEntity userEntity, List<GrantedAuthority> authorities) {

     MyUserDetails myUserDetails = new MyUserDetails (userEntity.getUsername(), userEntity.getPassword(), userEntity.isEnabled(), userEntity.isAccountNonExpired(), userEntity.isCredentialsNonExpired(),userEntity.isAccountNonLocked(),authorities,userEntity.getUserId(),userEntity.getSocietyId(),userEntity.getUserType(),userEntity.getFirstName(),userEntity.getMiddleName(),userEntity.getLastName());

     return myUserDetails;

}

private List<GrantedAuthority> buildUserAuthority(String userType) {

    Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();

    // Build user's authorities

    setAuths.add(new SimpleGrantedAuthority(userType));

    List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);

    return Result;

}

}

MyUserDetails class

public class MyUserDetails extends User {
 public MyUserDetails(String username, String password, boolean enabled,
        boolean accountNonExpired, boolean credentialsNonExpired,
        boolean accountNonLocked,
        Collection<? extends GrantedAuthority> authorities, Long userId,
        Long societyId, String userType, String firstName,
        String middleName, String lastName) {
    super(username, password, enabled, accountNonExpired,
            credentialsNonExpired, accountNonLocked, authorities);
    this.userId = userId;
    this.societyId = societyId;
    this.userType = userType;
    this.firstName = firstName;
    this.middleName = middleName;
    this.lastName = lastName;
 }
// getter setter goes here

}

Upvotes: 1

Views: 1169

Answers (1)

shazin
shazin

Reputation: 21903

The problem is you are using SecurityMockMvcRequestPostProcessors.user(String username) RequestPostProcessor which will create and return a org.springframework.security.core.userdetails.User which is an implementation of UserDetails but not the MyUserDetails that you want.

Instead you can use SecurityMockMvcRequestPostProcessors.user(UserDetails user) which allows to submit your own implementation of UserDetails, in this case MyUserDetails that you want.

Change your test as following:

@Test
void test() throws Exception {
mvc.perform(MockMvcRequestBuilders.post("/vendor/user/getVendorList").with(csrf().asHeader())
        .param("iDisplayStart","0")
        .param("iDisplayLength", "10")
        .param("iSortCol_0", "0")
        .param("sSortDir_0", "asc")
        .param("sSearch","")
        .with(user(new MyUserDetails ("username", "password", true, true, true,true, Arrays.asList(new SimpleGrantedAuthority("2")),1,1,USER_TYPE,"FirstName","MiddleName","LastName")))).andExpect(status().isOk());
 }

Reference Spring Security Source code

Upvotes: 4

Related Questions