相关文章推荐
淡定的盒饭  ·  ASP.NET 核心 Blazor ...·  1 月前    · 
傻傻的馒头  ·  STRING_SPLIT ...·  1 月前    · 
犯傻的黄豆  ·  Branches API | GitLab ...·  3 周前    · 
笑点低的毛豆  ·  CVPR2023 ...·  1 年前    · 
豪气的电影票  ·  dart - Flutter ...·  2 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I am getting class cast exception when I implement User class of spring security. I want to add few additional details in MyUserDetails (id) but I am not able to get the result.

This question is answered here but then two I am getting error, don't know where I am missing.

Below is my code :

SecurityConfig.java:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    @Qualifier("authenticationProvider")
    AuthenticationProvider authenticationProvider;
    @Autowired
    DataSource dataSource;
    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .passwordEncoder(passwordEncoder())
                .usersByUsernameQuery(
                        "select username,password, enabled from users where username=?")
                .authoritiesByUsernameQuery(
                        "select username, role from user_roles where username=?");
    @Bean
    public PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.headers().cacheControl().and().xssProtection().and()
                .frameOptions().and();
        http.authorizeRequests()
                .antMatchers("/sadmin/**")
                .access("hasRole('ROLE_SADMIN')")
                .antMatchers("/admin/**")
                .access("hasRole('ROLE_ADMIN') or hasRole('ROLE_SADMIN')")
                .antMatchers("/")
                .access("hasRole('ROLE_ADMIN') or hasRole('ROLE_SADMIN') or hasRole('ROLE_USER')")
                .and().formLogin()
                .loginProcessingUrl("/j_spring_security_check")
                .loginPage("/login").failureUrl("/login?error")
                .usernameParameter("username").passwordParameter("password")
                .and().logout().logoutUrl("/j_spring_security_logout")
                .logoutSuccessUrl("/login?logout").and().exceptionHandling()
                .accessDeniedPage("/403").and().csrf();
        // session management URL for reference
        // https://github.com/spring-projects/spring-security-javaconfig/blob/master/spring-security-javaconfig/src/test/groovy/org/springframework/security/config/annotation/web/configurers/NamespaceSessionManagementTests.groovy

MyUserDetails.java:

