title: Spring Security login with UserDetailsService and Java config
body: <p>I am trying to add login functionality with a database lookup with Spring Security, and I am really struggling. I want to look up the user by implementing the <code>UserDetailsService</code> interface. I have read a ton of documentation and Googled for hours, but I am still stuck. Most of the examples that I could find are using XML, so maybe my problems are related to converting those to Java configuration.</p>
  
  <p><strong>UserDetailsService</strong></p>
  
  <pre><code>@Service
  public class AccountServiceImpl implements AccountService { // AccountService implements UserDetailsService
      @Override
      public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
          // The email variable is always ''
  
          List&lt;GrantedAuthority&gt; authList = new ArrayList&lt;&gt;();
          authList.add(new Role("ROLE_USER")); // Role implements GrantedAuthority
  
          return new User("test@example.com", "password", true, true, true, true, authList);
      }
  }
  </code></pre>
  
  <p><strong>Security config</strong></p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  @EnableGlobalMethodSecurity(prePostEnabled = true)
  public class SecurityConfig extends WebSecurityConfigurerAdapter {
      @Autowired
      private LogoutSuccessHandler logoutSuccessHandler;
  
      @Autowired
      private AccountService accountService;
  
  
      @Override
      @Bean
      protected AuthenticationManager authenticationManager() throws Exception {
          // This bean is required for using method security annotations
          return super.authenticationManager();
      }
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
              .formLogin()
                  .loginPage("/login")
                  .loginProcessingUrl("/login/process")
                  .failureUrl("/login?error=true")
                  .defaultSuccessUrl("/", false)
                  .and()
                  //.userDetailsService(this.accountService)
                  .logout()
                      .logoutUrl("/logout")
                      .logoutSuccessHandler(this.logoutSuccessHandler)
                      .invalidateHttpSession(true)
                  .and()
                  // Permissions here
                  .csrf().disable();
      }
  
      @Autowired
      public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
          auth
                  .inMemoryAuthentication()
                  .withUser("test@example.com").password("password").roles("USER");
      }
  
      /*@Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth
                  //.userDetailsService(this.accountService);
                  .inMemoryAuthentication()
                  .withUser("test@example.com").password("password").roles("USER").and()
                  .withUser("admin").password("password").roles("USER", "ADMIN");
      }*/
  
      /*@Bean
      public DaoAuthenticationProvider daoAuthenticationProvider() {
          DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
          provider.setUserDetailsService(this.accountService);
          return provider;
      }*/
  }
  </code></pre>
  
  <p>As you can see, there is a bunch of outcommented code, which are just some of the things I tried to make it work. I also tried with simple in-memory authentication, but that didn't work either.</p>
  
  <p><strong>login.jsp</strong></p>
  
  <pre><code>&lt;form action="/login/process" method="POST"&gt;
      &lt;input name="j_username" id="j_username" type="text" /&gt;
      &lt;input name="j_password" id="j_password" type="password" /&gt;
  
      &lt;input type="submit" value="Login" /&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p><strong>Debug</strong></p>
  
  <pre><code>DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Request is to process authentication
  
  DEBUG org.springframework.security.authentication.ProviderManager - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
  
  DEBUG org.springframework.security.authentication.dao.DaoAuthenticationProvider - User '' not found
  
  DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
  
  DEBUG org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter - Updated SecurityContextHolder to contain null Authentication
  </code></pre>
  
  <p>The above seems to always be the case for all of the configurations that I tried. I am not even sure why the <code>DaoAuthenticationProvider</code> is used, even if I try to override it; I guess it's a default. For some of the configuration above, my <code>UserDetailsService</code> implementation gets called, but with an empty string as the parameter. Also, even if I return a hard coded <code>UserDetails</code> object with the same credentials as the ones I entered in my form, the authentication still fails, and I get redirected back to <code>/login?error=true</code>.</p>
  
  <p>What am I doing wrong here? Please inform me about my mistakes or provide a simple example using Java configuration. Thanks!</p>