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: FSLogoutResponse.java,v 1.4 2008/06/25 05:46:44 qcheng Exp $ 026 * Portions Copyrighted 2014 ForgeRock AS 027 */ 028 029package com.sun.identity.federation.message; 030 031import com.sun.identity.shared.encode.Base64; 032import com.sun.identity.shared.encode.URLEncDec; 033import com.sun.identity.shared.xml.XMLUtils; 034 035import com.sun.identity.shared.DateUtils; 036 037import com.sun.identity.federation.message.common.FSMsgException; 038import com.sun.identity.federation.common.FSUtils; 039import com.sun.identity.federation.common.IFSConstants; 040 041import com.sun.identity.saml.common.SAMLConstants; 042import com.sun.identity.saml.common.SAMLException; 043import com.sun.identity.saml.common.SAMLResponderException; 044import com.sun.identity.saml.common.SAMLVersionMismatchException; 045 046import com.sun.identity.saml.xmlsig.XMLSignatureManager; 047 048import com.sun.identity.saml.protocol.AbstractResponse; 049import com.sun.identity.saml.protocol.Status; 050import com.sun.identity.saml.protocol.StatusCode; 051 052import java.io.IOException; 053 054import java.text.ParseException; 055 056import java.util.Date; 057import java.util.List; 058 059import javax.servlet.http.HttpServletRequest; 060 061import org.w3c.dom.Element; 062import org.w3c.dom.Node; 063import org.w3c.dom.NodeList; 064import org.w3c.dom.Document; 065 066/** 067 * This class has methods to create a Liberty <code>LogoutResponse</code>. 068 * 069 * @supported.all.api 070 * @deprecated since 12.0.0 071 */ 072@Deprecated 073public class FSLogoutResponse extends AbstractResponse { 074 private String providerId; 075 private String relayState; 076 private Status status; 077 protected String xmlString; 078 protected String signatureString; 079 protected String id; 080 private String inResponseTo; 081 082 /** 083 * Default Constructor. 084 */ 085 public FSLogoutResponse() { 086 try { 087 setIssueInstant(new Date()); 088 providerId = new String(); 089 StatusCode statusCode = new StatusCode(IFSConstants.SAML_SUCCESS); 090 status = new Status(statusCode); 091 relayState = new String(); 092 } catch (SAMLException e){ 093 FSUtils.debug.error("FSLogoutResponse.constructor:", e); 094 } 095 096 } 097 098 /** 099 * Constructor creates <code>FSLogoutResponse</code> object. 100 * 101 * @param responseID the value of <code>ResponseID</code> attribute. 102 * @param inResponseTo the value of <code>inResponseTo</code> attribute. 103 * @param status the Logout <code>Status</code> object. 104 * @param providerId the value of <code>ProviderID</code> attribute. 105 * @param relayState the value of <code>RelayState</code> attribute. 106 * @throws <code>FSMsgException</code> if this object cannot be created. 107 */ 108 public FSLogoutResponse(String responseID, 109 String inResponseTo, 110 Status status, 111 String providerId, 112 String relayState) 113 throws FSMsgException { 114 if ((responseID == null) || (responseID.length() == 0)) { 115 this.responseID = FSUtils.generateID(); 116 if (this.responseID == null) { 117 throw new FSMsgException("errorGenerateID",null); 118 } 119 } else { 120 this.responseID = responseID; 121 } 122 123 if (inResponseTo == null) { 124 FSUtils.debug.message("Response: inResponseTo is null."); 125 throw new FSMsgException("nullInput",null); 126 } 127 this.inResponseTo = inResponseTo; 128 if (status == null) { 129 FSUtils.debug.message("Response: missing <Status>."); 130 throw new FSMsgException("missingElement",null); 131 } 132 this.status = status; 133 this.providerId = providerId; 134 this.relayState = relayState; 135 setIssueInstant(new Date()); 136 } 137 138 /** 139 * Constructor creates <code>FSLogoutResponse</code> object from 140 * a Document element. 141 * 142 * @param root the Document element object. 143 * @throws FSMsgException if this object cannot be created. 144 * @throws SAMLException if there is an error. 145 */ 146 public FSLogoutResponse(Element root) throws FSMsgException, SAMLException { 147 if (root == null) { 148 FSUtils.debug.message("FSLogoutResponse.parseXML: null input."); 149 throw new FSMsgException("nullInput",null); 150 } 151 String tag = null; 152 if (((tag = root.getLocalName()) == null) || 153 (!tag.equals(IFSConstants.LOGOUT_RESPONSE))) { 154 FSUtils.debug.message("FSLogoutResponse.parseXML: wrong input."); 155 throw new FSMsgException("wrongInput",null); 156 } 157 158 id = root.getAttribute(IFSConstants.ID); 159 160 // Attribute ResponseID 161 responseID = root.getAttribute(IFSConstants.RESPONSE_ID); 162 if ((responseID == null) || (responseID.length() == 0)) { 163 if (FSUtils.debug.messageEnabled()) { 164 FSUtils.debug.message("FSLogoutResponse.parseXML: " 165 + "Reponse doesn't have ResponseID."); 166 } 167 String[] args = { IFSConstants.RESPONSE_ID }; 168 throw new FSMsgException("missingAttribute",args); 169 } 170 parseMajorVersion(root.getAttribute(IFSConstants.MAJOR_VERSION)); 171 parseMinorVersion(root.getAttribute(IFSConstants.MINOR_VERSION)); 172 // Attribute InResponseTo 173 inResponseTo = root.getAttribute(IFSConstants.IN_RESPONSE_TO); 174 if (inResponseTo == null) { 175 if (FSUtils.debug.messageEnabled()) { 176 FSUtils.debug.message("FSLogoutResponse.parseXML: " 177 + "Response doesn't have InResponseTo."); 178 } 179 String[] args = { IFSConstants.IN_RESPONSE_TO }; 180 throw new FSMsgException("missingAttribute",args); 181 } 182 // Attribute IssueInstant 183 String instantString = root.getAttribute(IFSConstants.ISSUE_INSTANT); 184 if ((instantString == null) || (instantString.length() == 0)) { 185 FSUtils.debug.message("FSLogoutResponse(Element): " 186 + "missing IssueInstant"); 187 String[] args = { IFSConstants.ISSUE_INSTANT }; 188 throw new FSMsgException("missingAttribute",args); 189 } else { 190 try { 191 issueInstant = DateUtils.stringToDate(instantString); 192 } catch (ParseException e) { 193 if (FSUtils.debug.messageEnabled()) { 194 FSUtils.debug.message( 195 "FSLogoutResponse(Element): could not " + 196 "parse IssueInstant", e); 197 } 198 throw new FSMsgException("wrongInput", null); 199 } 200 } 201 202 NodeList nl = root.getChildNodes(); 203 Node child; 204 String childName; 205 int length = nl.getLength(); 206 for (int i = 0; i < length; i++) { 207 child = nl.item(i); 208 if ((childName = child.getLocalName()) != null) { 209 if (childName.equals(IFSConstants.STATUS)) { 210 if (status != null) { 211 if (FSUtils.debug.messageEnabled()) { 212 FSUtils.debug.message( 213 "FSLogoutResponse: included more" 214 + " than one <Status>"); 215 } 216 throw new FSMsgException("moreElement",null); 217 } 218 status = new Status((Element) child); 219 } else if (childName.equals(IFSConstants.SIGNATURE)) { 220 } else if (childName.equals(IFSConstants.PROVIDER_ID)) { 221 if (providerId != null) { 222 if (FSUtils.debug.messageEnabled()) { 223 FSUtils.debug.message( 224 "FSLogoutResponse: included more" 225 + " than one providerId"); 226 } 227 throw new FSMsgException("moreElement",null); 228 } 229 providerId = XMLUtils.getElementValue((Element) child); 230 } else if (childName.equals(IFSConstants.RELAY_STATE)) { 231 relayState = XMLUtils.getElementValue((Element) child); 232 } else { 233 if (FSUtils.debug.messageEnabled()) { 234 FSUtils.debug.message("FSLogoutResponse: included wrong" 235 + " element:" + childName); 236 } 237 throw new FSMsgException("wrongInput",null); 238 } 239 } // end if childName != null 240 } // end for loop 241 242 if (status == null) { 243 FSUtils.debug.message("FSLogoutResponse:missing element <Status>."); 244 throw new FSMsgException("oneElement",null); 245 } 246 247 if (providerId == null) { 248 FSUtils.debug.message( 249 "FSLogoutResponse: missing element providerId."); 250 throw new FSMsgException("oneElement",null); 251 } 252 253 //check for signature 254 List signs = XMLUtils.getElementsByTagNameNS1(root, 255 SAMLConstants.XMLSIG_NAMESPACE_URI, 256 SAMLConstants.XMLSIG_ELEMENT_NAME); 257 int signsSize = signs.size(); 258 if (signsSize == 1) { 259 Element elem = (Element)signs.get(0); 260 setSignature(elem); 261 xmlString = XMLUtils.print(root); 262 signed = true; 263 } else if (signsSize != 0) { 264 if (FSUtils.debug.messageEnabled()) { 265 FSUtils.debug.message( 266 "FSLogoutResponse(Element): included more than" 267 + " one Signature element."); 268 } 269 throw new FSMsgException("moreElement",null); 270 } 271 } 272 273 /** 274 * Returns the value of <code>RelayState</code> attribute. 275 * 276 * @return the value of <code>RelayState</code> attribute. 277 * @see #setRelayState(String) 278 */ 279 public String getRelayState(){ 280 return relayState; 281 } 282 283 /** 284 * Set the value of <code>RelayState</code> attribute. 285 * 286 * @param relayState the value of <code>RelayState</code> attribute. 287 * @see #getRelayState() 288 */ 289 public void setRelayState(String relayState){ 290 this.relayState = relayState; 291 } 292 293 /** 294 * Returns the value of <code>InResponseTo</code> attribute. 295 * 296 * @return the value of <code>InResponseTo</code> attribute. 297 * @see #setResponseTo(String) 298 */ 299 public String getResponseTo(){ 300 return inResponseTo; 301 } 302 303 /** 304 * Sets the value of <code>InResponseTo</code> attribute. 305 * 306 * @param inResponseTo the value of <code>InResponseTo</code> attribute. 307 * @see #getResponseTo 308 */ 309 public void setResponseTo(String inResponseTo){ 310 this.inResponseTo = inResponseTo; 311 } 312 313 /** 314 * Returns the value of <code>id</code> attribute. 315 * 316 * @return the value of <code>id</code> attribute. 317 * @see #setID(String) 318 */ 319 public String getID(){ 320 return id; 321 } 322 323 /** 324 * Sets the value of <code>id</code> attribute. 325 * 326 * @param id the value of <code>id</code> attribute. 327 * @see #getID() 328 */ 329 public void setID(String id){ 330 this.id = id; 331 } 332 333 /** 334 * Returns the value of <code>ProviderID</code> attribute. 335 * 336 * @return the value of <code>ProviderID</code> attribute. 337 * @see #setProviderId(String). 338 */ 339 340 public String getProviderId(){ 341 return providerId; 342 } 343 344 /** 345 * Sets the value of <code>ProviderID</code> attribute. 346 * 347 * @param providerId the value of <code>ProviderID</code> attribute. 348 * @see #getProviderId() 349 */ 350 public void setProviderId(String providerId){ 351 this.providerId = providerId; 352 } 353 354 /** 355 * Returns the Signed <code>LogoutResponse</code> string. 356 * 357 * @return signatureString the Signed <code>LogoutResponse</code> string. 358 */ 359 public String getSignatureString(){ 360 return signatureString; 361 } 362 363 /** 364 * Returns the value of <code>MinorVersion</code> attribute. 365 * 366 * @return the value of <code>MinorVersion</code> attribute. 367 * @see #setMinorVersion(int) 368 */ 369 public int getMinorVersion() { 370 return minorVersion; 371 } 372 373 /** 374 * Sets the value of <code>MinorVersion</code> attribute. 375 * 376 * @param version thevalue of <code>MinorVersion</code> attribute. 377 * @see #getMinorVersion() 378 */ 379 public void setMinorVersion(int version) { 380 minorVersion = version; 381 } 382 383 /** 384 * Returns the Logout <code>Status</code>. 385 * 386 * @return the Logout <code>Status</code>. 387 * @see #setStatus(String) 388 * @see #setStatus(Status) 389 */ 390 public Status getStatus() { 391 return status; 392 } 393 394 /** 395 * Sets the Logout <code>Status</code>. 396 * 397 * @param status the Logout <code>Status</code code. 398 * @see #getStatus 399 */ 400 public void setStatus(String status) { 401 try { 402 StatusCode statusCode = new StatusCode(status); 403 this.status = new Status(statusCode); 404 } catch (Exception e) { 405 if (FSUtils.debug.messageEnabled()) { 406 FSUtils.debug.message("FSLogoutResponse(Element): could not " 407 + "set attribute:", e); 408 } 409 } 410 } 411 412 /** 413 * Sets the Logout <code>Status</code>. 414 * 415 * @param status the Logout <code>Status</code object. 416 * @see #getStatus 417 */ 418 public void setStatus(Status status) { 419 this.status=status; 420 } 421 422 /** 423 * Sets the <code>MajorVersion</code> by parsing the version string. 424 * 425 * @param majorVer a String representing the <code>MajorVersion</code> to 426 * be set. 427 * @throws FSMsgException on error. 428 * @throws SAMLException when the version mismatchs. 429 */ 430 private void parseMajorVersion(String majorVer) 431 throws FSMsgException, SAMLException { 432 try { 433 majorVersion = Integer.parseInt(majorVer); 434 } catch (NumberFormatException e) { 435 if (FSUtils.debug.messageEnabled()) { 436 FSUtils.debug.message("Response(Element): invalid " 437 + "MajorVersion", e); 438 } 439 throw new FSMsgException("wrongInput",null); 440 } 441 442 if (majorVersion != SAMLConstants.PROTOCOL_MAJOR_VERSION) { 443 if (majorVersion > SAMLConstants.PROTOCOL_MAJOR_VERSION) { 444 if (FSUtils.debug.messageEnabled()) { 445 FSUtils.debug.message("Response(Element):MajorVersion of" 446 + " the Response is too high."); 447 } 448 throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME, 449 "responseVersionTooHigh",null); 450 } else { 451 if (FSUtils.debug.messageEnabled()) { 452 FSUtils.debug.message("Response(Element):MajorVersion of" 453 + " the Response is too low."); 454 } 455 throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME, 456 "responseVersionTooLow",null); 457 } 458 } 459 } 460 461 /** 462 * Sets the <code>MinorVersion</code> by parsing the version string. 463 * 464 * @param minorVer a String representing the <code>MinorVersion</code> to 465 * be set. 466 * @throws SAMLException when the version mismatchs. 467 */ 468 private void parseMinorVersion(String minorVer) 469 throws FSMsgException, SAMLException { 470 try { 471 minorVersion = Integer.parseInt(minorVer); 472 } catch (NumberFormatException e) { 473 if (FSUtils.debug.messageEnabled()) { 474 FSUtils.debug.message("Response(Element): invalid " 475 + "MinorVersion", e); 476 } 477 throw new FSMsgException("wrongInput",null); 478 } 479 if (minorVersion > IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 480 FSUtils.debug.error("Response(Element):MinorVersion of" 481 + " the Response is too high."); 482 throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME, 483 "responseVersionTooHigh",null); 484 } else if (minorVersion < IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { 485 FSUtils.debug.error("Response(Element):MinorVersion of" 486 + " the Response is too low."); 487 throw new SAMLVersionMismatchException(FSUtils.BUNDLE_NAME, 488 "responseVersionTooLow",null); 489 } 490 } 491 492 /** 493 * Returns the <code>FSLogoutResponse</code> object. 494 * 495 * @param xml the XML string to be parsed. 496 * @return <code>FSLogoutResponse</code> object created from the XML string. 497 * @throws FSMsgException if there is 498 * error creating the object. 499 */ 500 501 public static FSLogoutResponse parseXML(String xml) throws FSMsgException { 502 FSLogoutResponse logoutResponse = null; 503 try{ 504 Document doc = XMLUtils.toDOMDocument(xml, FSUtils.debug); 505 Element root = doc.getDocumentElement(); 506 logoutResponse = new FSLogoutResponse(root); 507 }catch(SAMLException ex){ 508 if (FSUtils.debug.messageEnabled()) { 509 FSUtils.debug.message("FSLogoutResponse.parseXML: " 510 + "Error while parsing input xml string"); 511 } 512 throw new FSMsgException("parseError",null, ex); 513 } 514 return logoutResponse; 515 } 516 517 /** 518 * Returns a String representation of the <code>LogoutResponse</code> 519 * object. This method translates the response to an XML string. 520 * 521 * @return An XML String representing the logout response. 522 */ 523 public String toXMLString() throws FSMsgException { 524 return this.toXMLString(true, true); 525 } 526 527 /** 528 * Returns a String representation of the <code>LogoutResponse</code> 529 * object. 530 * 531 * @return An XML String representing the logout response. 532 * @throws FSMsgException if there is an error converting 533 * this object ot a string. 534 */ 535 public String toXMLString(boolean includeNS, boolean declareNS) 536 throws FSMsgException { 537 return toXMLString(includeNS, declareNS, false); 538 } 539 540 /** 541 * Returns a String representation of the <code>LogoutResponse</code> 542 * object. 543 * 544 * @param includeNS Determines whether or not the namespace qualifier 545 * is prepended to the Element when converted 546 * @param declareNS Determines whether or not the namespace is declared 547 * within the Element. 548 * @param includeHeader Determines whether the output include the xml 549 * declaration header. 550 * @return a string containing the valid XML for this element 551 * @throws FSMsgException if there is an error converting 552 * this object ot a string. 553 */ 554 555 public String toXMLString(boolean includeNS, boolean declareNS, 556 boolean includeHeader) throws FSMsgException { 557 StringBuffer xml = new StringBuffer(300); 558 if (includeHeader) { 559 xml.append(IFSConstants.XML_PREFIX) 560 .append(SAMLConstants.DEFAULT_ENCODING) 561 .append(IFSConstants.QUOTE) 562 .append(IFSConstants.SPACE) 563 .append(IFSConstants.QUESTION_MARK) 564 .append(IFSConstants.RIGHT_ANGLE) 565 .append(IFSConstants.NL); 566 } 567 String prefixLIB = ""; 568 String uriLIB = ""; 569 if (includeNS) { 570 prefixLIB = IFSConstants.LIB_PREFIX; 571 } 572 573 if (declareNS) { 574 if(minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 575 uriLIB = IFSConstants.LIB_12_NAMESPACE_STRING; 576 } else { 577 uriLIB = IFSConstants.LIB_NAMESPACE_STRING; 578 } 579 } 580 581 String instantString = DateUtils.toUTCDateFormat(issueInstant); 582 583 if((providerId == null) || (providerId.length() == 0)){ 584 FSUtils.debug.error("FSLogoutResponse.toXMLString: " 585 + "providerId is null in the response with responseId:" 586 + responseID); 587 String[] args = { responseID }; 588 throw new FSMsgException("nullProviderIdWResponseId",args); 589 } 590 591 xml.append(IFSConstants.LEFT_ANGLE) 592 .append(prefixLIB) 593 .append(IFSConstants.LOGOUT_RESPONSE) 594 .append(uriLIB) 595 .append(IFSConstants.SPACE); 596 597 if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION && 598 id != null && !(id.length() == 0)) { 599 xml.append(IFSConstants.ID) 600 .append(IFSConstants.EQUAL_TO) 601 .append(IFSConstants.QUOTE) 602 .append(id) 603 .append(IFSConstants.QUOTE) 604 .append(IFSConstants.SPACE) 605 .append(IFSConstants.SPACE); 606 } 607 608 if (responseID != null) { 609 xml.append(IFSConstants.RESPONSE_ID) 610 .append(IFSConstants.EQUAL_TO) 611 .append(IFSConstants.QUOTE) 612 .append(responseID) 613 .append(IFSConstants.QUOTE) 614 .append(IFSConstants.SPACE) 615 .append(IFSConstants.SPACE); 616 } 617 618 if (inResponseTo != null) { 619 xml.append(IFSConstants.IN_RESPONSE_TO) 620 .append(IFSConstants.EQUAL_TO) 621 .append(IFSConstants.QUOTE) 622 .append(inResponseTo) 623 .append(IFSConstants.QUOTE) 624 .append(IFSConstants.SPACE) 625 .append(IFSConstants.SPACE); 626 } 627 628 xml.append(IFSConstants.MAJOR_VERSION) 629 .append(IFSConstants.EQUAL_TO) 630 .append(IFSConstants.QUOTE) 631 .append(majorVersion) 632 .append(IFSConstants.QUOTE) 633 .append(IFSConstants.SPACE) 634 .append(IFSConstants.SPACE) 635 .append(IFSConstants.MINOR_VERSION) 636 .append(IFSConstants.EQUAL_TO) 637 .append(IFSConstants.QUOTE) 638 .append(minorVersion) 639 .append(IFSConstants.QUOTE) 640 .append(IFSConstants.SPACE) 641 .append(IFSConstants.SPACE) 642 .append(IFSConstants.ISSUE_INSTANT) 643 .append(IFSConstants.EQUAL_TO) 644 .append(IFSConstants.QUOTE) 645 .append(instantString) 646 .append(IFSConstants.QUOTE) 647 .append(IFSConstants.RIGHT_ANGLE); 648 649 if (signed) { 650 if (signatureString != null) { 651 xml.append(signatureString); 652 } else if (signature != null) { 653 signatureString = XMLUtils.print(signature); 654 xml.append(signatureString); 655 } 656 } 657 658 if (providerId != null) { 659 xml.append(IFSConstants.LEFT_ANGLE) 660 .append(prefixLIB) 661 .append(IFSConstants.PROVIDER_ID) 662 .append(IFSConstants.RIGHT_ANGLE) 663 .append(providerId) 664 .append(IFSConstants.START_END_ELEMENT) 665 .append(prefixLIB) 666 .append(IFSConstants.PROVIDER_ID) 667 .append(IFSConstants.RIGHT_ANGLE); 668 } 669 670 if (status != null) { 671 xml.append(status.toString(includeNS, true)); 672 } 673 674 if (relayState != null) { 675 xml.append(IFSConstants.LEFT_ANGLE) 676 .append(prefixLIB) 677 .append(IFSConstants.RELAY_STATE) 678 .append(IFSConstants.RIGHT_ANGLE) 679 .append(relayState) 680 .append(IFSConstants.START_END_ELEMENT) 681 .append(prefixLIB) 682 .append(IFSConstants.RELAY_STATE) 683 .append(IFSConstants.RIGHT_ANGLE); 684 } 685 686 xml.append(IFSConstants.START_END_ELEMENT) 687 .append(prefixLIB) 688 .append(IFSConstants.LOGOUT_RESPONSE) 689 .append(IFSConstants.RIGHT_ANGLE); 690 691 return xml.toString(); 692 } 693 694 /** 695 * Returns <code>FSLogoutResponse</code> object. The object 696 * is created by parsing an Base64 encode authentication 697 * request String. 698 * 699 * @param encodedRes the encode string 700 * @throws FSMsgException if there is an error creating this object. 701 * @throws SAMLException if there is an error creating this object. 702 */ 703 public static FSLogoutResponse parseBASE64EncodedString(String encodedRes) 704 throws FSMsgException, SAMLException { 705 if (encodedRes != null){ 706 String decodedNameRegRes = new String(Base64.decode(encodedRes)); 707 if (FSUtils.debug.messageEnabled()) { 708 FSUtils.debug.message("FSLogoutResponse." 709 + "parseBASE64EncodedString: decoded input string: " 710 + decodedNameRegRes); 711 } 712 return parseXML(decodedNameRegRes); 713 } else { 714 if (FSUtils.debug.messageEnabled()) { 715 FSUtils.debug.message( 716 "FSLogoutResponse.parseBASE64EncodedString" 717 + ": null String passed in as argument."); 718 } 719 throw new FSMsgException("nullInput",null); 720 } 721 } 722 723 /** 724 * Returns a Base64 Encoded String. 725 * 726 * @return a Base64 Encoded String. 727 * @throws FSMsgException if there is an error encoding the string. 728 */ 729 public String toBASE64EncodedString() throws FSMsgException { 730 if ((responseID == null) || (responseID.length() == 0)){ 731 responseID = FSUtils.generateID(); 732 if (responseID == null) { 733 FSUtils.debug.error("FSLogoutResponse.toBASE64EncodedString: " 734 + "couldn't generate ResponseID."); 735 throw new FSMsgException("errorGenerateID",null); 736 } 737 } 738 return Base64.encode(this.toXMLString().getBytes()); 739 } 740 741 /** 742 * Unsupported operation. 743 */ 744 public void signXML() { 745 } 746 747 /** 748 * Signs the <code>LogoutResponse</code>. 749 * 750 * @param certAlias the Certificate Alias. 751 * @throws XMLSignatureException if this object cannot be signed. 752 */ 753 public void signXML(String certAlias) throws SAMLException { 754 FSUtils.debug.message("FSLogoutResponse.signXML: Called"); 755 if (signed) { 756 if (FSUtils.debug.messageEnabled()) { 757 FSUtils.debug.message("FSLogoutResponse.signXML: " 758 + "the assertion is already signed."); 759 } 760 throw new SAMLResponderException(FSUtils.BUNDLE_NAME, 761 "alreadySigned",null); 762 } 763 if (certAlias == null || certAlias.length() == 0) { 764 throw new SAMLResponderException(FSUtils.BUNDLE_NAME, 765 "cannotFindCertAlias",null); 766 } 767 try{ 768 XMLSignatureManager manager = XMLSignatureManager.getInstance(); 769 if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { 770 signatureString = manager.signXML(this.toXMLString(true, true), 771 certAlias, 772 IFSConstants.DEF_SIG_ALGO, 773 IFSConstants.ID, 774 this.id, false); 775 } else if (minorVersion == 776 IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 777 signatureString = 778 manager.signXML(this.toXMLString(true, true), 779 certAlias, IFSConstants.DEF_SIG_ALGO, 780 IFSConstants.RESPONSE_ID, 781 this.getResponseID(), false); 782 } else { 783 if (FSUtils.debug.messageEnabled()) { 784 FSUtils.debug.message("invalid minor version."); 785 } 786 } 787 788 signature = XMLUtils.toDOMDocument(signatureString, FSUtils.debug) 789 .getDocumentElement(); 790 791 signed = true; 792 xmlString = this.toXMLString(true, true); 793 } catch (Exception e) { 794 throw new SAMLResponderException(FSUtils.BUNDLE_NAME, 795 "signFailed",null); 796 } 797 } 798 799 /** 800 * Sets the Signature. 801 * 802 * @param elem the Document Element. 803 * @return true if success otherwise false. 804 */ 805 public boolean setSignature(Element elem) { 806 signatureString = XMLUtils.print(elem); 807 return super.setSignature(elem); 808 } 809 810 /** 811 * Returns an URL Encoded String. 812 * 813 * @return a url encoded query string. 814 * @throws FSMsgException if there is an error. 815 */ 816 public String toURLEncodedQueryString() throws FSMsgException { 817 if ((providerId == null) || (providerId.length() == 0)) { 818 FSUtils.debug.error("FSLogoutResponse." 819 + "toURLEncodedQueryString: providerId is null in " 820 + "the response "); 821 throw new FSMsgException("nullProviderIdInRequest",null); 822 } 823 if ((responseID == null) || (responseID.length() == 0)){ 824 responseID = FSUtils.generateID(); 825 if (responseID == null) { 826 FSUtils.debug.error("FSNameRegistrationRequest." 827 + "toURLEncodedQueryString: couldn't generate " 828 + "responseID."); 829 throw new FSMsgException("errorGenerateID",null); 830 } 831 } 832 833 StringBuffer urlEncodedAuthnReq = new StringBuffer(300); 834 urlEncodedAuthnReq.append(IFSConstants.RESPONSE_ID) 835 .append(IFSConstants.EQUAL_TO) 836 .append(URLEncDec.encode(responseID)) 837 .append(IFSConstants.AMPERSAND); 838 839 if((inResponseTo != null) && (inResponseTo.length() > 0)) { 840 urlEncodedAuthnReq.append(IFSConstants.IN_RESPONSE_TO) 841 .append(IFSConstants.EQUAL_TO) 842 .append(URLEncDec.encode(inResponseTo)) 843 .append(IFSConstants.AMPERSAND); 844 } 845 urlEncodedAuthnReq.append(IFSConstants.MAJOR_VERSION) 846 .append(IFSConstants.EQUAL_TO) 847 .append(majorVersion) 848 .append(IFSConstants.AMPERSAND) 849 .append(IFSConstants.MINOR_VERSION) 850 .append(IFSConstants.EQUAL_TO) 851 .append(minorVersion) 852 .append(IFSConstants.AMPERSAND); 853 854 if (issueInstant != null) { 855 urlEncodedAuthnReq.append(IFSConstants.ISSUE_INSTANT) 856 .append(IFSConstants.EQUAL_TO) 857 .append(URLEncDec.encode( 858 DateUtils.toUTCDateFormat(issueInstant))) 859 .append(IFSConstants.AMPERSAND); 860 } else { 861 FSUtils.debug.error("FSLogoutResponse." 862 + "toURLEncodedQueryString: issueInstant missing"); 863 String[] args = { IFSConstants.ISSUE_INSTANT }; 864 throw new FSMsgException("missingAttribute",args); 865 } 866 if(providerId != null && providerId.length() != 0) { 867 urlEncodedAuthnReq.append(IFSConstants.PROVIDER_ID) 868 .append(IFSConstants.EQUAL_TO) 869 .append(URLEncDec.encode(providerId)) 870 .append(IFSConstants.AMPERSAND); 871 } 872 873 if(relayState != null && relayState.length() != 0) { 874 urlEncodedAuthnReq.append(IFSConstants.RELAY_STATE) 875 .append(IFSConstants.EQUAL_TO) 876 .append(URLEncDec.encode(relayState)) 877 .append(IFSConstants.AMPERSAND); 878 } 879 880 if (status != null) { 881 urlEncodedAuthnReq.append(IFSConstants.VALUE) 882 .append(IFSConstants.EQUAL_TO) 883 .append(URLEncDec.encode( 884 status.getStatusCode().getValue())) 885 .append(IFSConstants.AMPERSAND); 886 } 887 return urlEncodedAuthnReq.toString(); 888 } 889 890 891 /** 892 * Returns <code>FSLogoutResponse</code> object. The 893 * object is creating by parsing the <code>HttpServletRequest</code> 894 * object. 895 * 896 * @param request the <code>HttpServletRequest</code> object. 897 * @throws FSMsgException if there is an error creating this object. 898 * @throws SAMLException if there is an error. 899 */ 900 public static FSLogoutResponse parseURLEncodedRequest( 901 HttpServletRequest request) 902 throws FSMsgException, SAMLException { 903 FSLogoutResponse retLogoutResponse = new FSLogoutResponse(); 904 try { 905 FSUtils.debug.message("checking minor version"); 906 retLogoutResponse.majorVersion = 907 Integer.parseInt( 908 request.getParameter(IFSConstants.MAJOR_VERSION)); 909 retLogoutResponse.minorVersion = 910 Integer.parseInt( 911 request.getParameter(IFSConstants.MINOR_VERSION)); 912 } catch(NumberFormatException ex){ 913 throw new FSMsgException("invalidNumber",null); 914 } 915 916 String requestID = request.getParameter(IFSConstants.RESPONSE_ID); 917 if (requestID != null) { 918 retLogoutResponse.responseID = requestID ; 919 } else { 920 String[] args = { IFSConstants.RESPONSE_ID }; 921 throw new FSMsgException("missingAttribute",args); 922 } 923 retLogoutResponse.inResponseTo = 924 request.getParameter(IFSConstants.IN_RESPONSE_TO); 925 926 String instantString = 927 request.getParameter(IFSConstants.ISSUE_INSTANT); 928 if (instantString == null || instantString.length() == 0) { 929 String[] args = { IFSConstants.ISSUE_INSTANT }; 930 throw new FSMsgException("missingAttribute",args); 931 } 932 try{ 933 retLogoutResponse.issueInstant = 934 DateUtils.stringToDate(instantString); 935 } catch (ParseException e){ 936 throw new FSMsgException("parseError",null); 937 } 938 FSUtils.debug.message(" get provider Id"); 939 String providerID = request.getParameter(IFSConstants.PROVIDER_ID); 940 if (providerID != null) { 941 retLogoutResponse.providerId = providerID; 942 if (FSUtils.debug.messageEnabled()) { 943 FSUtils.debug.message("ProviderID : " 944 + retLogoutResponse.providerId); 945 } 946 } else { 947 if (FSUtils.debug.messageEnabled()) { 948 FSUtils.debug.message("ProviderID : " 949 + retLogoutResponse.providerId); 950 } 951 throw new FSMsgException("missingElement",null); 952 } 953 954 String relayState = request.getParameter(IFSConstants.RELAY_STATE); 955 if (relayState != null) { 956 retLogoutResponse.relayState = relayState; 957 if (FSUtils.debug.messageEnabled()) { 958 FSUtils.debug.message("RelayState:" 959 + retLogoutResponse.relayState); 960 } 961 } 962 963 String value = request.getParameter(IFSConstants.VALUE); 964 if (value != null){ 965 if (FSUtils.debug.messageEnabled()) { 966 FSUtils.debug.message("Status : " + value); 967 } 968 StatusCode statusCode = new StatusCode(value); 969 retLogoutResponse.status = new Status(statusCode); 970 } else { 971 if (FSUtils.debug.messageEnabled()) { 972 FSUtils.debug.message("Status : " + value); 973 } 974 throw new FSMsgException("missingElement",null); 975 } 976 977 FSUtils.debug.message("Returning Logout response Object"); 978 return retLogoutResponse; 979 } 980 }
Copyright © 2010-2017, ForgeRock All Rights Reserved.