001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: FSRequest.java,v 1.3 2008/06/25 05:46:45 qcheng Exp $ 026 * Portions Copyrighted 2014 ForgeRock AS 027 */ 028 029/** 030 * Portions Copyrighted 2012 ForgeRock AS 031 */ 032package com.sun.identity.federation.message; 033 034import java.util.List; 035import java.util.Collections; 036import java.util.ArrayList; 037import java.util.Iterator; 038import java.util.StringTokenizer; 039import org.w3c.dom.Attr; 040import org.w3c.dom.Element; 041import org.w3c.dom.Node; 042import org.w3c.dom.NodeList; 043import org.w3c.dom.NamedNodeMap; 044import org.w3c.dom.Document; 045import com.sun.identity.saml.common.SAMLConstants; 046import com.sun.identity.saml.common.SAMLException; 047import com.sun.identity.saml.common.SAMLResponderException; 048import com.sun.identity.saml.common.SAMLRequesterException; 049import com.sun.identity.saml.common.SAMLRequestVersionTooHighException; 050import com.sun.identity.saml.common.SAMLRequestVersionTooLowException; 051import com.sun.identity.saml.xmlsig.XMLSignatureManager; 052import com.sun.identity.saml.protocol.AssertionArtifact; 053import com.sun.identity.saml.protocol.AttributeQuery; 054import com.sun.identity.saml.protocol.AuthenticationQuery; 055import com.sun.identity.saml.protocol.AuthorizationDecisionQuery; 056import com.sun.identity.saml.protocol.Request; 057import com.sun.identity.saml.protocol.Query; 058import com.sun.identity.shared.DateUtils; 059import com.sun.identity.saml.assertion.AssertionIDReference; 060import com.sun.identity.federation.common.FSUtils; 061import com.sun.identity.federation.common.IFSConstants; 062import com.sun.identity.shared.xml.XMLUtils; 063 064/** 065 * This class represents a Liberty <code>Request</code>. 066 * It extends from the abstract base class <code>AbstractRequest</code>. 067 * 068 * @supported.all.api 069 * @deprecated since 12.0.0 070 */ 071@Deprecated 072public class FSRequest extends Request { 073 /* 074 * data members 075 */ 076 protected String id = null; 077 078 079 /** 080 * Returns the value of <code>id</code> attribute. 081 * 082 * @return the value of <code>id</code> attribute. 083 * @see #setID(String) 084 */ 085 public String getID() { 086 return id; 087 } 088 089 /** 090 * Sets the value of <code>id</code> attribute. 091 * 092 * @param id the value of <code>id</code> attribute. 093 * @see #getID() 094 */ 095 096 public void setID(String id) { 097 this.id = id; 098 } 099 100 /* 101 * Default Constructor. 102 */ 103 protected FSRequest() { 104 } 105 106 107 /** 108 * Constructor creates <code>Request</code> object. This 109 * shall only be used at the client side to construct a 110 * <code>Request</code> object. 111 * NOTE: The content here is just the body for the Request. The 112 * constructor will add <code>MajorVersion</code>, 113 * <code>MinorVersion</code>, etc. to form a complete Request. 114 * 115 * @param requestId the request identifier, if this 116 * value is null then one will be generated. 117 * @param query <code>AuthenticationQuery</code> to be included in 118 * the Request. 119 * @throws <code>SAMLException</code> on error. 120 */ 121 public FSRequest(String requestId, Query query) throws SAMLException { 122 super(requestId, query); 123 } 124 125 /** 126 * Constructor creates <code>Request</code> object. This 127 * shall only be used at the client side to construct a 128 * <code>Request</code> object. 129 * NOTE: The content here is just the body for the Request. The 130 * constructor will add <code>MajorVersion</code>, 131 * <code>MinorVersion</code>, etc. to form a complete Request. 132 * 133 * @param requestId the request identifier, if this 134 * value is null then one will be generated. 135 * @param contents a <code>List</code> of objects that are the contents 136 * of Request that the client wants to send to the server. 137 * It could be an : 138 * <code>AuthenticationQuery</code>, 139 * <code>AuthorizationDecisionQuery</code>, 140 * <code>AttributeQuery</code>, 1 or more 141 * <code>AssertionIDReference</code>, or 1 or more of 142 * <code>AssertionArtifact</code>. 143 * @throws <code>SAMLException</code> throws errors on exception. 144 */ 145 public FSRequest(String requestId, List contents) throws SAMLException { 146 super(requestId, contents); 147 } 148 149 150 /** 151 * Returns the <code>MinorVersion</code>. 152 * 153 * @return the <code>MinorVersion</code>. 154 * @see #setMinorVersion(int) 155 */ 156 public int getMinorVersion() { 157 return minorVersion; 158 } 159 160 /** 161 * Sets the <code>MinorVersion</code>. 162 * 163 * @param version the <code>MinorVersion</code>. 164 * @see #getMinorVersion() 165 */ 166 public void setMinorVersion(int version) { 167 minorVersion = version; 168 } 169 170 /** 171 * Parses the <code>XML</code> Document String to construct a 172 * <code>Request</code> object. This method shall only be used at the server 173 * side to reconstruct a Request object based on the XML document 174 * received from client. 175 * 176 * @param xml the <code>XML</code> Document string. 177 * @return the <code>Request</code> object. 178 * @throws <code>SAMLException</code> on error. 179 */ 180 public static Request parseXML(String xml) throws SAMLException { 181 // parse the xml string 182 Document doc = XMLUtils.toDOMDocument(xml, FSUtils.debug); 183 Element root = doc.getDocumentElement(); 184 return new FSRequest(root); 185 } 186 187 /** 188 * Constructor creates a <code>FSRequest</code> object from 189 * a <code>XML</code> Document Element. 190 * 191 * @param root the <code>XML</code> Document Element. 192 * @throws <code>SAMLException</code> on error. 193 */ 194 public FSRequest(Element root) throws SAMLException { 195 // Make sure this is a Request 196 String tag = null; 197 if (root == null) { 198 FSUtils.debug.message("Request(Element): null input."); 199 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 200 "nullInput",null); 201 } 202 if (((tag = root.getLocalName()) == null) || 203 (!tag.equals("Request"))) { 204 FSUtils.debug.message("Request(Element): wrong input"); 205 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 206 "wrongInput",null); 207 } 208 209 id = root.getAttribute("id"); 210 List signs = XMLUtils.getElementsByTagNameNS1(root, 211 SAMLConstants.XMLSIG_NAMESPACE_URI, 212 SAMLConstants.XMLSIG_ELEMENT_NAME); 213 int signsSize = signs.size(); 214 if (signsSize == 1) { 215 XMLSignatureManager manager = XMLSignatureManager.getInstance(); 216 if (id == null) { 217 valid = manager.verifyXMLSignature(root, 218 IFSConstants.REQUEST_ID, null); 219 } else { 220 valid = manager.verifyXMLSignature(root); 221 } 222 if (!valid) { 223 if (FSUtils.debug.messageEnabled()) { 224 FSUtils.debug.message("Request(Element): couldn't verify" 225 + " Request's signature."); 226 } 227 } 228 xmlString = XMLUtils.print(root); 229 signed = true; 230 } else if (signsSize != 0) { 231 if (FSUtils.debug.messageEnabled()) { 232 FSUtils.debug.message("Request(Element): included more than" 233 + " one Signature element."); 234 } 235 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 236 "moreElement",null); 237 } 238 239 // Attribute RequestID 240 requestID = root.getAttribute("RequestID"); 241 if ((requestID == null) || (requestID.length() == 0)) { 242 if (FSUtils.debug.messageEnabled()) { 243 FSUtils.debug.message("Request(Element): Request doesn't " 244 + "have a RequestID."); 245 } 246 String[] args = { IFSConstants.REQUEST_ID }; 247 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 248 "missingAttribute",args); 249 } 250 251 // Attribute MajorVersion 252 parseMajorVersion(root.getAttribute("MajorVersion")); 253 254 // Attribute MinorVersion 255 parseMinorVersion(root.getAttribute("MinorVersion")); 256 257 // Attribute IssueInstant 258 String instantString = root.getAttribute("IssueInstant"); 259 if ((instantString == null) || (instantString.length() == 0)) { 260 FSUtils.debug.message("Request(Element): missing IssueInstant"); 261 String[] args = { IFSConstants.ISSUE_INSTANT }; 262 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 263 "missingAttribute",args); 264 } else { 265 try { 266 issueInstant = DateUtils.stringToDate(instantString); 267 } catch (Exception e) { 268 FSUtils.debug.message( 269 "Request(Element): could not parse IssueInstant", e); 270 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 271 "wrongInput",null); 272 } 273 } 274 275 // get the contents of the request 276 NodeList contentnl = root.getChildNodes(); 277 Node child; 278 String nodeName; 279 String respondWith; 280 for (int i = 0, length = contentnl.getLength(); i < length; i++) { 281 child = contentnl.item(i); 282 if ((nodeName = child.getLocalName()) != null) { 283 if (nodeName.equals("RespondWith")) { 284 respondWith = XMLUtils.getElementValue((Element) child); 285 if (respondWith.length() == 0) { 286 if (FSUtils.debug.messageEnabled()) { 287 FSUtils.debug.message("Request(Element): wrong " 288 + "RespondWith value."); 289 } 290 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 291 "wrongInput",null); 292 } 293 if (respondWiths == Collections.EMPTY_LIST) { 294 respondWiths = new ArrayList(); 295 } 296 respondWiths.add(respondWith); 297 } else if (nodeName.equals("Signature")) { 298 signature = (Element) child; 299 } else if (nodeName.equals("AuthenticationQuery")) { 300 // make sure the content is not assigned already 301 if (contentType != NOT_SUPPORTED) { 302 if (FSUtils.debug.messageEnabled()) { 303 FSUtils.debug.message("Request(Element): should" 304 + "contain only one AuthenticationQuery."); 305 } 306 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 307 "wrongInput",null); 308 } 309 contentType = AUTHENTICATION_QUERY; 310 query = new AuthenticationQuery((Element) child); 311 } else if (nodeName.equals("AuthorizationDecisionQuery")) { 312 // make sure content is not assigned already 313 if (contentType != NOT_SUPPORTED) { 314 if (FSUtils.debug.messageEnabled()) { 315 FSUtils.debug.message("Request(Element): should" 316 + "contain only one " 317 + "AuthorizationDecisionQuery."); 318 } 319 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 320 "wrongInput",null); 321 } 322 contentType = AUTHORIZATION_DECISION_QUERY; 323 query = new AuthorizationDecisionQuery((Element) child); 324 } else if (nodeName.equals("AttributeQuery")) { 325 // make sure content is not assigned already 326 if (contentType != NOT_SUPPORTED) { 327 if (FSUtils.debug.messageEnabled()) { 328 FSUtils.debug.message("Request(Element): should" 329 + "contain only one AttributeQuery."); 330 } 331 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 332 "wrongInput",null); 333 } 334 contentType = ATTRIBUTE_QUERY; 335 query = new AttributeQuery((Element) child); 336 } else if (nodeName.equals("AssertionIDReference")) { 337 // make sure the content has no other elements assigned 338 if ((contentType != NOT_SUPPORTED) && 339 (contentType != ASSERTION_ID_REFERENCE)) { 340 if (FSUtils.debug.messageEnabled()) { 341 FSUtils.debug.message("Request(Element): " 342 + "contained mixed contents."); 343 } 344 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 345 "wrongInput",null); 346 } 347 contentType = ASSERTION_ID_REFERENCE; 348 if (assertionIDRefs == Collections.EMPTY_LIST) { 349 assertionIDRefs = new ArrayList(); 350 } 351 assertionIDRefs.add(new AssertionIDReference( 352 XMLUtils.getElementValue((Element) child))); 353 } else if (nodeName.equals("AssertionArtifact")) { 354 // make sure the content has no other elements assigned 355 if ((contentType != NOT_SUPPORTED) && 356 (contentType != ASSERTION_ARTIFACT)) { 357 if (FSUtils.debug.messageEnabled()) { 358 FSUtils.debug.message("Request(Element): " 359 + "contained mixed contents."); 360 } 361 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 362 "wrongInput",null); 363 } 364 contentType = ASSERTION_ARTIFACT; 365 if (artifacts == Collections.EMPTY_LIST) { 366 artifacts = new ArrayList(); 367 } 368 artifacts.add(new AssertionArtifact( 369 XMLUtils.getElementValue((Element) child))); 370 } else if (nodeName.equals("Query") || 371 nodeName.equals("SubjectQuery")) { 372 parseQuery(child); 373 } else { 374 if (FSUtils.debug.messageEnabled()) { 375 FSUtils.debug.message("Request(Element): invalid" 376 + " node" + nodeName); 377 } 378 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 379 "wrongInput",null); 380 } // check nodeName 381 } // if nodeName != null 382 } // done for the nodelist loop 383 384 if (contentType == NOT_SUPPORTED) { 385 FSUtils.debug.message("Request: empty content."); 386 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 387 "wrongInput",null); 388 } 389 } 390 391 /* Returns the value of <code>RespondWith</code> attribute. 392 * 393 * @return value of the <code>RespondWith</code> attribute. 394 * @throws <code>SAMLException</code> on error. 395 */ 396 private String checkAndGetRespondWith(String respondWith) 397 throws SAMLException { 398 if ((respondWith == null) || (respondWith.length() == 0)) { 399 FSUtils.debug.message("Request: empty RespondWith Value."); 400 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 401 "wrongInput",null); 402 } 403 404 if (respondWith.indexOf(":") == -1) { 405 return (SAMLConstants.ASSERTION_PREFIX + respondWith); 406 } else { 407 StringTokenizer st = new StringTokenizer(respondWith, ":"); 408 if (st.countTokens() != 2) { 409 FSUtils.debug.message("Request: wrong RespondWith value."); 410 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 411 "wrongInput",null); 412 } 413 st.nextToken(); 414 String temp = st.nextToken().trim(); 415 if (temp.length() == 0) { 416 FSUtils.debug.message("Request: wrong RespondWith value."); 417 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 418 "wrongInput",null); 419 } 420 return (SAMLConstants.ASSERTION_PREFIX + temp); 421 } 422 } 423 424 425 /** 426 * Sets the <code>MajorVersion</code> by parsing the version string. 427 * 428 * @param majorVer a String representing the <code>MajorVersion</code> to 429 * be set. 430 * @throws <code>FSMsgException</code> on error. 431 */ 432 433 private void parseMajorVersion(String majorVer) throws SAMLException { 434 try { 435 majorVersion = Integer.parseInt(majorVer); 436 } catch (NumberFormatException e) { 437 if (FSUtils.debug.messageEnabled()) { 438 FSUtils.debug.message("Request(Element): invalid " 439 + "MajorVersion", e); 440 } 441 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 442 "wrongInput",null); 443 } 444 445 if (majorVersion != SAMLConstants.PROTOCOL_MAJOR_VERSION) { 446 if (majorVersion > SAMLConstants.PROTOCOL_MAJOR_VERSION) { 447 if (FSUtils.debug.messageEnabled()) { 448 FSUtils.debug.message("Request(Element):MajorVersion of " 449 + "the Request is too high."); 450 } 451 throw new SAMLRequestVersionTooHighException( 452 FSUtils.BUNDLE_NAME,"requestVersionTooHigh",null); 453 } else { 454 if (FSUtils.debug.messageEnabled()) { 455 FSUtils.debug.message("Request(Element):MajorVersion of " 456 + "the Request is too low."); 457 } 458 throw new SAMLRequestVersionTooLowException(FSUtils.BUNDLE_NAME, 459 "requestVersionTooLow",null); 460 } 461 } 462 } 463 464 /** 465 * Sets the <code>MinorVersion</code> by parsing the version string. 466 * 467 * @param minorVer a String representing the <code>MinorVersion</code> to 468 * be set. 469 * @throws <code>SAMLException</code> when the version mismatchs. 470 */ 471 private void parseMinorVersion(String minorVer) throws SAMLException { 472 try { 473 minorVersion = Integer.parseInt(minorVer); 474 } catch (NumberFormatException e) { 475 if (FSUtils.debug.messageEnabled()) { 476 FSUtils.debug.message("Request(Element): invalid " 477 + "MinorVersion", e); 478 } 479 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 480 "wrongInput",null); 481 } 482 483 if(minorVersion > IFSConstants.FF_12_SAML_PROTOCOL_MINOR_VERSION) { 484 FSUtils.debug.error("Request(Element): MinorVersion" 485 + " of the Request is too high."); 486 throw new SAMLRequestVersionTooHighException(FSUtils.BUNDLE_NAME, 487 "requestVersionTooHigh",null); 488 } else if (minorVersion < 489 IFSConstants.FF_11_SAML_PROTOCOL_MINOR_VERSION) { 490 FSUtils.debug.error("Request(Element): MinorVersion" 491 + " of the Request is too low."); 492 throw new SAMLRequestVersionTooLowException(FSUtils.BUNDLE_NAME, 493 "requestVersionTooLow",null); 494 } 495 } 496 497 /** 498 * Parses the Query or <code>SubjectQuery</code> represented by 499 * a DOM tree Node. It then checks and sets data members if it is a 500 * supported query, such as <code>AuthenticationQuery</code>, 501 * <code>AttributeQeury</code>, or <code>AuthorizationDecisionQuery</code>. 502 * 503 * @param child a <code>DOM</code> Node. 504 * @throws <code>SAMLException</code> if the <code>Query</code> is invalid. 505 */ 506 private void parseQuery(Node child) throws SAMLException { 507 NamedNodeMap nm = child.getAttributes(); 508 int len = nm.getLength(); 509 String attrName; 510 String attrValue; 511 Attr attr; 512 boolean found = false; 513 for (int j = 0; j < len; j++) { 514 attr = (Attr) nm.item(j); 515 attrName = attr.getLocalName(); 516 if ((attrName != null) && (attrName.equals("type"))) { 517 attrValue = attr.getNodeValue(); 518 if (attrValue.equals("AuthenticationQueryType")) { 519 if (contentType != NOT_SUPPORTED) { 520 if (FSUtils.debug.messageEnabled()) { 521 FSUtils.debug.message("Request(Element): should" 522 + " contain only one AuthenticationQuery."); 523 } 524 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 525 "wrongInput",null); 526 } 527 contentType = AUTHENTICATION_QUERY; 528 query = new AuthenticationQuery((Element) child); 529 } else if (attrValue.equals( 530 "AuthorizationDecisionQueryType")) { 531 if (contentType != NOT_SUPPORTED) { 532 if (FSUtils.debug.messageEnabled()) { 533 FSUtils.debug.message("Request(Element): should " 534 + "contain one " 535 + "AuthorizationDecisionQuery."); 536 } 537 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 538 "wrongInput",null); 539 } 540 contentType = AUTHORIZATION_DECISION_QUERY; 541 query = new AuthorizationDecisionQuery((Element) child); 542 } else if (attrValue.equals("AttributeQueryType")) { 543 if (contentType != NOT_SUPPORTED) { 544 if (FSUtils.debug.messageEnabled()) { 545 FSUtils.debug.message("Request(Element): should " 546 + "contain one AttributeQuery."); 547 } 548 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 549 "wrongInput",null); 550 } 551 contentType = ATTRIBUTE_QUERY; 552 query = new AttributeQuery((Element) child); 553 } else { 554 if (FSUtils.debug.messageEnabled()) { 555 FSUtils.debug.message("Request(Element): This type of" 556 + " " + attrName + " is not supported."); 557 } 558 throw new SAMLResponderException(FSUtils.BUNDLE_NAME, 559 "queryNotSupported",null); 560 } // check typevalue 561 found = true; 562 break; 563 } // if found type attribute 564 } // end attribute for loop 565 // if not found type 566 if (!found) { 567 if (FSUtils.debug.messageEnabled()) { 568 FSUtils.debug.message("Request(Element): missing" 569 + " xsi:type definition in " + child.getLocalName()); 570 } 571 throw new SAMLRequesterException(FSUtils.BUNDLE_NAME, 572 "wrongInput",null); 573 } 574 } 575 576 /** 577 * Creates a String representation of the <code><samlp:Request></code> 578 * element. 579 * 580 * @return a <code>XML</code> String representing the request. 581 */ 582 public String toXMLString() { 583 return toXMLString(true, true); 584 } 585 586 /** 587 * Creates a String representation of the <code><samlp:Request></code> 588 * element. 589 * 590 * @param includeNS Determines whether or not the names pace qualifier 591 * is prepended to the Element when converted 592 * @param declareNS Determines whether or not the name space is declared 593 * within the Element. 594 * @return a string containing the valid XML for this object. 595 */ 596 public String toXMLString(boolean includeNS, boolean declareNS) { 597 return toXMLString(includeNS, declareNS, false); 598 } 599 600 /** 601 * Creates a String representation of the <code><samlp:Request></code> 602 * element. 603 * 604 * @param includeNS Determines whether or not the name space qualifier 605 * is prepended to the Element when converted 606 * @param declareNS Determines whether or not the name space is declared 607 * within the Element. 608 * @param includeHeader Determines whether the output include the XML 609 * declaration header. 610 * @return a string containing the valid XML for this object. 611 */ 612 public String toXMLString(boolean includeNS,boolean declareNS, 613 boolean includeHeader) { 614 if (signed && (xmlString != null)) { 615 return xmlString; 616 } 617 618 StringBuffer xml = new StringBuffer(300); 619 if (includeHeader) { 620 xml.append("<?xml version=\"1.0\" encoding=\""). 621 append(SAMLConstants.DEFAULT_ENCODING).append("\" ?>\n"); 622 } 623 String prefix = ""; 624 String libprefix = ""; 625 String uri = ""; 626 String liburi = ""; 627 String uriXSI=""; 628 if (includeNS) { 629 prefix = SAMLConstants.PROTOCOL_PREFIX; 630 libprefix = IFSConstants.LIB_PREFIX; 631 } 632 if (declareNS) { 633 uri = SAMLConstants.PROTOCOL_NAMESPACE_STRING; 634 if(minorVersion == IFSConstants.FF_12_SAML_PROTOCOL_MINOR_VERSION){ 635 liburi = IFSConstants.LIB_12_NAMESPACE_STRING; 636 } else { 637 liburi = IFSConstants.LIB_NAMESPACE_STRING; 638 } 639 uriXSI = IFSConstants.XSI_NAMESPACE_STRING; 640 } 641 642 String instantString = DateUtils.toUTCDateFormat(issueInstant); 643 644 xml.append("<").append(prefix).append("Request").append(uri). 645 //append(" xmlns=\"http://www.w3.org/2000/xmlns/\"").append(uri). 646 append(" ").append(liburi).append(" ").append(uriXSI); 647 if(minorVersion == IFSConstants.FF_11_SAML_PROTOCOL_MINOR_VERSION) { 648 if(id != null && !(id.length() == 0)){ 649 xml.append(" id=\"").append(id).append("\""); 650 } 651 } 652 xml.append(" RequestID=\"").append(requestID).append("\""). 653 append(" MajorVersion=\"").append(majorVersion).append("\""). 654 append(" MinorVersion=\"").append(minorVersion).append("\""). 655 append(" IssueInstant=\"").append(instantString).append("\""); 656 657 if(minorVersion == IFSConstants.FF_11_SAML_PROTOCOL_MINOR_VERSION) { 658 xml.append(" xsi:type").append("=\"").append(libprefix). 659 append("SignedSAMLRequestType").append("\""); 660 } 661 xml.append(">"); 662 if((respondWiths != null) && (respondWiths != Collections.EMPTY_LIST)){ 663 Iterator i = respondWiths.iterator(); 664 String respondWith = null; 665 while (i.hasNext()) { 666 respondWith = (String) i.next(); 667 xml.append("<").append(prefix).append("RespondWith>"); 668 if (respondWith.startsWith(SAMLConstants.ASSERTION_PREFIX)) { 669 xml.append(respondWith); 670 } else { 671 try { 672 xml.append(checkAndGetRespondWith(respondWith)); 673 } catch (SAMLException e) { 674 FSUtils.debug.error("Request.toString: ", e); 675 xml.append(respondWith); 676 } 677 } 678 xml.append("</").append(prefix).append("RespondWith>"); 679 } 680 } 681 682 if (signed) { 683 if (signatureString != null) { 684 xml.append(signatureString); 685 } else if (signature != null) { 686 signatureString = XMLUtils.print(signature); 687 xml.append(signatureString); 688 } 689 } 690 Iterator j; 691 switch (contentType) { 692 case AUTHENTICATION_QUERY: 693 xml.append(((AuthenticationQuery)query) 694 .toString(includeNS, false)); 695 break; 696 case AUTHORIZATION_DECISION_QUERY: 697 xml.append(((AuthorizationDecisionQuery)query) 698 .toString(includeNS,false)); 699 break; 700 case ATTRIBUTE_QUERY: 701 xml.append(((AttributeQuery)query).toString(includeNS, false)); 702 break; 703 case ASSERTION_ID_REFERENCE: 704 j = assertionIDRefs.iterator(); 705 while (j.hasNext()) { 706 xml.append(((AssertionIDReference) j.next()). 707 toString(true, true)); 708 } 709 break; 710 case ASSERTION_ARTIFACT: 711 j = artifacts.iterator(); 712 while (j.hasNext()) { 713 xml.append(((AssertionArtifact) 714 j.next()).toString(includeNS, false)); 715 } 716 break; 717 default: 718 break; 719 } 720 721 xml.append("</").append(prefix).append("Request>"); 722 return xml.toString(); 723 } 724}