private ModelAndView performLogin(HttpServletRequest request, User user) {
    if (user.isDisabled())
      throw new RuntimeException("User " + user.getUsername() + " is disabled. Aborting login");

    // Update the last login time.
    new UserDao().recordLogin(user.getId());

    // Add the user object to the session. This indicates to the rest of the application whether the
    // user is logged
    // in or not. Will replace any existing user object.
    Common.setUser(request, user);
    if (logger.isDebugEnabled()) logger.debug("User object added to session");

    if (user.isFirstLogin()) return new ModelAndView(new RedirectView(newUserUrl));
    if (!StringUtils.isBlank(user.getHomeUrl()))
      return new ModelAndView(new RedirectView(user.getHomeUrl()));

    for (AuthenticationDefinition def :
        ModuleRegistry.getDefinitions(AuthenticationDefinition.class)) def.postLogin(user);

    return new ModelAndView(new RedirectView(successUrl));
  }
  @Override
  protected ModelAndView onSubmit(
      HttpServletRequest request,
      HttpServletResponse response,
      Object command,
      BindException errors)
      throws Exception {
    LoginForm login = (LoginForm) command;

    // Check if the user exists
    User user = new UserDao().getUser(login.getUsername());
    if (user == null)
      ValidationUtils.rejectValue(errors, "username", "login.validation.noSuchUser");
    else if (user.isDisabled()) ValidationUtils.reject(errors, "login.validation.accountDisabled");
    else {
      boolean authenticated = false;

      for (AuthenticationDefinition def :
          ModuleRegistry.getDefinitions(AuthenticationDefinition.class)) {
        authenticated = def.authenticate(request, response, user, login.getPassword(), errors);
        if (authenticated) break;
      }

      if (!authenticated) {
        String passwordHash = Common.encrypt(login.getPassword());

        // Validating the password against the database.
        if (!passwordHash.equals(user.getPassword()))
          ValidationUtils.reject(errors, "login.validation.invalidLogin");
      }
    }

    if (errors.hasErrors()) return showForm(request, response, errors);

    return performLogin(request, user);
  }
  @Override
  protected ModelAndView showForm(
      HttpServletRequest request,
      HttpServletResponse response,
      BindException errors,
      @SuppressWarnings("rawtypes") Map controlModel)
      throws Exception {
    LoginForm loginForm = (LoginForm) errors.getTarget();

    if (!errors.hasErrors()) checkDomain(request, errors);

    if (!errors.hasErrors()) {
      User user = null;
      for (AuthenticationDefinition def :
          ModuleRegistry.getDefinitions(AuthenticationDefinition.class)) {
        user = def.preLoginForm(request, response, loginForm, errors);
        if (user != null) break;
      }

      if (user != null) return performLogin(request, user);
    }

    return super.showForm(request, response, errors, controlModel);
  }