org.springframework.security.core.userdetails.User 无法转换为 MyUserDetails (Junit 5)

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

我正在使用 Junit 5 测试 Web 应用程序,除

外,一切正常

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

line in controller class while 运行ning 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)

我的测试用例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());
     }
}

我缺少什么代码,所以它是 return org.springframework.security.core.userdetails.User 对象,而 运行 使用 Junit 5 测试用例,但如果我 运行 通过 spring开机.

添加UserDetailsS​​ervice实现代码

@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

}

问题是您使用的 SecurityMockMvcRequestPostProcessors.user(String username) RequestPostProcessor 将创建 return 一个 org.springframework.security.core.userdetails.User,它是 UserDetails 的实现,但不是 MyUserDetails你想要的。

相反,您可以使用 SecurityMockMvcRequestPostProcessors.user(UserDetails user),它允许提交您自己的 UserDetails 实现,在本例中是您想要的 MyUserDetails

按如下方式更改您的测试:

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

参考Spring安全Source code