protected AuthnRequest getAuthnRequest(AuthenticationContext context) throws SAMLSSOException {

    AuthnRequest authnRequest = null;
    AuthenticationRequest authenticationRequest = context.getAuthenticationRequest();
    String[] samlRequestParams =
        authenticationRequest.getRequestQueryParam(SSOConstants.HTTP_POST_PARAM_SAML2_AUTH_REQ);
    String samlRequest = null;
    if (samlRequestParams != null && samlRequestParams.length > 0) {
      samlRequest = samlRequestParams[0];
      XMLObject xmlObject;
      if (authenticationRequest.isPost()) {
        xmlObject = unmarshall(SSOUtils.decodeForPost(samlRequest));
      } else {
        xmlObject = unmarshall(SSOUtils.decode(samlRequest));
      }
      if (xmlObject instanceof AuthnRequest) {
        authnRequest = (AuthnRequest) xmlObject;
      }
    }
    return authnRequest;
  }
  /**
   * Builds the wrapper, wrapping incoming request and information take from cache entry
   *
   * @param request Original request coming to authentication framework
   * @param cacheEntry Cache entry from the cache, which is added from calling servlets
   * @return
   */
  public static HttpServletRequest getCommonAuthReqWithParams(
      HttpServletRequest request, AuthenticationRequestCacheEntry cacheEntry) {

    // add this functionality as a constructor
    Map<String, String[]> modifiableParameters = new TreeMap<String, String[]>();
    if (cacheEntry != null) {
      AuthenticationRequest authenticationRequest = cacheEntry.getAuthenticationRequest();

      if (!authenticationRequest.getRequestQueryParams().isEmpty()) {
        modifiableParameters.putAll(authenticationRequest.getRequestQueryParams());
      }

      // Adding field variables to wrapper
      if (authenticationRequest.getType() != null) {
        modifiableParameters.put(
            FrameworkConstants.RequestParams.TYPE, new String[] {authenticationRequest.getType()});
      }
      if (authenticationRequest.getCommonAuthCallerPath() != null) {
        modifiableParameters.put(
            FrameworkConstants.RequestParams.CALLER_PATH,
            new String[] {authenticationRequest.getCommonAuthCallerPath()});
      }
      if (authenticationRequest.getRelyingParty() != null) {
        modifiableParameters.put(
            FrameworkConstants.RequestParams.ISSUER,
            new String[] {authenticationRequest.getRelyingParty()});
      }
      if (authenticationRequest.getTenantDomain() != null) {
        modifiableParameters.put(
            FrameworkConstants.RequestParams.TENANT_DOMAIN,
            new String[] {authenticationRequest.getTenantDomain()});
      }
      modifiableParameters.put(
          FrameworkConstants.RequestParams.FORCE_AUTHENTICATE,
          new String[] {String.valueOf(authenticationRequest.getForceAuth())});
      modifiableParameters.put(
          FrameworkConstants.RequestParams.PASSIVE_AUTHENTICATION,
          new String[] {String.valueOf(authenticationRequest.getPassiveAuth())});

      if (log.isDebugEnabled()) {
        StringBuilder queryStringBuilder = new StringBuilder("");

        for (Map.Entry<String, String[]> entry : modifiableParameters.entrySet()) {
          StringBuilder paramValueBuilder = new StringBuilder("");
          String[] paramValueArr = entry.getValue();

          if (paramValueArr != null) {
            for (String paramValue : paramValueArr) {
              paramValueBuilder.append("{").append(paramValue).append("}");
            }
          }

          queryStringBuilder
              .append("\n")
              .append(entry.getKey() + "=" + paramValueBuilder.toString());
        }

        log.debug("\nInbound Request parameters: " + queryStringBuilder.toString());
      }

      return new AuthenticationFrameworkWrapper(
          request, modifiableParameters, authenticationRequest.getRequestHeaders());
    }
    return request;
  }
  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());
  }