public AuthOutcome authenticate() {
    if (log.isTraceEnabled()) {
      log.trace("--> authenticate()");
    }

    BearerTokenRequestAuthenticator bearer = createBearerTokenAuthenticator();
    if (log.isTraceEnabled()) {
      log.trace("try bearer");
    }

    AuthOutcome outcome = bearer.authenticate(facade);
    if (outcome == AuthOutcome.FAILED) {
      challenge = bearer.getChallenge();
      log.debug("Bearer FAILED");
      return AuthOutcome.FAILED;
    } else if (outcome == AuthOutcome.AUTHENTICATED) {
      if (verifySSL()) return AuthOutcome.FAILED;
      completeAuthentication(bearer, "KEYCLOAK");
      log.debug("Bearer AUTHENTICATED");
      return AuthOutcome.AUTHENTICATED;
    }

    if (deployment.isEnableBasicAuth()) {
      BasicAuthRequestAuthenticator basicAuth = createBasicAuthAuthenticator();
      if (log.isTraceEnabled()) {
        log.trace("try basic auth");
      }

      outcome = basicAuth.authenticate(facade);
      if (outcome == AuthOutcome.FAILED) {
        challenge = basicAuth.getChallenge();
        log.debug("BasicAuth FAILED");
        return AuthOutcome.FAILED;
      } else if (outcome == AuthOutcome.AUTHENTICATED) {
        log.debug("BasicAuth AUTHENTICATED");
        completeAuthentication(basicAuth, "BASIC");
        return AuthOutcome.AUTHENTICATED;
      }
    }

    if (deployment.isBearerOnly()) {
      challenge = bearer.getChallenge();
      log.debug("NOT_ATTEMPTED: bearer only");
      return AuthOutcome.NOT_ATTEMPTED;
    }

    if (log.isTraceEnabled()) {
      log.trace("try oauth");
    }

    if (tokenStore.isCached(this)) {
      if (verifySSL()) return AuthOutcome.FAILED;
      log.debug("AUTHENTICATED: was cached");
      return AuthOutcome.AUTHENTICATED;
    }

    OAuthRequestAuthenticator oauth = createOAuthAuthenticator();
    outcome = oauth.authenticate();
    if (outcome == AuthOutcome.FAILED) {
      challenge = oauth.getChallenge();
      return AuthOutcome.FAILED;
    } else if (outcome == AuthOutcome.NOT_ATTEMPTED) {
      challenge = oauth.getChallenge();
      return AuthOutcome.NOT_ATTEMPTED;
    }

    if (verifySSL()) return AuthOutcome.FAILED;

    completeAuthentication(oauth);

    // redirect to strip out access code and state query parameters
    facade.getResponse().setHeader("Location", oauth.getStrippedOauthParametersRequestUri());
    facade.getResponse().setStatus(302);
    facade.getResponse().end();

    log.debug("AUTHENTICATED");
    return AuthOutcome.AUTHENTICATED;
  }