org.springframework.security.core.userdetails.User cannot be cast to MyUser

spring-security

Solution

You've overriden wrong method, additionally override `createUserDetails` which creates final User object from these fetched via `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());` will work if you used your code, or you can remove `loadUsersByUsername` and fetch id right inside `createUserDetails` which doc's says:

Can be overridden to customize the creation of the final UserDetailsObject which is returned by the loadUserByUsername method.

Problem

This is a spring security question. I want to be able to retrieve my custom User object object using ``` SecurityContextHolder.getContext().getAuthentication().getPrincipal(); ``` because I need additional details like user id and stuff for further business logic in my classes. For this, I have a custom class derived from org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl where I've overriden loadUsersByUsername() to populate additional user fields and return an object of MyUser with the extra fields like user id etc. Code - ``` 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; } }); } } ``` My application context - ``` <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> ``` The issue is, when I do a ``` MyUser user = (MyUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); ``` I get an exception java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to package.MyUser What should I do to access my user object with additional fields from SecurityContextHolder? Thanks

Original source

Related problems