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