@Override
  public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory)
      throws ServerAuthException {
    if (log.isTraceEnabled()) {
      log.trace("*** authenticate");
    }
    Request request = resolveRequest(req);
    JettyHttpFacade facade = new JettyHttpFacade(request, (HttpServletResponse) res);
    SamlDeployment deployment = deploymentContext.resolveDeployment(facade);
    if (deployment == null || !deployment.isConfigured()) {
      log.debug("*** deployment isn't configured return false");
      return Authentication.UNAUTHENTICATED;
    }
    boolean isEndpoint =
        request.getRequestURI().substring(request.getContextPath().length()).endsWith("/saml");
    if (!mandatory && !isEndpoint) return new DeferredAuthentication(this);
    JettySamlSessionStore tokenStore = getTokenStore(request, facade, deployment);

    SamlAuthenticator authenticator = null;
    if (isEndpoint) {
      authenticator =
          new SamlAuthenticator(facade, deployment, tokenStore) {
            @Override
            protected void completeAuthentication(SamlSession account) {}

            @Override
            protected SamlAuthenticationHandler createBrowserHandler(
                HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
              return new SamlEndpoint(facade, deployment, sessionStore);
            }
          };

    } else {
      authenticator =
          new SamlAuthenticator(facade, deployment, tokenStore) {
            @Override
            protected void completeAuthentication(SamlSession account) {}

            @Override
            protected SamlAuthenticationHandler createBrowserHandler(
                HttpFacade facade, SamlDeployment deployment, SamlSessionStore sessionStore) {
              return new BrowserHandler(facade, deployment, sessionStore);
            }
          };
    }
    AuthOutcome outcome = authenticator.authenticate();
    if (outcome == AuthOutcome.AUTHENTICATED) {
      if (facade.isEnded()) {
        return Authentication.SEND_SUCCESS;
      }
      SamlSession samlSession = tokenStore.getAccount();
      Authentication authentication = register(request, samlSession);
      return authentication;
    }
    if (outcome == AuthOutcome.LOGGED_OUT) {
      logoutCurrent(request);
      if (deployment.getLogoutPage() != null) {
        forwardToLogoutPage(request, (HttpServletResponse) res, deployment);
      }
      return Authentication.SEND_CONTINUE;
    }

    AuthChallenge challenge = authenticator.getChallenge();
    if (challenge != null) {
      challenge.challenge(facade);
    }
    return Authentication.SEND_CONTINUE;
  }