title: How Spring Security's custom login works
body: <p>I'm trying to get through Spring Security. I have to implement a custom login form, so I need to understand very well what my configurations mean.</p>
  
  <p><strong>spring-security.xml</strong></p>
  
  <pre><code>&lt;beans:beans xmlns="http://www.springframework.org/schema/security"
      xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
      http://www.springframework.org/schema/security
      http://www.springframework.org/schema/security/spring-security-4.0.xsd"&gt;
  
      &lt;http auto-config="true"&gt;
          &lt;intercept-url pattern="/user**" access="isAuthenticated()" /&gt;
          &lt;form-login authentication-failure-url="/login" login-page="/login"
              login-processing-url="/login" default-target-url="/user" /&gt;
          &lt;logout invalidate-session="true" logout-success-url="/index"
              logout-url="/logout" /&gt;
      &lt;/http&gt;
  
      &lt;authentication-manager id="custom-auth"&gt;
          &lt;authentication-provider&gt;
              &lt;user-service&gt;
                  &lt;user name="my_username" password="my_password"
                      authorities="ROLE_USER" /&gt;
              &lt;/user-service&gt;
          &lt;/authentication-provider&gt;
      &lt;/authentication-manager&gt;
  </code></pre>
  
  <p><strong>LoginController</strong></p>
  
  <pre><code>@Controller
  public class LoginController {
      [....]
  
      @RequestMapping(value = "/login", method = RequestMethod.POST)
      public ModelAndView doLogin() {
          System.out.println("***LOGIN_POST***");
          return new ModelAndView("users/home");
      }
  
      @RequestMapping(value = "/logout", method = RequestMethod.POST)
      public ModelAndView doLogout() {
          System.out.println("***LOGOUT_POST***");
          return new ModelAndView("index");
      }
  }
  </code></pre>
  
  <p>I know I can map the /login URL with RequestMethod.GET, but when I try to intercept the POST after form submit it doesn't work.</p>
  
  <ol>
  <li>I believe, but need to confirm, that is because Security is doing
  something behind the scenes: gets username and password values from
  the posted form and compare them with the ones in the authentication
  provider: if these match, default-target-url is shown, else user
  must repeat the login. Is it right?</li>
  <li>Then my problem is: I need username and password values typed in the
  Security's login form, because I have to send an HTTP request to an
  external server to verify if these match. Before to introduce
  Security I developed this mechanism using /login GET and /login
  POST, with @ModelAttribute annotation. How can I do now?</li>
  <li>Changing the authentication-provider, using a class which implements UserDetailsService, what happens? I believe that, in this case, username and password typed in the login form are compared with the ones retrieved from the db, as these are assigned to the User object. Is it right? </li>
  </ol>
  
  <p><strong>UserDetailsServiceImpl</strong></p>
  
  <pre><code>    @Service
      public class UserDetailsServiceImpl implements UserDetailsService {
          @Autowired
          private CustomerDao customerDao;
  
          @Override
          public UserDetails loadUserByUsername(String username)
                  throws UsernameNotFoundException {
              Customer customer = customerDao.findCustomerByUsername(username);
              return new User(customer.getUsername(), customer.getPassword(), true, true, true, true,
                  Arrays.asList(new SimpleGrantedAuthority(customer.getRole())));
          }
      }
  </code></pre>
  
  <p><strong>N.B.</strong>
  User's data are not in my db at first, that's because I'm not sure about the UserDetailsService solution (in which UserDetails are loaded simply by username). To retrieve my Customer object I need both username and password (to send to a specific external URL) then, if the JSON response is positive (username and password are correct), I have to send 2 others HTTP request to get Customer's data as firstname, lastname, nationality, etc. At this point my user can be considered logged in.</p>
  
  <p>Any suggestions?
  Thanks in advance.</p>