ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpotts/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * of the Common Development and Distribution License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * (the License). You may not use this file except in
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You can obtain a copy of the License at
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * opensso/legal/CDDLv1.0.txt
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * permission and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Header Notice in each file and include the License file
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * at opensso/legal/CDDLv1.0.txt.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below the CDDL Header,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * with the fields enclosed by brackets [] replaced by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * your own identifying information:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * $Id: Response.java,v 1.3 2009/02/13 04:05:10 bina Exp $
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpotts * Portions Copyrighted 2014-2016 ForgeRock AS.
b3b3b7da0bb140cb1fe4613cc2e322683dc034d5James Phillpotts */
b3b3b7da0bb140cb1fe4613cc2e322683dc034d5James Phillpottspackage com.sun.identity.saml.protocol;
cc87cf22700a4a41bf0eba0d9579db53e7cedd94James Phillpotts
ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpottsimport static org.forgerock.openam.utils.Time.*;
ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpotts
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.common.SystemConfigurationUtil;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.xml.XMLUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.DateUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.assertion.Assertion;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLConstants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLRequesterException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLRequestVersionTooHighException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLRequestVersionTooLowException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLResponderException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLVersionMismatchException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.xmlsig.XMLSignatureManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.ByteArrayOutputStream;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.InputStream;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.text.ParseException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.ArrayList;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Collections;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Date;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Iterator;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.List;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport org.w3c.dom.Document;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport org.w3c.dom.Element;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport org.w3c.dom.Node;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport org.w3c.dom.NodeList;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This <code>Response</code> class represents a Response XML document.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The schema of Response is defined as the following:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @supported.all.api
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpublic class Response extends AbstractResponse {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected Status status = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected List assertions = Collections.EMPTY_LIST;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected String xmlString = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected String signatureString = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected String issuer = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Response ID attribute name
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static final String RESPONSE_ID_ATTRIBUTE = "ResponseID";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /** default constructor */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected Response() {}
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Return whether the signature on the object is valid or not.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return true if the signature on the object is valid; false otherwise.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public boolean isSignatureValid() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signed & ! validationDone) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster valid = SAMLUtils.checkSignatureValid(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xmlString, RESPONSE_ID_ATTRIBUTE, issuer);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster validationDone = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return valid;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Method that signs the Response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @exception SAMLException if could not sign the Response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void signXML() throws SAMLException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signed) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response.signXML: the response is "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "already signed.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("alreadySigned"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String certAlias =
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SystemConfigurationUtil.getProperty(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "com.sun.identity.saml.xmlsig.certalias");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (certAlias == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response.signXML: couldn't obtain "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "this site's cert alias.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLResponderException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("cannotFindCertAlias"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster XMLSignatureManager manager = XMLSignatureManager.getInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((majorVersion == 1) && (minorVersion == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Request.signXML: sign with version 1.0");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signatureString = manager.signXML(this.toString(true, true),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster certAlias);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // this block is used for later return of signature element by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // getSignature() method
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signature =
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster XMLUtils.toDOMDocument(signatureString, SAMLUtils.debug)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster .getDocumentElement();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Document doc = XMLUtils.toDOMDocument(this.toString(true, true),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // sign with SAML 1.1 spec & include cert in KeyInfo
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signature = manager.signXML(doc, certAlias, null,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster RESPONSE_ID_ATTRIBUTE, getResponseID(), true, null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signatureString = XMLUtils.print(signature);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signed = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xmlString = this.toString(true, true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private void buildResponse(String responseID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String inResponseTo,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Status status,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String recipient,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List contents) throws SAMLException
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((responseID == null) || (responseID.length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // generate one
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.responseID = SAMLUtils.generateID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (this.responseID == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("errorGenerateID"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.responseID = responseID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.inResponseTo = inResponseTo;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.recipient = recipient;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpotts issueInstant = newDate();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (status == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response: missing <Status>.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("missingElement"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.status = status;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((contents != null) &&
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (contents != Collections.EMPTY_LIST)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int length = contents.size();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < length; i++) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Object temp = contents.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!(temp instanceof Assertion)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response: Wrong input "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "for Assertion.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("wrongInput"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertions = contents;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This constructor shall only be used at the server side to construct
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * a Response object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * NOTE: The content here is just the body for the Response. The
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * constructor will add the unique <code>ResponseID</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>MajorVersion</code>, etc. to form a complete Response object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param responseID If it's null, the constructor will create one.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param inResponseTo the <code>RequestID</code> that this response is
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * corresponding. It could be null or empty string "".
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param status The status of the response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param contents A List of Assertions that are the content of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Response. It could be null when there is no Assertion.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws SAMLException if error occurs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Response(String responseID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String inResponseTo,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Status status,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List contents) throws SAMLException
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster buildResponse(responseID, inResponseTo, status, null, contents);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This constructor shall only be used at the server side to construct
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * a Response object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * NOTE: The content here is just the body for the Response. The
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * constructor will add the unique <code>ResponseID</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>MajorVersion</code>, etc. to form a complete Response object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param responseID If it's null, the constructor will create one.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param inResponseTo the <code>RequestID</code> that this response is
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * corresponding. It could be null or empty string "".
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param status The status of the response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param recipient The intended recipient of the response. It could be
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * null or empty string since it's optional.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param contents A List of Assertions that are the content of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Response. It could be null when there is no Assertion.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws SAMLException if error occurs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Response(String responseID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String inResponseTo,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Status status,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String recipient,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List contents) throws SAMLException
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster buildResponse(responseID, inResponseTo, status, recipient, contents);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This constructor shall only be used at the server side to construct
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * a Response object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * NOTE: The content here is just the body for the Response. The
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * constructor will add the unique <code>ResponseID</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>MajorVersion</code>, etc. to form a complete Response object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param responseID If it's null, the constructor will create one.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param status The status of the response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param recipient The intended recipient of the response. It could be
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * null or empty string since it's optional.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param contents A List of Assertions that are the content of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Response. It could be null when there is no Assertion.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws SAMLException if error occurs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Response(String responseID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Status status,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String recipient,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List contents) throws SAMLException
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster buildResponse(responseID, null, status, recipient, contents);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This constructor shall only be used at the server side to construct
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * a Response object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * NOTE: The content here is just the body for the Response. The
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * constructor will add the unique <code>ResponseID</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>MajorVersion</code>, etc. to form a complete Response object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param responseID If it's null, the constructor will create one.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param status The status of the response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param contents A List of Assertions that are the content of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Response. It could be null when there is no Assertion.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws SAMLException if error occurs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Response(String responseID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Status status,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List contents) throws SAMLException
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster buildResponse(responseID, null, status, null, contents);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns Response object based on the XML document received from server.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method is used primarily at the client side. The schema of the XML
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * document is describe above.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param xml The Response XML document String.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * NOTE: this is a complete SAML response XML string with
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>ResponseID</code>, <code>MajorVersion</code>, etc.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return Response object based on the XML document received from server.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @exception SAMLException if XML parsing failed
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static Response parseXML(String xml) throws SAMLException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // parse the xml string
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Document doc = XMLUtils.toDOMDocument(xml, SAMLUtils.debug);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Element root = doc.getDocumentElement();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return new Response(root);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns Response object based on the XML document received from server.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method is used primarily at the client side. The schema of the XML
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * document is describe above.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param is The Response XML <code>InputStream</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * NOTE: The <code>InputStream</code> contains a complete
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * SAML response with
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>ResponseID</code>, <code>MajorVersion</code>, etc.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return Response object based on the XML document received from server.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @exception SAMLException if XML parsing failed
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static Response parseXML(InputStream is) throws SAMLException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Document doc = XMLUtils.toDOMDocument(is, SAMLUtils.debug);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Element root = doc.getDocumentElement();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return new Response(root);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Constructor.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param root <code>Response</code> element
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @throws SAMLException if error occurs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Response(Element root) throws SAMLException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Make sure this is a Response
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (root == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element): null input.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("nullInput"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String tag = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (((tag = root.getLocalName()) == null) ||
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (!tag.equals("Response"))) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element): wrong input.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("wrongInput"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List signs = XMLUtils.getElementsByTagNameNS1(root,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLConstants.XMLSIG_NAMESPACE_URI,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLConstants.XMLSIG_ELEMENT_NAME);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int signsSize = signs.size();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signsSize == 1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xmlString = XMLUtils.print(root);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signed = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (signsSize != 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element): included more than"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + " one Signature element.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("moreElement"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Attribute ResponseID
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster responseID = root.getAttribute("ResponseID");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((responseID == null) || (responseID.length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response.parseXML: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "Reponse doesn't have ResponseID.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("missingAttribute"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Attribute InResponseTo
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (root.hasAttribute("InResponseTo")) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster inResponseTo = root.getAttribute("InResponseTo");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Attribute MajorVersion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster parseMajorVersion(root.getAttribute("MajorVersion"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster parseMinorVersion(root.getAttribute("MinorVersion"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (root.hasAttribute("Recipient")) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster recipient = root.getAttribute("Recipient");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Attribute IssueInstant
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String instantString = root.getAttribute("IssueInstant");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((instantString == null) || (instantString.length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element): missing IssueInstant");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("missingAttribute"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster issueInstant = DateUtils.stringToDate(instantString);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (ParseException e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Resposne(Element): could not parse IssueInstant", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(SAMLUtils.bundle.getString(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "wrongInput"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NodeList nl = root.getChildNodes();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Node child;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String childName;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int length = nl.getLength();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < length; i++) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster child = nl.item(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((childName = child.getLocalName()) != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (childName.equals("Signature")) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signature = (Element) child;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (childName.equals("Status")) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (status != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response: included more"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + " than one <Status>");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("moreElement"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster status = new Status((Element) child);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (childName.equals("Assertion")) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (assertions == Collections.EMPTY_LIST) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertions = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Element canoEle = SAMLUtils.getCanonicalElement(child);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (canoEle == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("errorCanonical"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Assertion oneAssertion= new Assertion(canoEle);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster issuer = oneAssertion.getIssuer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertions.add(oneAssertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response: included wrong "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "element:" + childName);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("wrongInput"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } // end if childName != null
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } // end for loop
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (status == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response: missing element <Status>.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("oneElement"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Parse the input and set the majorVersion accordingly.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param majorVer a String representing the MajorVersion to be set.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @exception SAMLException when the version mismatchs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private void parseMajorVersion(String majorVer) throws SAMLException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster majorVersion = Integer.parseInt(majorVer);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (NumberFormatException e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element): invalid "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "MajorVersion", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("wrongInput"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (majorVersion != SAMLConstants.PROTOCOL_MAJOR_VERSION) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (majorVersion > SAMLConstants.PROTOCOL_MAJOR_VERSION) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element):MajorVersion of"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + " the Response is too high.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLVersionMismatchException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("responseVersionTooHigh"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element):MajorVersion of"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + " the Response is too low.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLVersionMismatchException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("responseVersionTooLow"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Parse the input and set the minorVersion accordingly.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param minorVer a String representing the MinorVersion to be set.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @exception SAMLException when the version mismatchs.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private void parseMinorVersion(String minorVer) throws SAMLException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster minorVersion = Integer.parseInt(minorVer);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (NumberFormatException e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element): invalid "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "MinorVersion", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequesterException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("wrongInput"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (minorVersion > SAMLConstants.PROTOCOL_MINOR_VERSION_ONE) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element): MinorVersion"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + " of the Response is too high.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequestVersionTooHighException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("responseVersionTooHigh"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (minorVersion < SAMLConstants.PROTOCOL_MINOR_VERSION_ZERO) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAMLUtils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.debug.message("Response(Element): MinorVersion"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + " of the Response is too low.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAMLRequestVersionTooLowException(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAMLUtils.bundle.getString("responseVersionTooLow"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method returns the set of Assertions that is the content of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return The set of Assertions that is the content of the response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * It could be Collections.EMPTY_LIST when there is no Assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * in the response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public List getAssertion() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return assertions;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Add an assertion to the Response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param assertion The assertion to be added.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return A boolean value: true if the operation is successful;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * false otherwise.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public boolean addAssertion(Assertion assertion) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signed) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (assertion == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((assertions == null) || (assertions == Collections.EMPTY_LIST)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertions = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertions.add(assertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Gets the Status of the Response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return The Status of the response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public Status getStatus() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return status;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Set the Status of the Response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param status The Status of the Response to be set.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return true if the operation is successful.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public boolean setStatus(Status status) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signed) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (status == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster this.status = status;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Set the signature for the Response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param elem ds:Signature element
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return A boolean value: true if the operation succeeds; false otherwise.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public boolean setSignature(Element elem) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signatureString = XMLUtils.print(elem);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return super.setSignature(elem);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method translates the response to an XML document String based on
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the Response schema described above.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return An XML String representing the response. NOTE: this is a
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * complete SAML response XML string with <code>ResponseID</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>MajorVersion</code>, etc.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public String toString() {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return this.toString(true, true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Creates a String representation of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>&lt;samlp:Response&gt;</code> element.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param includeNS Determines whether or not the namespace qualifier
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * is prepended to the Element when converted
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param declareNS Determines whether or not the namespace is declared
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * within the Element.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return A string containing the valid XML for this element
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public String toString(boolean includeNS, boolean declareNS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return toString(includeNS, declareNS, false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Creates a String representation of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>&lt;samlp:Response&gt;</code> element.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param includeNS Determines whether or not the namespace qualifier
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * is prepended to the Element when converted
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param declareNS Determines whether or not the namespace is declared
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * within the Element.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param includeHeader Determines whether the output include the XML
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * declaration header.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return A string containing the valid XML for this element
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public String toString(boolean includeNS,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean declareNS,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean includeHeader) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signed && (xmlString != null)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return xmlString;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer xml = new StringBuffer(300);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (includeHeader) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append("<?xml version=\"1.0\" encoding=\"").
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster append(SAMLConstants.DEFAULT_ENCODING).append("\" ?>\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String prefix = "";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String uri = "";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (includeNS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster prefix = SAMLConstants.PROTOCOL_PREFIX;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (declareNS) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster uri = SAMLConstants.PROTOCOL_NAMESPACE_STRING;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String instantString = DateUtils.toUTCDateFormat(issueInstant);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append("<").append(prefix).append("Response").append(uri).
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster append(" ResponseID=\"").append(responseID).append("\"");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (inResponseTo != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append(" InResponseTo=\"").append(inResponseTo).append("\"");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append(" MajorVersion=\"").append(majorVersion).append("\"").
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster append(" MinorVersion=\"").append(minorVersion).append("\"").
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster append(" IssueInstant=\"").append(instantString).append("\"");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (recipient != null) {
621f9bab12c9d56934d4025ee4f39a2d2abe7872Peter Major xml.append(" Recipient=\"").append(XMLUtils.escapeSpecialCharacters(recipient)).append("\"");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append(">\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signed) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signatureString != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append(signatureString);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (signature != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signatureString = XMLUtils.print(signature);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append(signatureString);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append(status.toString(includeNS, false));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((assertions != null) && (assertions != Collections.EMPTY_LIST)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Iterator j = assertions.iterator();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (j.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append(((Assertion) j.next()).toString(true, true));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster xml.append("</").append(prefix).append("Response>\n");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return xml.toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}