Looping - Não consigo resolver!?

Olá pessoal, estou com um probleminha estou dando um submit automatico em um form para executar um servlet e gerar um arquivo XML so que o meu problema é justamente esse arquivo XML que está retornando para mesma pagina onde esta o botao sendo assim quando ele retorna para pagina ele executa novamente o submit automatico e fica em um looping alguem pode de ajudar a resolver?

<form name=“IdentityProviderForm” action=“ProcessResponseServlet” method=“post”>
<input type=“hidden” name=“SAMLRequest” value="<%=samlRequest%>"/>
<input type=“hidden” name=“RelayState” value="<%=relayState%>"/>
<input type=“hidden” name=“returnPage” value=“identity_provider.jsp”>
<input type=“hidden” name=“samlAction” value=“Generate SAML Response”> </form>

Para dar o submit estou usando document.IdentityProviderForm.submit.click();

Isso é o script que estou usando… será que alguem sabe me dizer como resolver??? As paginas são .JSP

[ ] s

Kleber

O problema não está no seu servlet não? Faça o seguinte, veja se ele está sendo chamado, se não tente substituir o script pelo:

document.IdentityProviderForm.click&#40;&#41;

:okok:

Opa velho, eu ja tentei isso e não foi… vou postar meu servlet aqui…

Falow

package servlets;

import org.apache.commons.codec.binary.Base64;
import org.jdom.Document;

import util.SamlException;
import util.Util;
import util.XmlDigitalSigner;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * This servlet, part of the SAML-based Single Sign-On Reference Tool, takes in
 * a SAML AuthnRequest and verifies the user login credentials. Upon succesful
 * user login, it generates and signs the corresponding SAML Response, which is
 * then redirected to the specified Assertion Consumer Service.
 * 
 */
