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: FSAuthnRequestEnvelope.java,v 1.2 2008/06/25 05:46:43 qcheng Exp $ 026 * 027 */ 028 029package com.sun.identity.federation.message; 030 031import com.sun.identity.federation.common.IFSConstants; 032import com.sun.identity.federation.message.common.FSMsgException; 033import com.sun.identity.federation.common.FSUtils; 034import com.sun.identity.saml.common.SAMLUtils; 035import com.sun.identity.shared.encode.Base64; 036import com.sun.identity.shared.xml.XMLUtils; 037import java.io.IOException; 038import java.util.List; 039import org.w3c.dom.Element; 040import org.w3c.dom.Node; 041import org.w3c.dom.NodeList; 042import org.w3c.dom.Document; 043 044/** 045 * This class defines methods for setting and retrieving attributes and 046 * elements associated with a Liberty Authentication Request. 047 * 048 * @supported.all.api 049 */ 050public class FSAuthnRequestEnvelope { 051 private String assertionConsumerServiceURL = null; 052 private List otherElements = null; 053 private FSAuthnRequest authnRequest = null; 054 private FSIDPList idpList = null; 055 private String providerID = null; 056 private String providerName = null; 057 private boolean isPassive = false; 058 private int minorVersion = IFSConstants.FF_11_PROTOCOL_MINOR_VERSION; 059 060 /** 061 * Default Constructor. 062 */ 063 public FSAuthnRequestEnvelope() { 064 } 065 066 /** 067 * Constructs a new <code>FSAuthnRequestEnvelope</code> object. 068 * 069 * @param authnRequest the authentication request 070 * @param providerID the provider's identifier 071 * @param providerName name of the provider 072 * @param assertionConsumerServiceURL absolute url of the assertion 073 * consumer service 074 * @param idpList list of identity providers 075 * @param isPassive true if identity provider must not interact 076 * with the <code>Principal</code>. 077 */ 078 079 public FSAuthnRequestEnvelope(FSAuthnRequest authnRequest, 080 String providerID, 081 String providerName, 082 String assertionConsumerServiceURL, 083 FSIDPList idpList, boolean isPassive ) { 084 this.authnRequest = authnRequest; 085 this.providerID = providerID; 086 this.providerName = providerName; 087 this.assertionConsumerServiceURL = assertionConsumerServiceURL; 088 this.idpList = idpList; 089 this.isPassive = isPassive; 090 } 091 092 /** 093 * Constructs a new <code>FSAuthnRequestEnvelope</code> object 094 * from a Document Element. 095 * 096 * @param root the Document Element . 097 * @throws FSMsgException if there is an error 098 * creating this object. 099 */ 100 101 public FSAuthnRequestEnvelope(Element root) throws FSMsgException { 102 if (root == null) { 103 SAMLUtils.debug.message( 104 "FSAuthnRequestEnvelope.parseXML: null input."); 105 throw new FSMsgException("nullInput",null); 106 } 107 String tag = null; 108 if (((tag = root.getLocalName()) == null) || 109 (!tag.equals(IFSConstants.AUTHN_REQUEST_ENVELOPE))) { 110 FSUtils.debug.message( 111 "FSAuthnRequestEnvelope.parseXML: wrong input."); 112 throw new FSMsgException("wrongInput",null); 113 } 114 String ns = root.getNamespaceURI(); 115 if (ns == null) { 116 FSUtils.debug.error("FSAuthnRequestEnvelope(Element):" 117 + " No namespace"); 118 throw new FSMsgException("wrongInput", null); 119 } 120 121 if (ns.equals(IFSConstants.FF_12_XML_NS)) { 122 minorVersion = IFSConstants.FF_12_PROTOCOL_MINOR_VERSION; 123 } 124 125 NodeList nl = root.getChildNodes(); 126 Node child; 127 String childName; 128 int length = nl.getLength(); 129 for (int i = 0; i < length; i++) { 130 child = nl.item(i); 131 if ((childName = child.getLocalName()) != null) { 132 if (childName.equals( 133 IFSConstants.ASSERTION_CONSUMER_SERVICE_URL)) { 134 assertionConsumerServiceURL = 135 XMLUtils.getElementValue((Element) child); 136 } else if (childName.equals(IFSConstants.IDP_LIST)) { 137 idpList = new FSIDPList((Element) child); 138 } else if (childName.equals(IFSConstants.AUTHN_REQUEST)) { 139 authnRequest = new FSAuthnRequest((Element) child); 140 } else if (childName.equals(IFSConstants.PROVIDER_ID)) { 141 providerID = XMLUtils.getElementValue((Element) child); 142 } else if (childName.equals(IFSConstants.PROVIDER_NAME)) { 143 providerName = XMLUtils.getElementValue((Element) child); 144 } else if (childName.equals(IFSConstants.IS_PASSIVE)) { 145 String strIsPassive = 146 XMLUtils.getElementValue((Element) child); 147 boolean isPassive = false; 148 if (strIsPassive != null && 149 strIsPassive.equals(IFSConstants.TRUE)) { 150 isPassive = true; 151 } 152 } 153 } 154 } 155 } 156 157 /** 158 * Returns the value of <code>MinorVersion</code> property. 159 * 160 * @return the value of <code>MinorVersion</code> property. 161 */ 162 public int getMinorVersion() { 163 return minorVersion; 164 } 165 166 /** 167 * Sets the value of <code>MinorVersion</code> property. 168 * 169 * @param minorVersion the value of <code>MinorVersion</code> property. 170 * @see #setMinorVersion(int) 171 */ 172 173 public void setMinorVersion(int minorVersion) { 174 this.minorVersion = minorVersion; 175 } 176 177 /** 178 * Returns the request as an XML Document String 179 * based on the Liberty Request schema. 180 * 181 * @return XML String representing the request. 182 * @throws <code>FSMsgException</code> if there is an error. 183 */ 184 185 public String toXMLString() throws FSMsgException { 186 return toXMLString(true, true); 187 } 188 189 /** 190 * Creates a String representation of the <lib:AuthnRequest> element. 191 * @param includeNS : Determines whether or not the namespace qualifier 192 * is prepended to the Element when converted 193 * @param declareNS : Determines whether or not the namespace is declared 194 * within the Element. 195 * @return String containing the valid XML for this element. 196 * @throws FSMsgException if there is an error. 197 */ 198 199 public String toXMLString(boolean includeNS,boolean declareNS) 200 throws FSMsgException { 201 return toXMLString(includeNS, declareNS, false); 202 } 203 204 /** 205 * Creates a String representation of the <lib:AuthnRequest> element. 206 * 207 * @param includeNS Determines whether or not the namespace qualifier 208 * is prepended to the Element when converted 209 * @param declareNS Determines whether or not the namespace is declared 210 * within the Element. 211 * @param includeHeader Determines whether the output include the xml 212 * declaration header. 213 * @return A string containing the valid XML for this element. 214 * @throws <code>FSMsgException</code> if there is an error. 215 */ 216 public String toXMLString(boolean includeNS, 217 boolean declareNS, 218 boolean includeHeader) throws FSMsgException { 219 220 StringBuffer xml = new StringBuffer(300); 221 if (includeHeader) { 222 xml.append(IFSConstants.XML_PREFIX) 223 .append(IFSConstants.DEFAULT_ENCODING) 224 .append(IFSConstants.QUOTE) 225 .append(IFSConstants.SPACE) 226 .append(IFSConstants.QUESTION_MARK) 227 .append(IFSConstants.RIGHT_ANGLE) 228 .append(IFSConstants.NL); 229 } 230 String prefix = ""; 231 String uri = ""; 232 if (includeNS) { 233 prefix = IFSConstants.LIB_PREFIX; 234 } 235 if (declareNS) { 236 if(minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 237 uri = IFSConstants.LIB_12_NAMESPACE_STRING; 238 } else { 239 uri = IFSConstants.LIB_NAMESPACE_STRING; 240 } 241 } 242 243 xml.append(IFSConstants.LEFT_ANGLE) 244 .append(prefix) 245 .append(IFSConstants.AUTHN_REQUEST_ENVELOPE) 246 .append(uri) 247 .append(IFSConstants.RIGHT_ANGLE); 248 249 if (authnRequest != null){ 250 xml.append(authnRequest.toXMLString()); 251 } 252 253 if (providerID != null && providerID.length() != 0){ 254 xml.append(IFSConstants.LEFT_ANGLE) 255 .append(prefix) 256 .append(IFSConstants.PROVIDER_ID) 257 .append(uri) 258 .append(IFSConstants.RIGHT_ANGLE) 259 .append(providerID) 260 .append(IFSConstants.START_END_ELEMENT) 261 .append(prefix) 262 .append(IFSConstants.PROVIDER_ID) 263 .append(IFSConstants.RIGHT_ANGLE); 264 } 265 266 if (providerName != null && providerName.length() != 0){ 267 xml.append(IFSConstants.LEFT_ANGLE) 268 .append(prefix) 269 .append(IFSConstants.PROVIDER_NAME) 270 .append(uri) 271 .append(IFSConstants.RIGHT_ANGLE) 272 .append(providerName) 273 .append(IFSConstants.START_END_ELEMENT) 274 .append(prefix) 275 .append("ProviderName") 276 .append(IFSConstants.PROVIDER_NAME) 277 .append(IFSConstants.RIGHT_ANGLE); 278 } 279 280 if (assertionConsumerServiceURL != null && 281 assertionConsumerServiceURL.length() != 0) { 282 xml.append(IFSConstants.LEFT_ANGLE) 283 .append(prefix) 284 .append(IFSConstants.ASSERTION_CONSUMER_SERVICE_URL) 285 .append(uri) 286 .append(IFSConstants.RIGHT_ANGLE) 287 .append(assertionConsumerServiceURL) 288 .append(IFSConstants.START_END_ELEMENT) 289 .append(prefix) 290 .append(IFSConstants.ASSERTION_CONSUMER_SERVICE_URL) 291 .append(IFSConstants.RIGHT_ANGLE); 292 } 293 294 if (idpList != null){ 295 xml.append(idpList.toXMLString()); 296 } 297 298 String strIsPassive = IFSConstants.FALSE; 299 if (isPassive) { 300 strIsPassive = IFSConstants.TRUE; 301 } 302 303 xml.append(IFSConstants.LEFT_ANGLE) 304 .append(prefix) 305 .append(IFSConstants.IS_PASSIVE) 306 .append(IFSConstants.RIGHT_ANGLE) 307 .append(strIsPassive) 308 .append(IFSConstants.START_END_ELEMENT) 309 .append(prefix) 310 .append(IFSConstants.IS_PASSIVE) 311 .append(IFSConstants.RIGHT_ANGLE); 312 313 //Other elements needs to be handled here 314 315 xml.append(IFSConstants.START_END_ELEMENT) 316 .append(prefix) 317 .append(IFSConstants.AUTHN_REQUEST_ENVELOPE) 318 .append(IFSConstants.RIGHT_ANGLE); 319 320 return xml.toString(); 321 } 322 323 /** 324 * Returns the <code>FSAuthnRequestEnvelope</code> object. 325 * 326 * @param xml the XML string to create this object from 327 * @return <code>FSAuthnRequestEnvelope</code> object. 328 * @throws FSMsgException if there is 329 * error creating the object. 330 */ 331 332 public static FSAuthnRequestEnvelope parseXML(String xml) 333 throws FSMsgException { 334 Document doc = XMLUtils.toDOMDocument(xml, FSUtils.debug); 335 if (doc == null) { 336 if (FSUtils.debug.messageEnabled()) { 337 FSUtils.debug.message( 338 "FSAuthnRequestEnvelope.parseXML:Error " 339 + "while parsing input xml string"); 340 } 341 throw new FSMsgException("parseError",null); 342 } 343 Element root = doc.getDocumentElement(); 344 return new FSAuthnRequestEnvelope(root); 345 } 346 347 /** 348 * Returns the value of <code>AssertionConsumerServiceURL</code> attribute. 349 * 350 * @return the value of <code>AssertionConsumerServiceURL</code> attribute. 351 * @see #setAssertionConsumerServiceURL(String) 352 */ 353 public String getAssertionConsumerServiceURL() { 354 return assertionConsumerServiceURL; 355 } 356 357 /** 358 * Sets the value of <code>AssertionConsumerServiceURL</code> attribute. 359 * 360 * @param assertionConsumerURL the value of 361 * <code>AssertionConsumerServiceURL</code> attribute. 362 * @see #getAssertionConsumerServiceURL 363 */ 364 365 public void setAssertionConsumerServiceURL(String assertionConsumerURL) { 366 this.assertionConsumerServiceURL = assertionConsumerURL; 367 } 368 369 /** 370 * Returns the <code>FSAuthnRequest</code> object. 371 * 372 * @return the <code>FSAuthnRequest</code> object. 373 * @see #setAuthnRequest(FSAuthnRequest) 374 */ 375 public FSAuthnRequest getAuthnRequest() { 376 return authnRequest; 377 } 378 379 /** 380 * Sets the <code>FSAuthnRequest</code> object. 381 * 382 * @param authnRequest the <code>FSAuthnRequest</code> object. 383 * @see #getAuthnRequest 384 */ 385 public void setAuthnRequest(FSAuthnRequest authnRequest) { 386 this.authnRequest = authnRequest; 387 } 388 389 /** 390 * Returns the <code>FSIDPList</code> object. 391 * 392 * return the <code>FSIDPList</code> object. 393 * @see #setIDPList(FSIDPList) 394 */ 395 public FSIDPList getIDPList() { 396 return idpList; 397 } 398 399 /** 400 * Sets the <code>FSIDPList</code> object. 401 * 402 * @param idpList the <code>FSIDPList</code> object. 403 * @see #getIDPList 404 */ 405 public void setIDPList(FSIDPList idpList) { 406 this.idpList = idpList; 407 } 408 409 /** 410 * Returns a list of elements. 411 * 412 * @return list of elements. 413 * @see #setOtherElements(List) 414 */ 415 public List getOtherElements() { 416 return otherElements; 417 } 418 419 /** 420 * Sets a list of elements. 421 * 422 * @param otherElements a list of elements. 423 * @see #getOtherElements 424 */ 425 public void setOtherElements(List otherElements) { 426 this.otherElements = otherElements; 427 } 428 429 /** 430 * Returns <code>FSAuthnRequestEnvelope</code> object. The object 431 * is created by parsing an Base64 encode authentication 432 * request String. 433 * 434 * @param encodedReq the encoded string. 435 * @throws <code>FSMsgException</code> if there is an error 436 * creating <code>FSAuthnRequestEnvelope</code> object. 437 */ 438 439 public static FSAuthnRequestEnvelope parseBASE64EncodedString( 440 String encodedReq) throws FSMsgException { 441 if (encodedReq != null) { 442 String decodedAuthnReq = new String(Base64.decode(encodedReq)); 443 if (FSUtils.debug.messageEnabled()) { 444 FSUtils.debug.message("FSAuthnRequestEnvelope." 445 + "parseBASE64EncodedString: decoded input string: \n" 446 + decodedAuthnReq); 447 } 448 return parseXML(decodedAuthnReq); 449 } else { 450 if (FSUtils.debug.messageEnabled()) { 451 FSUtils.debug.message( 452 "FSAuthnRequestEnvelope.parseBASE64EncodedString: null " 453 + " String passed in as argument."); 454 } 455 throw new FSMsgException("nullInput",null); 456 } 457 } 458 459 /** 460 * Returns a Base64 Encoded Authentication Request String. 461 * 462 * @return a Base64 Encoded Authentication Request String. 463 * @throws FSMsgException if there is an error encoding 464 * the string. 465 */ 466 public String toBASE64EncodedString() throws FSMsgException { 467 if((assertionConsumerServiceURL == null) || 468 (assertionConsumerServiceURL.length() == 0)) { 469 FSUtils.debug.error("FSAuthnRequestEnvelope.toBASE64EncodedString:" 470 + "assertionConsumerServiceURL is null in the " 471 + "FSAuthnRequestEnvelope"); 472 throw new FSMsgException( 473 "noAssertionConsumerServiceURLElement",null); 474 } 475 if (authnRequest == null){ 476 FSUtils.debug.error("FSAuthnRequestEnvelope.toBASE64EncodedString:" 477 + "authnRequest is null in the FSAuthnRequestEnvelope"); 478 throw new FSMsgException("noAuthnRequestElement",null); 479 } 480 return Base64.encode(this.toXMLString().getBytes()); 481 } 482}