Spring security org.springframework.security.core.userdetails.User不能强制转换为MyUser

Spring security org.springframework.security.core.userdetails.User不能强制转换为MyUser,spring-security,Spring Security,这是一个春季安全问题 我希望能够使用 SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 因为我需要额外的详细信息,比如用户id和我的类中进一步的业务逻辑 为此,我有一个从org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl派生的自定义类,我在其中重写了loadUsersByUsername()以填充其他用户字段,并返回一个MyUse

这是一个春季安全问题

我希望能够使用

SecurityContextHolder.getContext().getAuthentication().getPrincipal();
因为我需要额外的详细信息,比如用户id和我的类中进一步的业务逻辑

为此,我有一个从org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl派生的自定义类,我在其中重写了loadUsersByUsername()以填充其他用户字段,并返回一个MyUser对象和其他字段,如用户id等

代码-

public class MyJdbcDaoImpl extends JdbcDaoImpl {

@Override
protected List<UserDetails> loadUsersByUsername(String username) {
    return getJdbcTemplate().query(getUsersByUsernameQuery(), new String[] {username}, new RowMapper<UserDetails>() {
        public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
            Long id = rs.getLong(1);
            String username = rs.getString(2);
            String password = rs.getString(3);
            boolean enabled = rs.getBoolean(4);
            MyUser user = new MyUser(username, password, enabled, true, true, true, AuthorityUtils.NO_AUTHORITIES);
            user.setId(id);
            return user;
        }

    });
}
}
我有个例外 java.lang.ClassCastException:org.springframework.security.core.userdetails.User不能强制转换为package.MyUser

我应该怎么做才能从SecurityContextHolder访问带有附加字段的用户对象


谢谢你回答我自己的问题-

问题不是从JdbcDaoImpl重写loadUserByUsername(字符串用户名)


因此,JdbcDaoImpl的loadUserByUsername(字符串用户名)的实现被调用,虽然它在内部首先调用loadUsersByUsername(字符串用户名),随后将授予的权限添加到上面返回的MyUser对象,并将其作为org.springframework.security.core.userdetails.User对象返回。

您重写了错误的方法,另外重写了
createUserDetails
,该方法通过
loadUsersByUsername
从这些获取的对象创建最终用户对象:

@Override
protected UserDetails createUserDetails(final String username,
    final UserDetails userFromUserQuery,
    final List<GrantedAuthority> combinedAuthorities) {
  String returnUsername = userFromUserQuery.getUsername();

  if (!isUsernameBasedPrimaryKey()) {
    returnUsername = username;
  }

  final MyUser userToReturn = new MyUser(returnUsername,
      userFromUserQuery.getPassword(), userFromUserQuery.isEnabled(), true,
      true, true, combinedAuthorities);
  userToReturn.setId(((MyUser) userFromUserQuery).getId());
  return userToReturn;
}
@覆盖
受保护的UserDetails createUserDetails(最终字符串用户名,
最终用户详细信息userFromUserQuery,
最终列表(合并权限){
字符串returnUsername=userFromUserQuery.getUsername();
如果(!isUsernameBasedPrimaryKey()){
returnUsername=用户名;
}
最终MyUser userToReturn=新MyUser(returnUsername,
userFromUserQuery.getPassword(),userFromUserQuery.isEnabled(),true,
真的,真的,联合授权);
setId(((MyUser)userFromUserQuery.getId());
返回用户返回;
}
userToReturn.setId(((MyUser)userFromUserQuery.getId())将起作用,或者您可以删除
loadUsersByUsername
并在
createUserDetails
中获取id,该文档说明:

可以重写以自定义最终样式的创建 由loadUserByUsername返回的UserDetailsObject 方法


在调试中,从
SecurityContextHolder.getContext().getAuthentication().getPrincipal()
返回的对象的运行时类是什么?spring默认用户类-org.springframework.security.core.userdetails.users您可以通过编辑您的问题向我们展示
package.MyJdbcDaoImpl
代码吗?我已经编辑了我的问题并添加了代码。谢谢。我想我找到了问题所在。我没有覆盖loadUserByUsername(字符串用户名),JdbcDaoImpl的实现返回一个“org.springframework.security.core.userdetails.User”对象。太好了,我将把实现更改为覆盖createUserDetails()。谢谢只是澄清一下:请记住,只有当您也重写了loadUsersByUsername时,userFromUserQuery才会是
MyUser
实例,并且作为替代方法,您可以将loadUsersByUsername和提取id直接放在createUserDetails;中。)@Xaerxess我也面临同样的问题,我尝试了你的代码,但没有成功。最后,我提出了一个问题,请你看看并告诉我哪里出了问题。
MyUser user = (MyUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
@Override
protected UserDetails createUserDetails(final String username,
    final UserDetails userFromUserQuery,
    final List<GrantedAuthority> combinedAuthorities) {
  String returnUsername = userFromUserQuery.getUsername();

  if (!isUsernameBasedPrimaryKey()) {
    returnUsername = username;
  }

  final MyUser userToReturn = new MyUser(returnUsername,
      userFromUserQuery.getPassword(), userFromUserQuery.isEnabled(), true,
      true, true, combinedAuthorities);
  userToReturn.setId(((MyUser) userFromUserQuery).getId());
  return userToReturn;
}