java.lang.ClassCastException:org.springframework.security.core.userdetails.User不能强制转换为model.User
我在应用程序中使用Spring安全性。我需要在应用程序的控制器中记录用户详细信息 为此,我使用此代码java.lang.ClassCastException:org.springframework.security.core.userdetails.User不能强制转换为model.User,java,spring,spring-security,Java,Spring,Spring Security,我在应用程序中使用Spring安全性。我需要在应用程序的控制器中记录用户详细信息 为此,我使用此代码 User loggedInUser = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 但是在运行这段代码时,我得到了一个classcastexception java.lang.ClassCastException: org.springframework.security.core.u
User loggedInUser = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
但是在运行这段代码时,我得到了一个classcastexception
java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to model.User
为了解决这个问题,我提到了这个
最初我使用CustomUserServiceDetails类
@Service("myUserDetailService")
@Transactional
public class CustomUserDetailsService implements UserDetailsService {
private static final Logger logger = Logger.getLogger(CustomUserDetailsService.class);
@Autowired
private UserDAO userDAO;
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException, DataAccessException {
// returns the get(0) of the user list obtained from the db
User domainUser = userDAO.getUser(name);
logger.debug("User fetched from database in loadUserByUsername method " + domainUser);
Set<Role> roles = domainUser.getRole();
logger.debug("role of the user" + roles);
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for(Role role: roles){
authorities.add(new SimpleGrantedAuthority(role.getRole()));
logger.debug("role" + role + " role.getRole()" + (role.getRole()));
}
boolean credentialNonExpired = true;
return new org.springframework.security.core.userdetails.User(domainUser.getProfileName(), domainUser.getPassword(), domainUser.isAccountEnabled(),
domainUser.isAccountNonExpired(), credentialNonExpired, domainUser.isAccountNonLocked(),authorities);
}
}
@Service(“myUserDetailService”)
@交易的
公共类CustomUserDetailsService实现UserDetailsService{
私有静态最终记录器Logger=Logger.getLogger(CustomUserDetailsService.class);
@自动连线
私有UserDAO UserDAO;
public UserDetails loadUserByUsername(字符串名)抛出UsernameNotFoundException、DataAccessException{
//返回从数据库获取的用户列表的get(0)
User domainUser=userDAO.getUser(名称);
debug(“在loadUserByUsername方法中从数据库获取的用户”+domainUser);
Set roles=domainUser.getRole();
logger.debug(“用户角色”+角色);
Set authorities=new HashSet();
for(角色:角色){
添加(新的SimpleGrantedAuthority(role.getRole());
debug(“role”+role+”role.getRole()“+(role.getRole()));
}
布尔credentialNonExpired=true;
返回新的org.springframework.security.core.userdetails.User(domainUser.getProfileName()、domainUser.getPassword()、domainUser.IsAccountabled(),
domainUser.isAccountNonExpired(),credentialNonExpired,domainUser.isAccountNonLocked(),Authories);
}
}
但是在参考了这篇文章之后,我从这里删除了grantedAuthority的设置,并将其移到了我的用户类中。在我的用户类中实现了spring security UserDetails类
现在,我的用户类中有一个额外的属性
@Entity
@Table(name = "user")
public class User implements UserDetails {
private Collection<GrantedAuthority> authorities;
@实体
@表(name=“user”)
公共类用户实现UserDetails{
私人收藏机构;
用一种方法
public void setAuthorities(Set<Role> roles) {
Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
for(Role role: roles){
authorities.add(new SimpleGrantedAuthority(role.getRole()));}
}
public void setAuthorities(设置角色){
Set authorities=new HashSet();
for(角色:角色){
添加(新的SimpleGrantedAuthority(role.getRole());}
}
答:我不确定如何将此属性映射到数据库。现有用户表架构不包含GrantedAuthority列,而且它甚至不是基元类型。我正在使用Hibernate进行对象映射。有人能告诉我获取控制器中用户类信息的正确方法吗
B.我还考虑了扩展spring的用户类和重载用户类的构造函数的方法。但是每次我在代码中的任何地方初始化用户时,我都必须提供所有构造函数参数,这一点都不好。方法.getPrincipal()返回创建的对象,并在loadUserByUsername方法中返回该对象 如果您想要一个用户,您必须在loadUserByUsername方法中返回一个用户,而不是org.springframework.security.core.userdetails.User修复了这个问题 解决方案 创建了一个CustomUserDetail类,该类实现了Spring的UserDetails接口。在其中注入了我的模型用户类
public class CustomUserDetail implements UserDetails{
private static final long serialVersionUID = 1L;
private User user;
Set<GrantedAuthority> authorities=null;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
public void setAuthorities(Set<GrantedAuthority> authorities)
{
this.authorities=authorities;
}
public String getPassword() {
return user.getPassword();
}
public String getUsername() {
return user.getProfileName();
}
public boolean isAccountNonExpired() {
return user.isAccountNonExpired();
}
public boolean isAccountNonLocked() {
return user.isAccountNonLocked();
}
public boolean isCredentialsNonExpired() {
return user.isCredentialsNonExpired();
}
public boolean isEnabled() {
return user.isAccountEnabled();
}
}
而不是使用
User loggedInUser = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
试试这个
Authentication loggedInUser = SecurityContextHolder.getContext().getAuthentication();
String username = loggedInUser.getName();
参考资料:
为什么…让你的
角色
类实现授权
…你还有ClassCastException吗?在我的应用程序中,MyUserDetails扩展了MyUser(数据库中的用户)并实现了UserDetails(spring安全性)。通过这种方式,我可以获得有关登录用户的所有信息。您是否在MyUserDetails中创建了重载构造函数?正如您的语句Bilal所理解的,我需要创建一个单独的MyUserDetails类,然后扩展我的模型用户并实现UserDetails?是的,我重载了构造函数。您不需要要做到这一点,你的代码应该可以工作。我遇到了与你类似的问题。如果你同意的话,你可以分享你的项目的一个片段来解决这个线程中讨论的问题吗?你可以使用@AuthenticationPrincipal来获取你的CustomUserDetails,而不是从上下文持有者那里获取它。我的Spring安全版本不太适合han 3.2,我相信在Spring security的早期版本中,该注释是不可用的。您从中获得用户ID了吗?
User loggedInUser = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Authentication loggedInUser = SecurityContextHolder.getContext().getAuthentication();
String username = loggedInUser.getName();