/**
   * Prompts user a notification with the status and message
   *
   * @param req
   * @param resp
   * @throws ServletException
   * @throws IOException
   */
  private void sendNotification(
      String errorResp,
      String status,
      String message,
      String acUrl,
      HttpServletRequest req,
      HttpServletResponse resp)
      throws ServletException, IOException {
    String redirectURL = CarbonUIUtil.getAdminConsoleURL(req);
    redirectURL =
        redirectURL.replace("samlsso/carbon/", "authenticationendpoint/samlsso_notification.do");

    // TODO Send status codes rather than full messages in the GET request
    String queryParams =
        "?"
            + SAMLSSOConstants.STATUS
            + "="
            + URLEncoder.encode(status, "UTF-8")
            + "&"
            + SAMLSSOConstants.STATUS_MSG
            + "="
            + URLEncoder.encode(message, "UTF-8");

    if (errorResp != null) {
      queryParams += "&" + SAMLSSOConstants.SAML_RESP + "=" + URLEncoder.encode(errorResp, "UTF-8");
    }

    if (acUrl != null) {
      queryParams +=
          "&" + SAMLSSOConstants.ASSRTN_CONSUMER_URL + "=" + URLEncoder.encode(acUrl, "UTF-8");
    }

    resp.sendRedirect(redirectURL + queryParams);
  }
 public GovImpactAnalysisDataProcessor(
     ServletConfig config, HttpSession session, HttpServletRequest request) throws AxisFault {
   client = new GovImpactAdminServiceClient(config, session, request);
   serverURL =
       CarbonUIUtil.getAdminConsoleURL(
           CarbonUIUtil.getServerConfigurationProperty("WebContextRoot"));
 }
  /**
   * This is override because of query string values hard coded and input values validations are not
   * required.
   *
   * @param request
   * @param response
   * @param context
   * @throws AuthenticationFailedException
   */
  @Override
  protected void initiateAuthenticationRequest(
      HttpServletRequest request, HttpServletResponse response, AuthenticationContext context)
      throws AuthenticationFailedException {

    try {
      Map<String, String> authenticatorProperties = context.getAuthenticatorProperties();
      if (authenticatorProperties != null) {
        String clientId = authenticatorProperties.get(OIDCAuthenticatorConstants.CLIENT_ID);
        String authorizationEP;
        if (getAuthorizationServerEndpoint(authenticatorProperties) != null) {
          authorizationEP = getAuthorizationServerEndpoint(authenticatorProperties);
        } else {
          authorizationEP =
              authenticatorProperties.get(OIDCAuthenticatorConstants.OAUTH2_AUTHZ_URL);
        }

        String callBackUrl =
            authenticatorProperties.get(GoogleOAuth2AuthenticationConstant.CALLBACK_URL);

        if (log.isDebugEnabled()) {
          log.debug("Google-callback-url : " + callBackUrl);
        }

        if (callBackUrl == null) {
          callBackUrl = CarbonUIUtil.getAdminConsoleURL(request);
          callBackUrl = callBackUrl.replace("commonauth/carbon/", "commonauth");
        }

        String state = context.getContextIdentifier() + "," + OIDCAuthenticatorConstants.LOGIN_TYPE;

        state = getState(state, authenticatorProperties);

        OAuthClientRequest authzRequest;

        // This is the query string need to send in order to get email and
        // profile
        String queryString = GoogleOAuth2AuthenticationConstant.QUERY_STRING;

        authzRequest =
            OAuthClientRequest.authorizationLocation(authorizationEP)
                .setClientId(clientId)
                .setRedirectURI(callBackUrl)
                .setResponseType(OIDCAuthenticatorConstants.OAUTH2_GRANT_TYPE_CODE)
                .setState(state)
                .buildQueryMessage();

        String loginPage = authzRequest.getLocationUri();
        String domain = request.getParameter("domain");

        if (domain != null) {
          loginPage = loginPage + "&fidp=" + domain;
        }

        if (queryString != null) {
          if (!queryString.startsWith("&")) {
            loginPage = loginPage + "&" + queryString;
          } else {
            loginPage = loginPage + queryString;
          }
        }
        response.sendRedirect(loginPage);

      } else {
        if (log.isDebugEnabled()) {
          log.debug("Error while retrieving properties. Authenticator Properties cannot be null");
        }
        throw new AuthenticationFailedException(
            "Error while retrieving properties. Authenticator Properties cannot be null");
      }
    } catch (IOException e) {
      throw new AuthenticationFailedException("Exception while sending to the login page", e);
    } catch (OAuthSystemException e) {
      throw new AuthenticationFailedException(
          "Exception while building authorization code request", e);
    }
  }
  /**
   * this method are overridden for extra claim request to google end-point
   *
   * @param request
   * @param response
   * @param context
   * @throws AuthenticationFailedException
   */
  @Override
  protected void processAuthenticationResponse(
      HttpServletRequest request, HttpServletResponse response, AuthenticationContext context)
      throws AuthenticationFailedException {

    try {

      Map<String, String> authenticatorProperties = context.getAuthenticatorProperties();
      String clientId = authenticatorProperties.get(OIDCAuthenticatorConstants.CLIENT_ID);
      String clientSecret = authenticatorProperties.get(OIDCAuthenticatorConstants.CLIENT_SECRET);
      String tokenEndPoint;
      if (getTokenEndpoint(authenticatorProperties) != null) {
        tokenEndPoint = getTokenEndpoint(authenticatorProperties);
      } else {
        tokenEndPoint = authenticatorProperties.get(OIDCAuthenticatorConstants.OAUTH2_TOKEN_URL);
      }

      String callBackUrl =
          authenticatorProperties.get(GoogleOAuth2AuthenticationConstant.CALLBACK_URL);

      log.debug("callBackUrl : " + callBackUrl);

      if (callBackUrl == null) {
        callBackUrl = CarbonUIUtil.getAdminConsoleURL(request);
        callBackUrl = callBackUrl.replace("commonauth/carbon/", "commonauth");
      }

      @SuppressWarnings({"unchecked"})
      Map<String, String> paramValueMap =
          (Map<String, String>) context.getProperty("oidc:param.map");

      if (paramValueMap != null && paramValueMap.containsKey("redirect_uri")) {
        callBackUrl = paramValueMap.get("redirect_uri");
      }

      OAuthAuthzResponse authzResponse = OAuthAuthzResponse.oauthCodeAuthzResponse(request);
      String code = authzResponse.getCode();

      OAuthClientRequest accessRequest = null;
      accessRequest = getAccessRequest(tokenEndPoint, clientId, clientSecret, callBackUrl, code);

      // create OAuth client that uses custom http client under the hood
      OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
      OAuthClientResponse oAuthResponse = null;
      oAuthResponse = getOAuthResponse(accessRequest, oAuthClient, oAuthResponse);
      // TODO : return access token and id token to framework
      String accessToken = "";
      String idToken = "";
      if (oAuthResponse != null) {
        accessToken = oAuthResponse.getParam(OIDCAuthenticatorConstants.ACCESS_TOKEN);
        idToken = oAuthResponse.getParam(OIDCAuthenticatorConstants.ID_TOKEN);
      }

      if (accessToken != null && (idToken != null || !requiredIDToken(authenticatorProperties))) {

        context.setProperty(OIDCAuthenticatorConstants.ACCESS_TOKEN, accessToken);

        if (idToken != null) {
          context.setProperty(OIDCAuthenticatorConstants.ID_TOKEN, idToken);

          String base64Body = idToken.split("\\.")[1];
          byte[] decoded = Base64.decodeBase64(base64Body.getBytes());
          String json = new String(decoded, Charset.forName("utf-8"));

          if (log.isDebugEnabled()) {
            log.debug("Id token json string : " + json);
          }

          Map<String, Object> jsonObject = JSONUtils.parseJSON(json);

          if (jsonObject != null) {
            Map<ClaimMapping, String> claims = getSubjectAttributes(oAuthResponse);

            String authenticatedUser =
                (String) jsonObject.get(OIDCAuthenticatorConstants.Claim.EMAIL);
            AuthenticatedUser authenticatedUserObj =
                AuthenticatedUser.createFederateAuthenticatedUserFromSubjectIdentifier(
                    authenticatedUser);
            authenticatedUserObj.setUserAttributes(claims);
            context.setSubject(authenticatedUserObj);
          } else {
            if (log.isDebugEnabled()) {
              log.debug("Decoded json object is null");
            }
            throw new AuthenticationFailedException("Decoded json object is null");
          }
        } else {
          if (log.isDebugEnabled()) {
            log.debug("Authentication Failed");
          }
          throw new AuthenticationFailedException("Authentication Failed");
        }

      } else {
        throw new AuthenticationFailedException("Authentication Failed");
      }
    } catch (OAuthProblemException e) {
      throw new AuthenticationFailedException("Error occurred while acquiring access token", e);
    } catch (JSONException e) {
      throw new AuthenticationFailedException("Error occurred while parsing json object", e);
    }
  }
  private void sendToFrameworkForLogout(
      HttpServletRequest request,
      HttpServletResponse response,
      SAMLSSOReqValidationResponseDTO signInRespDTO,
      String relayState,
      String sessionId,
      boolean invalid,
      boolean isPost)
      throws ServletException, IOException {

    SAMLSSOSessionDTO sessionDTO = new SAMLSSOSessionDTO();
    sessionDTO.setHttpQueryString(request.getQueryString());
    sessionDTO.setRelayState(relayState);
    sessionDTO.setSessionId(sessionId);
    sessionDTO.setLogoutReq(true);
    sessionDTO.setInvalidLogout(invalid);

    if (signInRespDTO != null) {
      sessionDTO.setDestination(signInRespDTO.getDestination());
      sessionDTO.setRequestMessageString(signInRespDTO.getRequestMessageString());
      sessionDTO.setIssuer(signInRespDTO.getIssuer());
      sessionDTO.setRequestID(signInRespDTO.getId());
      sessionDTO.setSubject(signInRespDTO.getSubject());
      sessionDTO.setRelyingPartySessionId(signInRespDTO.getRpSessionId());
      sessionDTO.setAssertionConsumerURL(signInRespDTO.getAssertionConsumerURL());
      sessionDTO.setValidationRespDTO(signInRespDTO);
    }

    String sessionDataKey = UUIDGenerator.generateUUID();
    addSessionDataToCache(
        sessionDataKey,
        sessionDTO,
        IdPManagementUtil.getIdleSessionTimeOut(
            CarbonContext.getThreadLocalCarbonContext().getTenantDomain()));

    String commonAuthURL = CarbonUIUtil.getAdminConsoleURL(request);
    commonAuthURL = commonAuthURL.replace("samlsso/carbon/", "commonauth");

    String selfPath = URLEncoder.encode("/samlsso", "UTF-8");

    // Add all parameters to authentication context before sending to authentication
    // framework
    AuthenticationRequest authenticationRequest = new AuthenticationRequest();
    authenticationRequest.addRequestQueryParam(
        FrameworkConstants.RequestParams.LOGOUT, new String[] {"true"});
    authenticationRequest.setRequestQueryParams(request.getParameterMap());
    authenticationRequest.setCommonAuthCallerPath(selfPath);
    authenticationRequest.setPost(isPost);

    if (signInRespDTO != null) {
      authenticationRequest.setRelyingParty(signInRespDTO.getIssuer());
    }
    authenticationRequest.appendRequestQueryParams(request.getParameterMap());
    // Add headers to AuthenticationRequestContext
    for (Enumeration e = request.getHeaderNames(); e.hasMoreElements(); ) {
      String headerName = e.nextElement().toString();
      authenticationRequest.addHeader(headerName, request.getHeader(headerName));
    }

    AuthenticationRequestCacheEntry authRequest =
        new AuthenticationRequestCacheEntry(authenticationRequest);
    FrameworkUtils.addAuthenticationRequestToCache(
        sessionDataKey,
        authRequest,
        IdPManagementUtil.getIdleSessionTimeOut(
            CarbonContext.getThreadLocalCarbonContext().getTenantDomain()));
    String queryParams =
        "?"
            + SAMLSSOConstants.SESSION_DATA_KEY
            + "="
            + sessionDataKey
            + "&"
            + "type"
            + "="
            + "samlsso";

    response.sendRedirect(commonAuthURL + queryParams);
  }
  /**
   * Sends the user for authentication to the login page
   *
   * @param req
   * @param resp
   * @param signInRespDTO
   * @param relayState
   * @throws ServletException
   * @throws IOException
   */
  private void sendToFrameworkForAuthentication(
      HttpServletRequest req,
      HttpServletResponse resp,
      SAMLSSOReqValidationResponseDTO signInRespDTO,
      String relayState,
      boolean isPost)
      throws ServletException, IOException, UserStoreException, IdentityException {

    SAMLSSOSessionDTO sessionDTO = new SAMLSSOSessionDTO();
    sessionDTO.setHttpQueryString(req.getQueryString());
    sessionDTO.setDestination(signInRespDTO.getDestination());
    sessionDTO.setRelayState(relayState);
    sessionDTO.setRequestMessageString(signInRespDTO.getRequestMessageString());
    sessionDTO.setIssuer(signInRespDTO.getIssuer());
    sessionDTO.setRequestID(signInRespDTO.getId());
    sessionDTO.setSubject(signInRespDTO.getSubject());
    sessionDTO.setRelyingPartySessionId(signInRespDTO.getRpSessionId());
    sessionDTO.setAssertionConsumerURL(signInRespDTO.getAssertionConsumerURL());
    sessionDTO.setTenantDomain(SAMLSSOUtil.getTenantDomainFromThreadLocal());

    if (sessionDTO.getTenantDomain() == null) {
      String[] splitIssuer = sessionDTO.getIssuer().split("@");
      if (splitIssuer != null
          && splitIssuer.length == 2
          && !splitIssuer[0].trim().isEmpty()
          && !splitIssuer[1].trim().isEmpty()) {
        sessionDTO.setTenantDomain(splitIssuer[1]);
      } else {
        sessionDTO.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME);
      }
    }
    SAMLSSOUtil.setTenantDomainInThreadLocal(sessionDTO.getTenantDomain());

    sessionDTO.setForceAuth(signInRespDTO.isForceAuthn());
    sessionDTO.setPassiveAuth(signInRespDTO.isPassive());
    sessionDTO.setValidationRespDTO(signInRespDTO);
    sessionDTO.setIdPInitSSO(signInRespDTO.isIdPInitSSO());

    String sessionDataKey = UUIDGenerator.generateUUID();
    addSessionDataToCache(
        sessionDataKey,
        sessionDTO,
        IdPManagementUtil.getIdleSessionTimeOut(sessionDTO.getTenantDomain()));

    String commonAuthURL = CarbonUIUtil.getAdminConsoleURL(req);
    commonAuthURL =
        commonAuthURL.replace(
            FrameworkConstants.RequestType.CLAIM_TYPE_SAML_SSO
                + "/"
                + FrameworkConstants.CARBON
                + "/",
            FrameworkConstants.COMMONAUTH);
    String selfPath =
        URLEncoder.encode("/" + FrameworkConstants.RequestType.CLAIM_TYPE_SAML_SSO, "UTF-8");
    // Setting authentication request context
    AuthenticationRequest authenticationRequest = new AuthenticationRequest();

    // Adding query parameters
    authenticationRequest.appendRequestQueryParams(req.getParameterMap());
    for (Enumeration headerNames = req.getHeaderNames(); headerNames.hasMoreElements(); ) {
      String headerName = headerNames.nextElement().toString();
      authenticationRequest.addHeader(headerName, req.getHeader(headerName));
    }

    authenticationRequest.setRelyingParty(signInRespDTO.getIssuer());
    authenticationRequest.setCommonAuthCallerPath(selfPath);
    authenticationRequest.setForceAuth(signInRespDTO.isForceAuthn());
    if (!authenticationRequest.getForceAuth()
        && authenticationRequest.getRequestQueryParam("forceAuth") != null) {
      String[] forceAuth = authenticationRequest.getRequestQueryParam("forceAuth");
      if (!forceAuth[0].trim().isEmpty() && Boolean.parseBoolean(forceAuth[0].trim())) {
        authenticationRequest.setForceAuth(Boolean.parseBoolean(forceAuth[0].trim()));
      }
    }
    authenticationRequest.setPassiveAuth(signInRespDTO.isPassive());
    authenticationRequest.setTenantDomain(sessionDTO.getTenantDomain());
    authenticationRequest.setPost(isPost);

    // Creating cache entry and adding entry to the cache before calling to commonauth
    AuthenticationRequestCacheEntry authRequest =
        new AuthenticationRequestCacheEntry(authenticationRequest);
    FrameworkUtils.addAuthenticationRequestToCache(
        sessionDataKey,
        authRequest,
        IdPManagementUtil.getIdleSessionTimeOut(sessionDTO.getTenantDomain()));
    StringBuilder queryStringBuilder = new StringBuilder();
    queryStringBuilder
        .append(commonAuthURL)
        .append("?")
        .append(SAMLSSOConstants.SESSION_DATA_KEY)
        .append("=")
        .append(sessionDataKey)
        .append("&")
        .append(FrameworkConstants.RequestParams.TYPE)
        .append("=")
        .append(FrameworkConstants.RequestType.CLAIM_TYPE_SAML_SSO);
    FrameworkUtils.setRequestPathCredentials(req);
    resp.sendRedirect(queryStringBuilder.toString());
  }
  private void handleIdPInitSSO(
      HttpServletRequest req,
      HttpServletResponse resp,
      String relayState,
      String queryString,
      String authMode,
      String sessionId,
      boolean isPost,
      boolean isLogout)
      throws UserStoreException, IdentityException, IOException, ServletException {

    String rpSessionId =
        CharacterEncoder.getSafeText(req.getParameter(MultitenantConstants.SSO_AUTH_SESSION_ID));
    SAMLSSOService samlSSOService = new SAMLSSOService();

    SAMLSSOReqValidationResponseDTO signInRespDTO =
        samlSSOService.validateIdPInitSSORequest(
            relayState,
            queryString,
            getQueryParams(req),
            CarbonUIUtil.getAdminConsoleURL(req),
            sessionId,
            rpSessionId,
            authMode,
            isLogout);

    if (!signInRespDTO.isLogOutReq()) {
      if (signInRespDTO.isValid()) {
        sendToFrameworkForAuthentication(req, resp, signInRespDTO, relayState, false);
      } else {
        if (log.isDebugEnabled()) {
          log.debug("Invalid IdP initiated SAML SSO Request");
        }

        String errorResp = signInRespDTO.getResponse();
        sendNotification(
            errorResp,
            SAMLSSOConstants.Notification.EXCEPTION_STATUS,
            SAMLSSOConstants.Notification.EXCEPTION_MESSAGE,
            signInRespDTO.getAssertionConsumerURL(),
            req,
            resp);
      }
    } else {
      if (signInRespDTO.isValid()) {
        sendToFrameworkForLogout(req, resp, signInRespDTO, relayState, sessionId, false, isPost);
      } else {
        if (log.isDebugEnabled()) {
          log.debug("Invalid IdP initiated SAML Single Logout Request");
        }

        if (signInRespDTO.isLogoutFromAuthFramework()) {
          sendToFrameworkForLogout(req, resp, null, null, sessionId, true, isPost);
        } else {
          String errorResp = signInRespDTO.getResponse();
          sendNotification(
              errorResp,
              SAMLSSOConstants.Notification.INVALID_MESSAGE_STATUS,
              SAMLSSOConstants.Notification.EXCEPTION_MESSAGE,
              signInRespDTO.getAssertionConsumerURL(),
              req,
              resp);
        }
      }
    }
  }
  /**
   * All requests are handled by this handleRequest method. In case of SAMLRequest the user will be
   * redirected to commonAuth servlet for authentication. Based on successful authentication of the
   * user a SAMLResponse is sent back to service provider. In case of logout requests, the IDP will
   * send logout requests to the other session participants and then send the logout response back
   * to the initiator.
   *
   * @param req
   * @param resp
   * @throws ServletException
   * @throws IOException
   */
  private void handleRequest(HttpServletRequest req, HttpServletResponse resp, boolean isPost)
      throws ServletException, IOException {
    String sessionId = null;
    Cookie ssoTokenIdCookie = getTokenIdCookie(req);

    if (ssoTokenIdCookie != null) {
      sessionId = ssoTokenIdCookie.getValue();
    }

    String queryString = req.getQueryString();
    if (log.isDebugEnabled()) {
      log.debug("Query string : " + queryString);
    }
    // if an openid authentication or password authentication
    String authMode = CharacterEncoder.getSafeText(req.getParameter("authMode"));
    if (!SAMLSSOConstants.AuthnModes.OPENID.equals(authMode)) {
      authMode = SAMLSSOConstants.AuthnModes.USERNAME_PASSWORD;
    }
    String relayState =
        CharacterEncoder.getSafeText(req.getParameter(SAMLSSOConstants.RELAY_STATE));
    String spEntityID =
        CharacterEncoder.getSafeText(
            req.getParameter(SAMLSSOConstants.QueryParameter.SP_ENTITY_ID.toString()));
    String samlRequest = CharacterEncoder.getSafeText(req.getParameter("SAMLRequest"));
    String sessionDataKey = CharacterEncoder.getSafeText(req.getParameter("sessionDataKey"));
    String slo =
        CharacterEncoder.getSafeText(
            req.getParameter(SAMLSSOConstants.QueryParameter.SLO.toString()));

    boolean isExpFired = false;
    try {

      String tenantDomain = CharacterEncoder.getSafeText(req.getParameter("tenantDomain"));
      SAMLSSOUtil.setTenantDomainInThreadLocal(tenantDomain);

      if (sessionDataKey != null) { // Response from common authentication framework.
        SAMLSSOSessionDTO sessionDTO = getSessionDataFromCache(sessionDataKey);

        if (sessionDTO != null) {
          SAMLSSOUtil.setTenantDomainInThreadLocal(sessionDTO.getTenantDomain());
          if (sessionDTO.isInvalidLogout()) {
            log.warn("Redirecting to default logout page due to an invalid logout request");
            String serverUrl = CarbonUIUtil.getAdminConsoleURL(req);
            resp.sendRedirect(
                serverUrl.replace(
                    SAMLSSOConstants.SAML_ENDPOINT, SAMLSSOConstants.DEFAULT_LOGOUT_LOCATION));
          } else if (sessionDTO.isLogoutReq()) {
            handleLogoutResponseFromFramework(req, resp, sessionDTO);
          } else {
            handleAuthenticationReponseFromFramework(req, resp, sessionId, sessionDTO);
          }

          removeAuthenticationResultFromCache(sessionDataKey);

        } else {
          log.error("Failed to retrieve sessionDTO from the cache for key " + sessionDataKey);
          String errorResp =
              SAMLSSOUtil.buildErrorResponse(
                  SAMLSSOConstants.StatusCodes.IDENTITY_PROVIDER_ERROR,
                  SAMLSSOConstants.Notification.EXCEPTION_STATUS,
                  null);
          sendNotification(
              errorResp,
              SAMLSSOConstants.Notification.EXCEPTION_STATUS,
              SAMLSSOConstants.Notification.EXCEPTION_MESSAGE,
              null,
              req,
              resp);
          return;
        }
      } else if (spEntityID != null || slo != null) { // idp initiated SSO/SLO
        handleIdPInitSSO(
            req, resp, relayState, queryString, authMode, sessionId, isPost, (slo != null));
      } else if (samlRequest != null) { // SAMLRequest received. SP initiated SSO
        handleSPInitSSO(
            req, resp, queryString, relayState, authMode, samlRequest, sessionId, isPost);
      } else {
        log.debug("Invalid request message or single logout message ");

        if (sessionId == null) {
          String errorResp =
              SAMLSSOUtil.buildErrorResponse(
                  SAMLSSOConstants.StatusCodes.REQUESTOR_ERROR, "Invalid request message", null);
          sendNotification(
              errorResp,
              SAMLSSOConstants.Notification.INVALID_MESSAGE_STATUS,
              SAMLSSOConstants.Notification.INVALID_MESSAGE_MESSAGE,
              null,
              req,
              resp);
        } else {
          // Non-SAML request are assumed to be logout requests
          sendToFrameworkForLogout(req, resp, null, null, sessionId, true, false);
        }
      }
    } catch (UserStoreException e) {
      if (log.isDebugEnabled()) {
        log.debug("Error occurred while handling SAML2 SSO request", e);
      }
      String errorResp = null;
      try {
        errorResp =
            SAMLSSOUtil.buildErrorResponse(
                SAMLSSOConstants.StatusCodes.IDENTITY_PROVIDER_ERROR,
                "Error occurred while handling SAML2 SSO request",
                null);
      } catch (IdentityException e1) {
        log.error("Error while building SAML response", e1);
      }
      sendNotification(
          errorResp,
          SAMLSSOConstants.Notification.EXCEPTION_STATUS,
          SAMLSSOConstants.Notification.EXCEPTION_MESSAGE,
          null,
          req,
          resp);
    } catch (IdentityException e) {
      log.error("Error when processing the authentication request!", e);
      String errorResp = null;
      try {
        errorResp =
            SAMLSSOUtil.buildErrorResponse(
                SAMLSSOConstants.StatusCodes.IDENTITY_PROVIDER_ERROR,
                "Error when processing the authentication request",
                null);
      } catch (IdentityException e1) {
        log.error("Error while building SAML response", e1);
      }
      sendNotification(
          errorResp,
          SAMLSSOConstants.Notification.EXCEPTION_STATUS,
          SAMLSSOConstants.Notification.EXCEPTION_MESSAGE,
          null,
          req,
          resp);
    }
  }