public class ProcessResponseServlet extends HttpServlet &#123;

  private final String samlResponseTemplateFile = &quot;SamlResponseTemplate.xml&quot;;
  private static final String domainName = &quot;facsumare.com.br&quot;;

  /*
   * The login method should either return a null string, if the user is not
   * successfully authenticated, or the user's username if the user is
   * successfully authenticated.
   */
  private String login&#40;String username, String password&#41; &#123;
    // Stage II&#58; Update this method to call your authentication mechanism.
    // Return username for successful authentication. Return null string
    // for failed authentication.
    return &quot;&quot;;
  &#125;

  /*
   * Retrieves the AuthnRequest from the encoded and compressed String extracted
   * from the URL. The AuthnRequest XML is retrieved in the following order&#58; &lt;p&gt;
   * 1. URL decode &lt;br&gt; 2. Base64 decode &lt;br&gt; 3. Inflate &lt;br&gt; Returns the String
   * format of the AuthnRequest XML.
   */
  private String decodeAuthnRequestXML&#40;String encodedRequestXmlString&#41;
      throws SamlException &#123;
    try &#123;
      // URL decode
      // No need to URL decode&#58; auto decoded by request.getParameter&#40;&#41; method

      // Base64 decode
      Base64 base64Decoder = new Base64&#40;&#41;;
      byte&#91;&#93; xmlBytes = encodedRequestXmlString.getBytes&#40;&quot;UTF-8&quot;&#41;;
      byte&#91;&#93; base64DecodedByteArray = base64Decoder.decode&#40;xmlBytes&#41;;

      //Uncompress the AuthnRequest data
      //First attempt to unzip the byte array according to DEFLATE &#40;rfc 1951&#41;
      try &#123;

        Inflater inflater = new Inflater&#40;true&#41;;
        inflater.setInput&#40;base64DecodedByteArray&#41;;
        // since we are decompressing, it's impossible to know how much space we
        // might need; hopefully this number is suitably big
        byte&#91;&#93; xmlMessageBytes = new byte&#91;5000&#93;;
        int resultLength = inflater.inflate&#40;xmlMessageBytes&#41;;

        if &#40;!inflater.finished&#40;&#41;&#41; &#123;
          throw new RuntimeException&#40;&quot;didn't allocate enough space to hold &quot;
            + &quot;decompressed data&quot;&#41;;
        &#125;

        inflater.end&#40;&#41;;      
        return new String&#40;xmlMessageBytes, 0, resultLength, &quot;UTF-8&quot;&#41;;
                   
      &#125; catch &#40;DataFormatException e&#41; &#123;

        // if DEFLATE fails, then attempt to unzip the byte array according to
        // zlib &#40;rfc 1950&#41;      
        ByteArrayInputStream bais = new ByteArrayInputStream&#40;
          base64DecodedByteArray&#41;;
        ByteArrayOutputStream baos = new ByteArrayOutputStream&#40;&#41;;
        InflaterInputStream iis = new InflaterInputStream&#40;bais&#41;;
        byte&#91;&#93; buf = new byte&#91;1024&#93;;
        int count = iis.read&#40;buf&#41;;
        while &#40;count != -1&#41; &#123;
          baos.write&#40;buf, 0, count&#41;;
          count = iis.read&#40;buf&#41;;
        &#125;
        iis.close&#40;&#41;;
        return new String&#40;baos.toByteArray&#40;&#41;&#41;;      
      &#125;      
      
    &#125; catch &#40;UnsupportedEncodingException e&#41; &#123;
      throw new SamlException&#40;&quot;Error decoding AuthnRequest&#58; &quot; +
            &quot;Check decoding scheme - &quot; + e.getMessage&#40;&#41;&#41;;
    &#125; catch &#40;IOException e&#41; &#123;
      throw new SamlException&#40;&quot;Error decoding AuthnRequest&#58; &quot; +
            &quot;Check decoding scheme - &quot; + e.getMessage&#40;&#41;&#41;;
    &#125;
  &#125;

  /*
   * Creates a DOM document from the specified AuthnRequest xmlString and
   * extracts the value under the &quot;AssertionConsumerServiceURL&quot; attribute
   */
  private String&#91;&#93; getRequestAttributes&#40;String xmlString&#41; throws SamlException &#123;
      Document doc = Util.createJdomDoc&#40;xmlString&#41;;
      if &#40;doc != null&#41; &#123;
        String&#91;&#93; samlRequestAttributes = new String&#91;3&#93;;
        samlRequestAttributes&#91;0&#93; = doc.getRootElement&#40;&#41;.getAttributeValue&#40;
          &quot;IssueInstant&quot;&#41;;
        samlRequestAttributes&#91;1&#93; = doc.getRootElement&#40;&#41;.getAttributeValue&#40;
          &quot;ProviderName&quot;&#41;;
        samlRequestAttributes&#91;2&#93; = doc.getRootElement&#40;&#41;.getAttributeValue&#40;
          &quot;AssertionConsumerServiceURL&quot;&#41;;
        return samlRequestAttributes;
      &#125; else &#123;
        throw new SamlException&#40;&quot;Error parsing AuthnRequest XML&#58; Null document&quot;&#41;;
      &#125;
  &#125;

  /*
   * Generates a SAML response XML by replacing the specified username on the
   * SAML response template file. Returns the String format of the XML file.
   */
  private String createSamlResponse&#40;String authenticatedUser, String notBefore,
      String notOnOrAfter&#41; throws SamlException &#123;
    String filepath = getServletContext&#40;&#41;.getRealPath&#40;
      &quot;templates/&quot; + samlResponseTemplateFile&#41;;
    String samlResponse = Util.readFileContents&#40;filepath&#41;;
    samlResponse = samlResponse.replace&#40;&quot;&lt;USERNAME_STRING&gt;&quot;, authenticatedUser&#41;;
    samlResponse = samlResponse.replace&#40;&quot;&lt;RESPONSE_ID&gt;&quot;, Util.createID&#40;&#41;&#41;;
    samlResponse = samlResponse.replace&#40;&quot;&lt;ISSUE_INSTANT&gt;&quot;, Util
      .getDateAndTime&#40;&#41;&#41;;
    samlResponse = samlResponse.replace&#40;&quot;&lt;AUTHN_INSTANT&gt;&quot;, Util
      .getDateAndTime&#40;&#41;&#41;;
    samlResponse = samlResponse.replace&#40;&quot;&lt;NOT_BEFORE&gt;&quot;, notBefore&#41;;
    samlResponse = samlResponse.replace&#40;&quot;&lt;NOT_ON_OR_AFTER&gt;&quot;, notOnOrAfter&#41;;
    samlResponse = samlResponse.replace&#40;&quot;&lt;ASSERTION_ID&gt;&quot;, Util.createID&#40;&#41;&#41;;
    return samlResponse;

  &#125;

  /*
   * Signs the SAML response XML with the specified private key, and embeds with
   * public key. Uses helper class XmlDigitalSigner to digitally sign the XML.
   */
  private String signResponse&#40;String response, DSAPublicKey publicKey,
      DSAPrivateKey privateKey&#41; throws SamlException &#123;
      return &#40;XmlDigitalSigner.signXML&#40;response, publicKey, privateKey&#41;&#41;;
  &#125;

  /*
   * Checks if the specified samlDate is formatted as per the SAML 2.0
   * specifications, namely YYYY-MM-DDTHH&#58;MM&#58;SSZ.
   */
  private boolean validSamlDateFormat&#40;String samlDate&#41; &#123;
    if &#40;samlDate == null&#41; &#123;
      return false;
    &#125;
    int indexT = samlDate.indexOf&#40;&quot;T&quot;&#41;;
    int indexZ = samlDate.indexOf&#40;&quot;Z&quot;&#41;;
    if &#40;indexT != 10 || indexZ != 19&#41; &#123;
      return false;
    &#125;
    String dateString = samlDate.substring&#40;0, indexT&#41;;
    String timeString = samlDate.substring&#40;indexT + 1, indexZ&#41;;
    SimpleDateFormat dayFormat = new SimpleDateFormat&#40;&quot;yyyy-MM-dd&quot;&#41;;
    SimpleDateFormat timeFormat = new SimpleDateFormat&#40;&quot;HH&#58;mm&#58;ss&quot;&#41;;
    ParsePosition pos = new ParsePosition&#40;0&#41;;
    Date parsedDate = dayFormat.parse&#40;dateString, pos&#41;;
    pos = new ParsePosition&#40;0&#41;;
    Date parsedTime = timeFormat.parse&#40;timeString, pos&#41;;
    if &#40;parsedDate == null || parsedTime == null&#41; &#123;
      return false;
    &#125;
    return true;
  &#125;

  /**
   * The doGet method handles HTTP GET requests sent to the
   * ProcessResponseServlet. This method's sole purpose is to interact with the
   * user interface that allows you to walk through the steps of the reference
   * implementation. In a production environment, Google's would send SAML
   * requests using HTTP POST requests.
   * 
   * This method receives an HTTP GET request and then forwards that request on
   * to the identity_provider.jsp file, which is included in Google's SAML
   * reference package. If this method receives a SAML request Read in SAML
   * AuthnRequest parameters from request and generate signed SAML response to
   * post to the Assertion Consumer Service.
   */
  public void doGet&#40;HttpServletRequest request, HttpServletResponse response&#41;
      throws ServletException, IOException &#123;
    String SAMLRequest = request.getParameter&#40;&quot;SAMLRequest&quot;&#41;;
    String relayStateURL = request.getParameter&#40;&quot;RelayState&quot;&#41;;
    if &#40;SAMLRequest != null&#41; &#123;
      try &#123;
        String requestXmlString = decodeAuthnRequestXML&#40;SAMLRequest&#41;;
        String&#91;&#93; samlRequestAttributes = getRequestAttributes&#40;requestXmlString&#41;;
        String issueInstant = samlRequestAttributes&#91;0&#93;;
        String providerName = samlRequestAttributes&#91;1&#93;;
        String acsURL = samlRequestAttributes&#91;2&#93;;
        request.setAttribute&#40;&quot;issueInstant&quot;, issueInstant&#41;;
        request.setAttribute&#40;&quot;providerName&quot;, providerName&#41;;
        request.setAttribute&#40;&quot;acsURL&quot;, acsURL&#41;;
        request.setAttribute&#40;&quot;relayStateURL&quot;, relayStateURL&#41;;
      &#125; catch &#40;SamlException e&#41; &#123;
        request.setAttribute&#40;&quot;error&quot;, e.getMessage&#40;&#41;&#41;;
      &#125;
    &#125;

    String returnPage = &quot;./identity_provider.jsp&quot;;
    request.getRequestDispatcher&#40;returnPage&#41;.include&#40;request, response&#41;;
  &#125;

  /**
   * The doPost method handles HTTP POST requests sent to the
   * ProcessResponseServlet. It then works to generate a SAML response with the
   * received parameter and then post the response to the Assertion Consumer
   * Service.
   */
  public void doPost&#40;HttpServletRequest request, HttpServletResponse response&#41;
      throws ServletException, IOException &#123;
    String samlAction = request.getParameter&#40;&quot;samlAction&quot;&#41;;
    String SAMLRequest = request.getParameter&#40;&quot;SAMLRequest&quot;&#41;;
    String returnPage = request.getParameter&#40;&quot;returnPage&quot;&#41;;
    String username = request.getParameter&#40;&quot;username&quot;&#41;;
    String password = request.getParameter&#40;&quot;password&quot;&#41;;
    String relayStateURL = request.getParameter&#40;&quot;RelayState&quot;&#41;;
    boolean continueLogin = true;

    if &#40;SAMLRequest == null || SAMLRequest.equals&#40;&quot;null&quot;&#41;&#41; &#123;
      continueLogin = false;
      request.setAttribute&#40;&quot;error&quot;, &quot;ERROR&#58; Unspecified SAML parameters.&quot;&#41;;
    &#125; else if &#40;samlAction == null&#41; &#123;
      continueLogin = false;
      request.setAttribute&#40;&quot;error&quot;, &quot;ERROR&#58; Invalid SAML action.&quot;&#41;;
    &#125; else if &#40;returnPage != null&#41; &#123;
      try &#123;
        // Parse the SAML request and extract the ACS URL and provider name
        // Extract the Assertion Consumer Service URL from AuthnRequest
        String requestXmlString = decodeAuthnRequestXML&#40;SAMLRequest&#41;;
        String&#91;&#93; samlRequestAttributes = getRequestAttributes&#40;requestXmlString&#41;;
        String issueInstant = samlRequestAttributes&#91;0&#93;;
        String providerName = samlRequestAttributes&#91;1&#93;;
        String acsURL = samlRequestAttributes&#91;2&#93;;

        /*
         * Stage II&#58; Whereas Stage I uses a hardcoded username
         * &#40;demouser@psosamldemo.net&#41;, in Stage II you need to modify the code
         * to call your user authentication application.
         */

        username = login&#40;username, password&#41;;

        // The following lines of code set variables used in the UI.
        request.setAttribute&#40;&quot;issueInstant&quot;, issueInstant&#41;;
        request.setAttribute&#40;&quot;providerName&quot;, providerName&#41;;
        request.setAttribute&#40;&quot;acsURL&quot;, acsURL&#41;;
        request.setAttribute&#40;&quot;domainName&quot;, domainName&#41;;
        request.setAttribute&#40;&quot;username&quot;, username&#41;;
        request.setAttribute&#40;&quot;relayStateURL&quot;, relayStateURL&#41;;
              
        if &#40;username == null&#41; &#123;
          request.setAttribute&#40;&quot;error&quot;, &quot;Login Failed&#58; Invalid user.&quot;&#41;;
        &#125; else &#123;
          // Acquire public and private DSA keys

          /*
           * Stage III&#58; 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&#40;&#41;.getRealPath&#40;
            &quot;./keys/DSAPublicKey01.key&quot;&#41;;
          String privateKeyFilePath = getServletContext&#40;&#41;.getRealPath&#40;
            &quot;./keys/DSAPrivateKey01.key&quot;&#41;;

          DSAPublicKey publicKey = &#40;DSAPublicKey&#41; Util.getPublicKey&#40;
            publicKeyFilePath, &quot;DSA&quot;&#41;;
          DSAPrivateKey privateKey = &#40;DSAPrivateKey&#41; Util.getPrivateKey&#40;
            privateKeyFilePath, &quot;DSA&quot;&#41;;

          // Check for valid parameter values for SAML response

          // First, verify that the NotBefore and NotOnOrAfter values are valid
          String notBefore = &quot;2003-04-17T00&#58;46&#58;02Z&quot;;
          String notOnOrAfter = &quot;2008-04-17T00&#58;51&#58;02Z&quot;;
          request.setAttribute&#40;&quot;notBefore&quot;, notBefore&#41;;
          request.setAttribute&#40;&quot;notOnOrAfter&quot;, notOnOrAfter&#41;;

          if &#40;!validSamlDateFormat&#40;issueInstant&#41;&#41; &#123;
            continueLogin = false;
            request.setAttribute&#40;&quot;error&quot;,
              &quot;ERROR&#58; Invalid NotBefore date specified - &quot; + notBefore&#41;;
          &#125; else if &#40;!validSamlDateFormat&#40;notOnOrAfter&#41;&#41; &#123;
            continueLogin = false;
            request.setAttribute&#40;&quot;notOnOrAfter&quot;, &quot;2008-04-17T00&#58;51&#58;02Z&quot;&#41;;
            request.setAttribute&#40;&quot;error&quot;,
              &quot;ERROR&#58; Invalid NotOnOrAfter date specified - &quot; + notOnOrAfter&#41;;
          &#125; 

          // Sign XML containing user name with specified keys
          if &#40;continueLogin&#41; &#123;
            // Generate SAML response contaning specified user name
            String responseXmlString = createSamlResponse&#40;username, notBefore,
                notOnOrAfter&#41;;

            // Sign the SAML response XML
            String signedSamlResponse = signResponse&#40;responseXmlString,
              publicKey, privateKey&#41;;
            request.setAttribute&#40;&quot;samlResponse&quot;, signedSamlResponse&#41;;
          &#125;
        &#125;
      &#125; catch &#40;SamlException e&#41; &#123;
        request.setAttribute&#40;&quot;error&quot;, e.getMessage&#40;&#41;&#41;;
      &#125;
    &#125;
    // Forward SAML response to ACS
    request.getRequestDispatcher&#40;returnPage&#41;.include&#40;request, response&#41;;
  &#125;
&#125;

Opa,

Veja este while seu. Sugiro debugar sua classe.

:okok:

Tenta colocar uma campo hidden como flag pra dizer que já deu um submit uma vez. Tipo

[code]
String sFlag = new String();
sFlag = req.getParametes("flag");
if(sFlag.length()>0)
//já leu a página uma vez
else
//a flag é virgem

//e no meio da sua página coloca algo que de carga na flag como
<input type = "hidden" name = "flag" value = "S" >
[/code]