title: Spring Security Authentication Bad Credentials Exception User Not Found
body: <p>I've been trying to implement Spring Security JDBC Authentication.  It worked for me when I used JdbcDaoImpl:</p>
  
  <pre><code>@Bean
  public UserDetailsService userDetailsService() {
      JdbcDaoImpl jdbcImpl = new JdbcDaoImpl();
      jdbcImpl.setDataSource(dataSource());
      jdbcImpl.setUsersByUsernameQuery("select username, password, enabled from admin_user where username=?");
      jdbcImpl.setAuthoritiesByUsernameQuery(
              "select admin_user.username, admin_roles.role from admin_user "
            + "INNER JOIN admin_user_roles ON admin_user.user_id = admin_user_roles.user_id "
            + "INNER JOIN admin_roles ON admin_roles.role_id = admin_user_roles.role_id "
            + "where username=?");
      return jdbcImpl;
  }
  </code></pre>
  
  <p>However, when I switched over to use custom UserDetailsService to authenticate with .loadUserByUsername(String username), it kept giving me authentication errors where the user could not be found.</p>
  
  <p>My Implementation:</p>
  
  <p>In the Custom UserDetailsService:</p>
  
  <pre><code>@Service
  public class AdminUserDetailsService implements UserDetailsService {
  
  @Autowired
  private AdminUserRepository adminUserRepository;
  
  /* (non-Javadoc)
   * @see com.asap.services.AdminUserDetailsService#loadUserByUsername(java.lang.String)
   */
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  
      try {
          AdminUser adminUser = adminUserRepository.findByUsername(username);
          Set&lt;GrantedAuthority&gt; authorities = adminUserRepository.getAuthorities(username);
          if (adminUser == null) {
              return null;
          }
          return new User(adminUser.getUsername(), adminUser.getPassword(), true, true, true, true, authorities);
      } catch (Exception e) {
          throw new UsernameNotFoundException("User not found!");
      }
  }
  }
  </code></pre>
  
  <p>In AdminUserRepository:</p>
  
  <pre><code>@Repository
  @Transactional
  public class AdminUserRepositoryImpl implements AdminUserRepository {
  
  @Autowired
  private SessionFactory sessionFactory;
  @Override
  public AdminUser findByUsername(String username) {
  
      try {
          AdminUser user = (AdminUser) sessionFactory.getCurrentSession()
                   .createQuery("FROM AdminUser adminUser " + 
                            "WHERE adminUser.username=:username")
               .setParameter("username", username);
          System.out.println("findByUsername method user: " + user);
          return user;
      } catch (HibernateException e) {
          System.out.println("findByUsername method in AdminUser throws hibernate exception: " + e.getMessage());
          return null;
      }
  }
  
  @Override
  @SuppressWarnings("unchecked")
  public Set&lt;GrantedAuthority&gt; getAuthorities(String username) {
  
      Set&lt;GrantedAuthority&gt; authorities = new HashSet&lt;GrantedAuthority&gt;();
      List&lt;ViewRole&gt; results = new ArrayList&lt;ViewRole&gt;();
  
      try {
          results = sessionFactory.getCurrentSession()
                                                         .createQuery("FROM ViewRole viewRole " +
                                                                      "WHERE viewRole.username=:username")
                                                         .setParameter("username", username)
                                                         .list();
      } catch (HibernateException e) {
          System.out.println("getAuthorities method in AdminUser throws hibernate exception: " + e.getMessage());
          return null;
      }
  
      for (ViewRole viewRole : results) {
          GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(viewRole.getRole());
          authorities.add(grantedAuthority);
      }
  
      System.out.println("User Authorities: " + authorities);
      return authorities;
  }
  }
  </code></pre>
  
  <p>In SecurityConfig:</p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
  @Autowired
  AdminUserDetailsService userDetailsService;
  
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
      auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
  }
  
  @Bean
  public PasswordEncoder passwordEncoder() {
      return new BCryptPasswordEncoder();
  }
  
  @Override
  protected void configure(HttpSecurity http) throws Exception {
      http
          .authorizeRequests()
              .anyRequest()
              .authenticated()
          .and()
              .formLogin()
              .loginPage("/login")
              .defaultSuccessUrl("/mydesk")
              .failureUrl("/login?error")
              .permitAll()
          .and()
              .logout()
              .permitAll()
          .and()
              .requiresChannel()      // HTTPS Channel Security enabled
              .anyRequest()
              .requiresSecure();
  }
  
  @Override
  public void configure(WebSecurity web) throws Exception {
      // Spring Security web filters
      web
          .ignoring()
              .antMatchers("/resources/**");
  }
  }
  </code></pre>
  
  <p>And here's the console log:</p>
  
  <blockquote>
  <pre><code>16:44:11.377 [https-jsse-nio-8443-exec-11] DEBUG     org.springframework.security.web.access.ExceptionTranslationFilter - Chain processed normally
  16:44:11.377 [https-jsse-nio-8443-exec-11] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/resources/**'
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.FilterChainProxy - /login at position 1 of 13 in additional filter chain; firing Filter: 'ChannelProcessingFilter'
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.access.channel.ChannelProcessingFilter - Request: FilterInvocation: URL: /login; ConfigAttributes: [REQUIRES_SECURE_CHANNEL]
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.FilterChainProxy - /login at position 2 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.FilterChainProxy - /login at position 3 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - HttpSession returned null object for SPRING_SECURITY_CONTEXT
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.context.HttpSessionSecurityContextRepository - No SecurityContext was available from the HttpSession: org.apache.catalina.session.StandardSessionFacade@1e4ab2e2. A new one will be created.
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.FilterChainProxy - /login at position 4 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
  16:44:15.538 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.FilterChainProxy - /login at position 5 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
  16:44:15.539 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.FilterChainProxy - /login at position 6 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
  16:44:15.539 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/logout'
  16:44:15.539 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.FilterChainProxy - /login at position 7 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
  16:44:15.539 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/login'; against '/login'
  16:44:15.539 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Request is to process authentication
  16:44:15.543 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
  16:44:15.553 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.transaction.annotation.AnnotationTransactionAttributeSource - Adding transactional method 'com.asap.repositories.AdminUserRepositoryImpl.findByUsername' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
  16:44:15.564 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'transactionManager'
  16:44:15.573 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.orm.hibernate5.HibernateTransactionManager - Creating new transaction with name [com.asap.repositories.AdminUserRepositoryImpl.findByUsername]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
  16:44:15.573 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.orm.hibernate5.HibernateTransactionManager - Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] for Hibernate transaction
  16:44:15.574 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.orm.hibernate5.HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
  16:44:15.574 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.jdbc.datasource.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:sqlserver://localhost:1433;databaseName=ASAP_DEV]
  16:44:15.803 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - begin
  16:44:15.810 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.orm.hibernate5.HibernateTransactionManager - Exposing Hibernate transaction as JDBC transaction [ConnectionID:3 ClientConnectionId: 478cbaa9-c943-4a39-a0df-44e35aa02f8d]
  16:44:15.841 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.QueryTranslatorFactoryInitiator - QueryTranslatorFactory : org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory@71b49fda
  16:44:15.842 [https-jsse-nio-8443-exec-3] INFO org.hibernate.hql.internal.QueryTranslatorFactoryInitiator - HHH000397: Using ASTQueryTranslatorFactory
  16:44:15.891 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - parse() - HQL: FROM com.asap.models.AdminUser adminUser WHERE adminUser.username=:username
  16:44:15.904 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - --- HQL AST ---
  \-[QUERY] Node: 'query'
  +-[SELECT_FROM] Node: 'SELECT_FROM'
  |  \-[FROM] Node: 'FROM'
  |     \-[RANGE] Node: 'RANGE'
  |        +-[DOT] Node: '.'
  |        |  +-[DOT] Node: '.'
  |        |  |  +-[DOT] Node: '.'
  |        |  |  |  +-[IDENT] Node: 'com'
  |        |  |  |  \-[IDENT] Node: 'asap'
  |        |  |  \-[IDENT] Node: 'models'
  |        |  \-[IDENT] Node: 'AdminUser'
  |        \-[ALIAS] Node: 'adminUser'
  \-[WHERE] Node: 'WHERE'
     \-[EQ] Node: '='
        +-[DOT] Node: '.'
        |  +-[IDENT] Node: 'adminUser'
        |  \-[IDENT] Node: 'username'
        \-[COLON] Node: ':'
           \-[IDENT] Node: 'username'
  16:44:15.904 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.ErrorCounter - throwQueryException() : no errors
  16:44:15.980 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.antlr.HqlSqlBaseWalker - select &lt;&lt; begin [level=1, statement=select]
  16:44:16.024 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.tree.FromElement - FromClause{level=1} : com.asap.models.AdminUser (adminUser) -&gt; adminuser0_
  16:44:16.029 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.tree.FromReferenceNode - Resolved : adminUser -&gt; adminuser0_.user_id
  16:44:16.031 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.tree.DotNode - getDataType() : username -&gt; org.hibernate.type.StringType@6448679f
  16:44:16.033 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.tree.FromReferenceNode - Resolved : adminUser.username -&gt; adminuser0_.username
  16:44:16.038 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.antlr.HqlSqlBaseWalker - select : finishing up [level=1, statement=select]
  16:44:16.038 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.HqlSqlWalker - processQuery() :  ( SELECT ( FromClause{level=1} dbo.admin_user adminuser0_ ) ( WHERE ( = ( adminuser0_.username adminuser0_.user_id username ) ? ) ) )
  16:44:16.048 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.HqlSqlWalker - Derived SELECT clause created.
  16:44:16.058 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.util.JoinProcessor - Using FROM fragment [dbo.admin_user adminuser0_]
  16:44:16.058 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.antlr.HqlSqlBaseWalker - select &gt;&gt; end [level=1, statement=select]
  16:44:16.059 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - --- SQL AST ---
  \-[SELECT] QueryNode: 'SELECT'  querySpaces (dbo.admin_user)
  +-[SELECT_CLAUSE] SelectClause: '{derived select clause}'
  |  +-[SELECT_EXPR] SelectExpressionImpl: 'adminuser0_.user_id as user_id1_5_' {FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=adminUser,role=null,tableName=dbo.admin_user,tableAlias=adminuser0_,origin=null,columns={,className=com.asap.models.AdminUser}}}
  |  \-[SQL_TOKEN] SqlFragment: 'adminuser0_.add_date as add_date2_5_, adminuser0_.add_user_id as add_user3_5_, adminuser0_.group_id as group_i13_5_, adminuser0_.description as descript4_5_, adminuser0_.enabled as enabled5_5_, adminuser0_.first_name as first_na6_5_, adminuser0_.last_name as last_nam7_5_, adminuser0_.middle_name as middle_n8_5_, adminuser0_.password as password9_5_, adminuser0_.update_date as update_10_5_, adminuser0_.update_user_id as update_11_5_, adminuser0_.username as usernam12_5_'
  +-[FROM] FromClause: 'FROM' FromClause{level=1, fromElementCounter=1, fromElements=1, fromElementByClassAlias=[adminUser], fromElementByTableAlias=[adminuser0_], fromElementsByPath=[], collectionJoinFromElementsByPath=[], impliedElements=[]}
  |  \-[FROM_FRAGMENT] FromElement: 'dbo.admin_user adminuser0_' FromElement{explicit,not a collection join,not a fetch join,fetch non-lazy properties,classAlias=adminUser,role=null,tableName=dbo.admin_user,tableAlias=adminuser0_,origin=null,columns={,className=com.asap.models.AdminUser}}
  \-[WHERE] SqlNode: 'WHERE'
     \-[EQ] BinaryLogicOperatorNode: '='
        +-[DOT] DotNode: 'adminuser0_.username' {propertyName=username,dereferenceType=PRIMITIVE,getPropertyPath=username,path=adminUser.username,tableAlias=adminuser0_,className=com.asap.models.AdminUser,classAlias=adminUser}
        |  +-[ALIAS_REF] IdentNode: 'adminuser0_.user_id' {alias=adminUser, className=com.asap.models.AdminUser, tableAlias=adminuser0_}
        |  \-[IDENT] IdentNode: 'username' {originalText=username}
        \-[NAMED_PARAM] ParameterNode: '?' {name=username, expectedType=org.hibernate.type.StringType@6448679f}
  16:44:16.059 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.ErrorCounter - throwQueryException() : no errors
  16:44:16.072 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - HQL: FROM com.asap.models.AdminUser adminUser WHERE adminUser.username=:username
  16:44:16.072 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.QueryTranslatorImpl - SQL: select adminuser0_.user_id as user_id1_5_, adminuser0_.add_date as add_date2_5_, adminuser0_.add_user_id as add_user3_5_, adminuser0_.group_id as group_i13_5_, adminuser0_.description as descript4_5_, adminuser0_.enabled as enabled5_5_, adminuser0_.first_name as first_na6_5_, adminuser0_.last_name as last_nam7_5_, adminuser0_.middle_name as middle_n8_5_, adminuser0_.password as password9_5_, adminuser0_.update_date as update_10_5_, adminuser0_.update_user_id as update_11_5_, adminuser0_.username as usernam12_5_ from dbo.admin_user adminuser0_ where adminuser0_.username=?
  16:44:16.072 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.hql.internal.ast.ErrorCounter - throwQueryException() : no errors
  16:44:16.124 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.orm.hibernate5.HibernateTransactionManager - Initiating transaction rollback
  16:44:16.128 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.orm.hibernate5.HibernateTransactionManager - Rolling back Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])]
  16:44:16.150 [https-jsse-nio-8443-exec-3] DEBUG org.hibernate.engine.transaction.internal.TransactionImpl - rolling back
  16:44:16.162 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.orm.hibernate5.HibernateTransactionManager - Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=ExecutableList{size=0} updates=ExecutableList{size=0} deletions=ExecutableList{size=0} orphanRemovals=ExecutableList{size=0} collectionCreations=ExecutableList{size=0} collectionRemovals=ExecutableList{size=0} collectionUpdates=ExecutableList{size=0} collectionQueuedOps=ExecutableList{size=0} unresolvedInsertDependencies=null])] after transaction
  16:44:16.278 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.authentication.dao.DaoAuthenticationProvider - User 'A.Montano.ASAP' not found
  16:44:16.279 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'delegatingApplicationListener'
  16:44:16.279 [https-jsse-nio-8443-exec-3] DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
  </code></pre>
  </blockquote>
  
  <p>I've used STS debugger to trace. Apparently the Spring security takes the username and password inputs and encoded the password, but somehow unable to get the user from the DB (It didn't even step into the repository calls).</p>