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