这是一个春季安全问题。
我希望能够使用
检索我的自定义用户对象对象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;
}
});
}
}
我的申请背景 -
<beans:bean id="myJdbcDaoImpl" class="package.MyJdbcDaoImpl">
<beans:property name="dataSource" ref="securityDB"/>
<beans:property name="authoritiesByUsernameQuery" value="select username,role_id from app_user,user_role where app_user.id = user_role.user_id and username=?"/>
<beans:property name="usersByUsernameQuery" value="select id,username,password,account_enabled from app_user where username = ?"/>
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="myJdbcDaoImpl">
<password-encoder hash="sha"/>
</authentication-provider>
问题是,当我做
时MyUser user = (MyUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
我得到一个例外 java.lang.ClassCastException:org.springframework.security.core.userdetails.User无法强制转换为package.MyUser
如何使用SecurityContextHolder中的其他字段访问我的用户对象?
由于
答案 0 :(得分:3)
你覆盖了错误的方法,另外覆盖了createUserDetails
,它通过loadUsersByUsername
从这些方法创建了最终的User对象:
@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;
}
如果您使用了代码, userToReturn.setId(((MyUser) userFromUserQuery).getId());
将会有效,或者您可以在loadUsersByUsername
内删除createUserDetails
并获取ID,其中doc说:
可以重写以自定义最终的创建 UserDetailsObject由loadUserByUsername返回 方法
答案 1 :(得分:0)
回答我自己的问题 -
问题不是从JdbcDaoImpl覆盖loadUserByUsername(String username)。
因此,正在调用JdbcDaoImpl的loadUserByUsername(String username)的实现,虽然内部首先调用loadUsersByUsername(String username),但随后将授予的权限添加到上面返回的MyUser对象并将其作为org.springframework.security返回。 core.userdetails.User对象。