我正在尝试登录用户,但遇到以下异常,
ava.lang.ClassCastException: class org.springframework.security.core.userdetails.User cannot be cast to class com.gaurav.studentmanagement.customUserdetailsAndJwtFilterRequestsAndServices.UserPrincipal (org.springframework.security.core.userdetails.User and com.gaurav.studentmanagement.customUserdetailsAndJwtFilterRequestsAndServices.UserPrincipal are in unnamed module of loader 'app')
我的UserPrincipal类是:
package com.gaurav.studentmanagement.customUserdetailsAndJwtFilterRequestsAndServices;
import com.gaurav.studentmanagement.entity.User;
import com.gaurav.studentmanagement.repo.RolesRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class UserPrincipal implements UserDetails {
private final User user;
private List<String> grantedAuthorities;
public UserPrincipal(User user){
this.user=user;
}
@Override
public Collection< ? extends GrantedAuthority > getAuthorities() {
List<GrantedAuthority> authorities = new ArrayList<>();
getGrantedAuthorities().forEach(p -> {
GrantedAuthority authority = new SimpleGrantedAuthority(p);
authorities.add(authority);
});
// Extract list of roles (ROLE_name)
getGrantedAuthorities().forEach(r -> {
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + r);
authorities.add(authority);
});
return authorities;
}
@Override
public String getPassword() {
return this.user.getPassword();
}
public User getUser(){
return user;
}
@Override
public String getUsername() {
return this.user.getEmail();
}
@Override
public boolean isAccountNonExpired() {
return false;
}
public List<String> getGrantedAuthorities() {
return grantedAuthorities;
}
@Override
public boolean isAccountNonLocked() {
return false;
}
@Override
public boolean isCredentialsNonExpired() {
return false;
}
@Override
public boolean isEnabled() {
return false;
}
}
我正在使用以下方法获取登录用户:
@Override
public User getLoggedInUser() {
UserPrincipal userPrincipal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user=userPrincipal.getUser();
if(user==null){
throw new CustomException("Not authorized");
}
return user;
}
每当调试器指向:
UserPrincipal userPrincipal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
抛出上面的异常,可能是什么问题,我试图从getLoggedInUser返回User,但是不知道哪里出错了,我想我返回了正确的User,得到了本金,但是找不到哪里出错了。
自定义用户详细信息服务类:
package com.gaurav.studentmanagement.customUserdetailsAndJwtFilterRequestsAndServices;
import com.gaurav.studentmanagement.entity.Roles;
import com.gaurav.studentmanagement.entity.User;
import com.gaurav.studentmanagement.repo.RolesRepo;
import com.gaurav.studentmanagement.repo.UserRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Service
public class CustomUserDetails implements UserDetailsService {
@Autowired
UserRepo userRepo;
@Autowired
RolesRepo rolesRepo;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional< User > user = userRepo.fetchByEmail(username);
if (user.isPresent()) {
List< Roles > roles = rolesRepo.findByUserId(user.get().getuId());
System.out.println(roles + " are the roles");
List< SimpleGrantedAuthority > authorities = new ArrayList<>();
for (Roles roles1 : roles) {
System.out.println(roles1.getRoleName()+" are the roles");
authorities.add(new SimpleGrantedAuthority(roles1.getRoleName()));
}
return new org.springframework.security.core.userdetails.User(user.get().getEmail(), user.get().getPassword(), authorities);
}
else {
throw new UsernameNotFoundException("User "+ username+" does not exist");
}
}
}
1条答案
按热度按时间vvppvyoh1#
你的
UserPrincipal
和org.springframework.security.core.userdetails.User
都实现了UserDetails
接口,但是它们不互相扩展,这些类是兄弟类,它们中的任何一个都可以用来代替它们的父类型UserDetails
,但是你不能把一个强制转换成另一个。由于最终您希望使用自定义实现
UserPrincipal
来表示UserDetails
,因此问题的解决方案是停止使用Spring SecurityTM提供的User
类,并基于您从loadUserByUsername()
中的数据库检索的自定义User
类的示例来构造UserPrincipal
。以下是它的实现方式:
注:
@Autowired
,并添加了Lombok的注解@AllArgsConstructor
(或者,如果您在项目中没有使用Lombok,则可以要求IDE为您生成构造函数,请注意,除非您有多个构造函数,否则不需要使用@Autowired
进行注解)。UserPrincipal
中定义all-args构造函数,因为它在上面显示的loadUserByUsername()
实现中使用(或者您可以使用@Builder
构建器注解):