4

这是一个春季安全问题。

我希望能够使用检索我的自定义用户对象对象

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 cannot be cast to package.MyUser

我应该怎么做才能使用来自 SecurityContextHolder 的附加字段访问我的用户对象?

谢谢

4

2 回答 2

3

您覆盖了错误的方法,另外覆盖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;
}

userToReturn.setId(((MyUser) userFromUserQuery).getId());如果您使用您的代码将起作用,或者您可以在文档中删除loadUsersByUsername并获取 id :createUserDetails

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

于 2012-08-22T21:24:26.250 回答
0

回答我自己的问题-

问题不是从 JdbcDaoImpl 覆盖 loadUserByUsername(String username)。

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

于 2012-08-22T21:23:04.833 回答