public class MyUserDetails extends User {
    private int id;
    public MyUserDetails(String username, String password, boolean enabled,
            boolean accountNonExpired, boolean credentialsNonExpired,
            boolean accountNonLocked,
            Collection<? extends GrantedAuthority> authorities) {
        super(username, password, enabled, accountNonExpired,
                credentialsNonExpired, accountNonLocked, authorities);
    // getter setter ....

CustomUserDetailsService.java:

@Service("userDetailsService")
public class CustomUserDetailsService extends JdbcDaoImpl{
    @Override
    protected List<UserDetails> loadUsersByUsername(String username) {
        return getJdbcTemplate().query(super.getUsersByUsernameQuery(), new String[] { username },
                new RowMapper<UserDetails>() {
                    public UserDetails mapRow(ResultSet rs, int rowNum) throws SQLException {
                        String username = rs.getString("username");
                        String password = rs.getString("password");
                        boolean enabled = rs.getBoolean("enabled");
                        boolean accountNonExpired = rs.getBoolean("accountNonExpired");
                        boolean credentialsNonExpired = rs.getBoolean("credentialsNonExpired");
                        boolean accountNonLocked = rs.getBoolean("accountNonLocked");
                        int id = rs.getInt("id");
                        MyUserDetails myUserDetails = new MyUserDetails(username, password, enabled, accountNonExpired, credentialsNonExpired,
                                accountNonLocked, AuthorityUtils.NO_AUTHORITIES);
                        myUserDetails.setId(id);
                        return myUserDetails;
    @Override
    protected UserDetails createUserDetails(String username, UserDetails userFromUserQuery,
            List<GrantedAuthority> combinedAuthorities) {
        String returnUsername = userFromUserQuery.getUsername();
        if (!isUsernameBasedPrimaryKey()) {
            returnUsername = username;
        final MyUserDetails myUserDetails = new MyUserDetails(returnUsername, userFromUserQuery.getPassword(), userFromUserQuery.isEnabled(),
                userFromUserQuery.isAccountNonExpired(), userFromUserQuery.isCredentialsNonExpired(),
                userFromUserQuery.isAccountNonLocked(), combinedAuthorities);
        myUserDetails.setId(((MyUserDetails) userFromUserQuery).getId());
        return myUserDetails;

Code to get MyUserDetails:

MyUserDetails userDetails = (MyUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

pom.xml:

<org.springframework.version>4.0.5.RELEASE</org.springframework.version>
<spring.security.version>4.0.1.RELEASE</spring.security.version>

Stacktrace:

SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/housing] threw exception [Request processing failed; nested exception is java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to com.esociety.dto.MyUserDetails] with root cause
java.lang.ClassCastException: org.springframework.security.core.userdetails.User cannot be cast to com.esociety.dto.MyUserDetails
    at com.esociety.controller.LoginController.dashboard(LoginController.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:168)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:96)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:655)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
                What version of Spring do you use? What stacktrace do you get? What's your XML / Java configuration for Spring Security?
– Grzegorz Rożniecki
                May 31, 2015 at 12:31
                @Xaerxess I have added spring version and stacktrace and I am using Java config. <org.springframework.version>4.0.5.RELEASE</org.springframework.version> <spring.security.version>4.0.1.RELEASE</spring.security.version>
– pise
                May 31, 2015 at 13:47

I have similar "requirements" as you and for my it is working fine. My setup is as follows

@Configuration
protected static class AuthenticationConfiguration extends
        GlobalAuthenticationConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(
                passwordEncoder);

My guess is that your problem is with auth.jdbcAuthentication() as it will provide implementation of UserDetailsService that returns core security User and does not use your implementation at all. See javadoc:

Add JDBC authentication to the AuthenticationManagerBuilder and return a JdbcUserDetailsManagerConfigurer to allow customization of the JDBC authentication. This method also ensure that a UserDetailsService is available for the getDefaultUserDetailsService() method. Note that additional UserDetailsService's may override this UserDetailsService as the default.

Can you please help me with code for Add JDBC authentication to the AuthenticationManagerBuilder and return a JdbcUserDetailsManagerConfigurer to allow customization of the JDBC authentication and also I need to create AuthenticationConfiguration class? – pise Jun 3, 2015 at 8:25 that's from javadoc (it is quoted) and it should just explain why your solution might not work. my suggestion is to use auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder) instead of your auth.jdbcAuthentication() – sodik Jun 3, 2015 at 12:48 Thank You very much your hint worked for me and I am posting full code if in case some one facing the same issue it would be easy for him. – pise Jun 4, 2015 at 10:55

I have taken mkyong tutorial to add additional data in MyUserDetails (In my case email id). Please refer this link for full code, I am putting only those code were I did changes for getting email id.

Thank You all for your time and efforts. User Class

@Entity
@Table(name = "users", catalog = "test")
public class User {
private String username;
private String password;
private boolean enabled;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private String emailId;
private Set<UserRole> userRole = new HashSet<UserRole>(0);
public User() {
public User(String username, String password, boolean enabled,boolean accountNonExpired,boolean accountNonLocked,boolean credentialsNonExpired, String emailId) {
    this.username = username;
    this.password = password;
    this.enabled = enabled;
    this.accountNonExpired = accountNonExpired;
    this.accountNonLocked = accountNonLocked;
    this.credentialsNonExpired = credentialsNonExpired;
    this.emailId = emailId;
public User(String username, String password, boolean enabled,boolean accountNonExpired,boolean accountNonLocked,boolean credentialsNonExpired, Set<UserRole> userRole,String emailId) {
    this.username = username;
    this.password = password;
    this.enabled = enabled;
    this.accountNonExpired = accountNonExpired;
    this.accountNonLocked = accountNonLocked;
    this.credentialsNonExpired = credentialsNonExpired;
    this.emailId = emailId;
    this.userRole = userRole;
@Column(name = "username", unique = true, nullable = false, length = 45)
public String getUsername() {
    return this.username;
public void setUsername(String username) {
    this.username = username;
@Column(name = "password", nullable = false, length = 60)
public String getPassword() {
    return this.password;
public void setPassword(String password) {
    this.password = password;
@Column(name = "enabled", nullable = false)
public boolean isEnabled() {
    return this.enabled;
public void setEnabled(boolean enabled) {
    this.enabled = enabled;
@Column(name = "accountNonExpired", nullable = false)
public boolean isAccountNonExpired() {
    return accountNonExpired;
public void setAccountNonExpired(boolean accountNonExpired) {
    this.accountNonExpired = accountNonExpired;
@Column(name = "accountNonLocked", nullable = false)
public boolean isAccountNonLocked() {
    return accountNonLocked;
public void setAccountNonLocked(boolean accountNonLocked) {
    this.accountNonLocked = accountNonLocked;
@Column(name = "credentialsNonExpired", nullable = false)
public boolean isCredentialsNonExpired() {
    return credentialsNonExpired;
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
    this.credentialsNonExpired = credentialsNonExpired;
@Column(name = "emailId", nullable = false)
public String getEmailId() {
    return emailId;
public void setEmailId(String emailId) {
    this.emailId = emailId;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
public Set<UserRole> getUserRole() {
    return this.userRole;
public void setUserRole(Set<UserRole> userRole) {
    this.userRole = userRole;

MyUserDetails Class

public class MyUserDetails extends User {
private final String emailId;
public MyUserDetails(String username, String password, boolean enabled,
        boolean accountNonExpired, boolean credentialsNonExpired,
        boolean accountNonLocked,String emailId,
        Collection<? extends GrantedAuthority> authorities) {
    super(username, password, enabled, accountNonExpired,
            credentialsNonExpired, accountNonLocked, authorities);
    // TODO Auto-generated constructor stub
    this.emailId = emailId;
public String getEmailId() {
    return emailId;

MyUserDetailsService Class

@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserDao userDao;
@Transactional(readOnly=true)
@Override
public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
    com.mkyong.users.model.User user = userDao.findByUserName(username);
    List<GrantedAuthority> authorities = buildUserAuthority(user.getUserRole());
    return buildUserForAuthentication(user, authorities);
private User buildUserForAuthentication(com.mkyong.users.model.User user, List<GrantedAuthority> authorities) {
     MyUserDetails myUserDetails = new MyUserDetails (user.getUsername(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isAccountNonLocked(), user.isCredentialsNonExpired(), user.getEmailId(),authorities);
     return myUserDetails;
private List<GrantedAuthority> buildUserAuthority(Set<UserRole> userRoles) {
    Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
    // Build user's authorities
    for (UserRole userRole : userRoles) {
        setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
    List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);
    return Result;

Security Config class there is no change in this. This is exactly same as tutorial link but this was hint given by @sodik to change JDBCAuthentication

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/admin/**")
        .access("hasRole('ROLE_ADMIN')").and().formLogin()
        .loginPage("/login").failureUrl("/login?error")
            .usernameParameter("username")
            .passwordParameter("password")
            .and().logout().logoutSuccessUrl("/login?logout")
            .and().csrf()
            .and().exceptionHandling().accessDeniedPage("/403");
@Bean
public PasswordEncoder passwordEncoder(){
    PasswordEncoder encoder = new BCryptPasswordEncoder();
    return encoder;

AppConfig adding password in this because password was not set in tutorial link

@EnableWebMvc
@Configuration
@ComponentScan({ "com.mkyong.*" })
@EnableTransactionManagement
@Import({ SecurityConfig.class })
public class AppConfig {
    @Bean(name = "dataSource")
    public BasicDataSource dataSource() {
      BasicDataSource ds = new BasicDataSource();
      ds.setDriverClassName("com.mysql.jdbc.Driver");
      ds.setUrl("jdbc:mysql://localhost:3036/test");
      ds.setUsername("root");
      ds.setPassword("password");
      return ds;
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.