public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String samlAction = request.getParameter("samlAction");
    String SAMLRequest = request.getParameter("SAMLRequest");
    String returnPage = request.getParameter("returnPage");
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    String relayStateURL = request.getParameter("RelayState");

    boolean continueLogin = true;

    if (SAMLRequest == null || SAMLRequest.equals("null")) {
      continueLogin = false;
      request.setAttribute("error", "ERROR: Unspecified SAML parameters.");
    } else if (samlAction == null) {
      continueLogin = false;
      request.setAttribute("error", "ERROR: Invalid SAML action.");
    } else if (returnPage != null) {
      try {
        // Parse the SAML request and extract the ACS URL and provider name
        // Extract the Assertion Consumer Service URL from AuthnRequest
        String requestXmlString = decodeAuthnRequestXML(SAMLRequest);
        String[] samlRequestAttributes = getRequestAttributes(requestXmlString);
        String issueInstant = samlRequestAttributes[0];
        String providerName = samlRequestAttributes[1];
        String acsURL = samlRequestAttributes[2];
        String requestId = samlRequestAttributes[3];

        /*
         * Stage II: Whereas Stage I uses a hardcoded username
         * (demouser@psosamldemo.net), in Stage II you need to modify the code
         * to call your user authentication application.
         */

        username = login(username, password);

        // The following lines of code set variables used in the UI.
        request.setAttribute("issueInstant", issueInstant);
        request.setAttribute("providerName", providerName);
        request.setAttribute("acsURL", acsURL);
        request.setAttribute("requestId", requestId);
        request.setAttribute("domainName", domainName);
        request.setAttribute("username", username);
        request.setAttribute("relayStateURL", relayStateURL);

        if (username == null) {
          request.setAttribute("error", "Login Failed: Invalid user.");
        } else {
          // Acquire public and private DSA keys

          /*
           * Stage III: Update the DSA filenames to identify the locations of
           * the DSA/RSA keys that digitally sign SAML responses for your
           * domain. The keys included in the reference implementation sign SAML
           * responses for the psosamldemo.net domain.
           */
          String publicKeyFilePath = getServletContext().getRealPath(
            "./keys/DSAPublicKey01.key");
          String privateKeyFilePath = getServletContext().getRealPath(
            "./keys/DSAPrivateKey01.key");

          DSAPublicKey publicKey = (DSAPublicKey) Util.getPublicKey(
            publicKeyFilePath, "DSA");
          DSAPrivateKey privateKey = (DSAPrivateKey) Util.getPrivateKey(
            privateKeyFilePath, "DSA");

          // Check for valid parameter values for SAML response

          // First, verify that the NotBefore and NotOnOrAfter values are valid
          String notBefore = Util.getNotBeforeDateAndTime();
          String notOnOrAfter = Util.getNotOnOrAfterDateAndTime();
          request.setAttribute("notBefore", notBefore);
          request.setAttribute("notOnOrAfter", notOnOrAfter);

          if (!validSamlDateFormat(issueInstant)) {
            continueLogin = false;
            request.setAttribute("error",
              "ERROR: Invalid NotBefore date specified - " + notBefore);
          } else if (!validSamlDateFormat(notOnOrAfter)) {
            continueLogin = false;
            request.setAttribute("notOnOrAfter", notOnOrAfter);
            request.setAttribute("error",
              "ERROR: Invalid NotOnOrAfter date specified - " + notOnOrAfter);
          } 

          // Sign XML containing user name with specified keys
          if (continueLogin) {
            // Generate SAML response contaning specified user name
            String responseXmlString = createSamlResponse(username, notBefore,
                notOnOrAfter, requestId, acsURL);

            // Sign the SAML response XML
            String signedSamlResponse = signResponse(responseXmlString,
              publicKey, privateKey);
            request.setAttribute("samlResponse", signedSamlResponse);
          }
        }
      } catch (SamlException e) {
        request.setAttribute("error", e.getMessage());
      }
    }
    // Forward SAML response to ACS
    request.getRequestDispatcher(returnPage).include(request, response);
  }