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;
}