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: FSAuthnRequest.java,v 1.4 2008/07/08 06:03:37 exu Exp $ 026 * 027 */ 028 029package com.sun.identity.federation.message; 030 031import java.util.List; 032import java.util.Date; 033import java.util.Collections; 034import java.util.ArrayList; 035import java.util.Iterator; 036 037import java.io.ByteArrayInputStream; 038import java.io.IOException; 039import java.text.ParseException; 040 041import javax.servlet.http.HttpServletRequest; 042 043import org.w3c.dom.Element; 044import org.w3c.dom.Node; 045import org.w3c.dom.NodeList; 046import org.w3c.dom.Document; 047 048import com.sun.identity.federation.common.FSUtils; 049import com.sun.identity.federation.common.IFSConstants; 050import com.sun.identity.federation.message.common.Extension; 051import com.sun.identity.federation.message.common.FSMsgException; 052import com.sun.identity.federation.message.common.RequestAuthnContext; 053import com.sun.identity.saml.common.SAMLConstants; 054import com.sun.identity.saml.common.SAMLException; 055import com.sun.identity.saml.common.SAMLUtils; 056import com.sun.identity.saml.common.SAMLResponderException; 057import com.sun.identity.saml.protocol.AbstractRequest; 058import com.sun.identity.saml.xmlsig.XMLSignatureManager; 059import com.sun.identity.shared.DateUtils; 060import com.sun.identity.shared.encode.Base64; 061import com.sun.identity.shared.encode.URLEncDec; 062import com.sun.identity.shared.xml.XMLUtils; 063 064/** 065 * The class <code>FSAuthnRequest</code> is used to create , parse 066 * <code>AuthnRequest</code> object. 067 * 068 * @supported.all.api 069 */ 070public class FSAuthnRequest extends AbstractRequest { 071 private List extensions = null; 072 private boolean isPassive = false; 073 private boolean forceAuthn = false; 074 private boolean federate = false; 075 private String nameIDPolicy = null; 076 private String protocolProfile = null; 077 private String providerId = null; 078 private RequestAuthnContext authnContext = null; 079 private String relayState = null; 080 protected String xmlString = null; 081 protected String signatureString = null; 082 protected String authContextCompType = null; 083 protected String id = null; 084 protected String assertionConsumerServiceID = null; 085 protected String consentURI = null; 086 protected String affiliationID = null; 087 protected int minorVersion = 0; 088 protected FSScoping scoping = null; 089 private static final String QUERY_STRING_EXTENSION_PREFIX = "AE_"; 090 /** 091 * Default AuthnRequest construtor 092 */ 093 public FSAuthnRequest() { 094 setIssueInstant(new Date()); 095 } 096 097 /** 098 * Constructor to create <code>FSAuthnRequest</code> object. 099 * 100 * @param requestId the request identifier. 101 * @param respondWiths List of respond withs attributes. 102 * @param providerID provider id of the requesting provider. 103 * @param forceAuthn Force Authentication boolean value. 104 * @param isPassive attribute for IDP to be passive or active. 105 * @param fed attribute to distingush this request for Federation or SSO 106 * @param nameIDPolicy Name ID Policy for this request, possible values 107 * are "none", "onetime", "federated", "any". 108 * @param protocolProf ProtocolProfile used for the SSO. 109 * @param authnCxt Authentication Context used for the SSO. 110 * @param relaySt Relay State i.e. original URL to be redirected after SSO. 111 * @param authContextCompType AuthContext comparison type. 112 * @throws <code>FSMsgException</code> on error. 113 */ 114 public FSAuthnRequest(String requestId, 115 List respondWiths, 116 String providerID, 117 boolean forceAuthn, 118 boolean isPassive, 119 boolean fed, 120 String nameIDPolicy, 121 String protocolProf, 122 RequestAuthnContext authnCxt, 123 String relaySt, 124 String authContextCompType) 125 throws FSMsgException { 126 127 setIssueInstant(new Date()); 128 if((respondWiths != null) && (respondWiths != Collections.EMPTY_LIST)) { 129 int length = respondWiths.size(); 130 for(int i = 0; i < length; i++) { 131 Object temp = respondWiths.get(i); 132 if(!(temp instanceof String)) { 133 FSUtils.debug.error("FSAuthnRequest: wrong input for " + 134 "RespondWith"); 135 throw new FSMsgException("wrongInput", null); 136 } 137 } 138 this.respondWiths = respondWiths; 139 } 140 141 if ((requestId != null) && (requestId.length() != 0)) { 142 requestID = requestId; 143 } else { 144 // random generate one 145 requestID = SAMLUtils.generateID(); 146 if (requestID == null) { 147 FSUtils.debug.error("FSAuthnRequest: couldn't gen RequestID."); 148 throw new FSMsgException("errorGenerateID",null); 149 } 150 } 151 this.isPassive = isPassive; 152 this.forceAuthn = forceAuthn; 153 this.providerId = providerID; 154 this.federate = fed; 155 this.nameIDPolicy = nameIDPolicy; 156 this.protocolProfile = protocolProf; 157 this.relayState = relaySt; 158 this.authnContext = authnCxt; 159 this.authContextCompType = authContextCompType; 160 id = requestID; 161 } 162 163 /** 164 * Constructor to create <code>FSAuthnRequest</code> object. 165 * 166 * @param root the Document Element object. 167 * @throws <code>FSMsgException</code> on error. 168 */ 169 public FSAuthnRequest(Element root) throws FSMsgException { 170 String tag = null; 171 if (root == null) { 172 FSUtils.debug.error("FSAuthnRequest(Element): null input."); 173 throw new FSMsgException("nullInput",null); 174 } 175 if(((tag = root.getLocalName()) == null) || 176 (!tag.equals(IFSConstants.AUTHN_REQUEST))) { 177 FSUtils.debug.error("FSAuthnRequest(Element): wrong input"); 178 throw new FSMsgException("wrongInput",null); 179 } 180 // Attribute IssueInstant 181 String instantString = root.getAttribute(IFSConstants.ISSUE_INSTANT); 182 if ((instantString == null) || (instantString.length() == 0)) { 183 FSUtils.debug.error("FSAuthnRequest(Element): " 184 + "missing IssueInstant"); 185 String[] args = { IFSConstants.ISSUE_INSTANT }; 186 throw new FSMsgException("missingAttribute",args); 187 } else { 188 try { 189 issueInstant = DateUtils.stringToDate(instantString); 190 } catch (ParseException e) { 191 FSUtils.debug.error("FSAuthnRequest(Element): " 192 + "could not parse IssueInstant", e); 193 throw new FSMsgException("wrongInput", null); 194 } 195 } 196 // Consent attribute 197 consentURI = root.getAttribute(IFSConstants.CONSENT); 198 199 id = root.getAttribute(IFSConstants.ID); 200 requestID = root.getAttribute(IFSConstants.AUTH_REQUEST_ID); 201 parseMajorVersion(root.getAttribute(IFSConstants.MAJOR_VERSION)); 202 parseMinorVersion(root.getAttribute(IFSConstants.MINOR_VERSION)); 203 NodeList contentnl = root.getChildNodes(); 204 Node child; 205 String nodeName; 206 int length = contentnl.getLength(); 207 for(int i = 0; i < length; i++) { 208 child = contentnl.item(i); 209 if ((nodeName = child.getLocalName()) != null) { 210 if (nodeName.equals(IFSConstants.RESPONDWITH)) { 211 if (respondWiths == Collections.EMPTY_LIST) { 212 respondWiths = new ArrayList(); 213 } 214 respondWiths.add(XMLUtils.getElementValue((Element) child)); 215 } else if (nodeName.equals(IFSConstants.PROVIDER_ID)) { 216 if(providerId != null && providerId.length() != 0) { 217 FSUtils.debug.error("FSAuthnRequest(Element): should" 218 + "contain only one ProviderID."); 219 throw new FSMsgException("wrongInput",null); 220 } 221 providerId = XMLUtils.getElementValue((Element) child); 222 } else if(nodeName.equals(IFSConstants.NAMEID_POLICY_ELEMENT)) { 223 nameIDPolicy=XMLUtils.getElementValue((Element) child); 224 225 if (nameIDPolicy != null && 226 (nameIDPolicy.equals( 227 IFSConstants.NAME_ID_POLICY_FEDERATED) || 228 nameIDPolicy.equals( 229 IFSConstants.NAME_ID_POLICY_ONETIME)) 230 ) { 231 federate = true; 232 } 233 } else if (nodeName.equals(IFSConstants.FEDERATE)) { 234 String strFederate = 235 XMLUtils.getElementValue((Element)child); 236 if(strFederate != null && strFederate.length() != 0 && 237 strFederate.equals(IFSConstants.TRUE) 238 || strFederate.equals(IFSConstants.ONE)) { 239 federate = true; 240 } 241 } else if (nodeName.equals(IFSConstants.IS_PASSIVE_ELEM)) { 242 String strIsPassive = 243 XMLUtils.getElementValue((Element) child); 244 if(strIsPassive != null && strIsPassive.length() != 0 && 245 strIsPassive.equals(IFSConstants.TRUE)) { 246 isPassive = true; 247 } else { 248 isPassive = false; 249 } 250 } else if (nodeName.equals(IFSConstants.FORCE_AUTHN_ELEM)) { 251 String strForceAuthn = 252 XMLUtils.getElementValue((Element) child); 253 if(strForceAuthn != null && strForceAuthn.length() != 0 && 254 strForceAuthn.equals(IFSConstants.TRUE)) { 255 forceAuthn = true; 256 } else { 257 forceAuthn = false; 258 } 259 } else if (nodeName.equals(IFSConstants.PROTOCOL_PROFILE)) { 260 if(protocolProfile != null 261 && protocolProfile.length() != 0) { 262 FSUtils.debug.error("FSAuthnRequest(Element): " 263 + "should contain only one ProtocolProfile."); 264 throw new FSMsgException("wrongInput",null); 265 } 266 protocolProfile = XMLUtils.getElementValue((Element) child); 267 268 } else if (nodeName.equals(IFSConstants.AUTHN_CONTEXT)) { 269 authnContext = new RequestAuthnContext((Element) child); 270 271 } else if (nodeName.equals( 272 IFSConstants.REQUEST_AUTHN_CONTEXT)) { 273 authnContext = new RequestAuthnContext((Element) child); 274 275 } else if (nodeName.equals(IFSConstants.RELAY_STATE)) { 276 relayState = XMLUtils.getElementValue((Element) child); 277 278 } else if (nodeName.equals( 279 IFSConstants.AUTHN_CONTEXT_COMPARISON)) { 280 authContextCompType = 281 XMLUtils.getElementValue((Element) child); 282 if(!(authContextCompType.equals(IFSConstants.MINIMUM) || 283 authContextCompType.equals(IFSConstants.EXACT) || 284 authContextCompType.equals(IFSConstants.MAXIMUM) || 285 authContextCompType.equals(IFSConstants.BETTER)) ) { 286 throw new FSMsgException("wrongInput",null); 287 } 288 } else if (nodeName.equals( 289 IFSConstants.ASSERTION_CONSUMER_SVC_ID)) { 290 assertionConsumerServiceID = 291 XMLUtils.getElementValue((Element) child); 292 } else if(nodeName.equals(IFSConstants.AFFILIATIONID)) { 293 affiliationID = XMLUtils.getElementValue((Element) child); 294 } else if(nodeName.equals(IFSConstants.EXTENSION)) { 295 if (extensions == null) { 296 extensions = new ArrayList(); 297 } 298 extensions.add(new Extension((Element)child)); 299 } else if(nodeName.equals(IFSConstants.SCOPING)) { 300 scoping = new FSScoping((Element)child); 301 } else { 302 FSUtils.debug.error("FSAuthnRequest(Element): invalid" 303 + " node" + nodeName); 304 throw new FSMsgException("wrongInput",null); 305 } 306 } 307 } 308 309 //check for signature 310 List signs = XMLUtils.getElementsByTagNameNS1(root, 311 SAMLConstants.XMLSIG_NAMESPACE_URI, 312 SAMLConstants.XMLSIG_ELEMENT_NAME); 313 int signsSize = signs.size(); 314 if (signsSize == 1) { 315 Element elem = (Element)signs.get(0); 316 setSignature(elem); 317 xmlString = XMLUtils.print(root); 318 signed = true; 319 } else if (signsSize != 0) { 320 FSUtils.debug.error("FSAuthnRequest(Element): " 321 + "included more than one Signature element."); 322 throw new FSMsgException("moreElement",null); 323 } 324 //end check for signature 325 } 326 327 /** 328 * This method translates the request to an XML document String based on 329 * the Request schema described above. 330 * NOTE: this is a complete AuthnRequest xml string with RequestID, 331 * MajorVersion, etc. 332 * 333 * @return XML String representing the request. 334 * @throws FSMsgException if there is an error. 335 */ 336 public String toXMLString() throws FSMsgException { 337 return toXMLString(true, true); 338 } 339 340 /** 341 * Creates a String representation of the <lib:AuthnRequest> element. 342 * 343 * @param includeNS : Determines whether or not the namespace qualifier 344 * is prepended to the Element when converted 345 * @param declareNS : Determines whether or not the namespace is declared 346 * within the Element. 347 * @return string containing the valid XML for this element. 348 * @throws FSMsgException if there is an error. 349 */ 350 public String toXMLString( 351 boolean includeNS, boolean declareNS 352 ) throws FSMsgException { 353 return toXMLString(includeNS, declareNS, false); 354 } 355 356 /** 357 * Creates a String representation of the <lib:AuthnRequest> element. 358 * 359 * @param includeNS Determines whether or not the namespace qualifier 360 * is prepended to the Element when converted 361 * @param declareNS Determines whether or not the namespace is declared 362 * within the Element. 363 * @param includeHeader Determines whether the output include the xml 364 * declaration header. 365 * @return A string containing the valid XML for this element. 366 * @throws FSMsgException if there is an error. 367 */ 368 public String toXMLString(boolean includeNS, 369 boolean declareNS, 370 boolean includeHeader) throws FSMsgException { 371 if (xmlString != null) { 372 return xmlString; 373 } 374 if((providerId == null) || (providerId.length() == 0)){ 375 FSUtils.debug.error("FSAuthnRequest.toXMLString: " 376 + "providerId is null in the request with requestId:" 377 + requestID); 378 String[] args = { requestID }; 379 throw new FSMsgException("nullProviderIdWRequestId",args); 380 } 381 if ((requestID == null) || (requestID.length() == 0)){ 382 requestID = SAMLUtils.generateID(); 383 if (requestID == null) { 384 FSUtils.debug.error("FSAuthnRequest.toXMLString: " 385 + "couldn't generate RequestID."); 386 throw new FSMsgException("errorGenerateID",null); 387 } 388 } 389 390 StringBuffer xml = new StringBuffer(300); 391 if (includeHeader) { 392 xml.append("<?xml version=\"1.0\" encoding=\""). 393 append(IFSConstants.DEFAULT_ENCODING).append("\" ?>"); 394 } 395 String prefix = ""; 396 String samlpPrefix = ""; 397 String uri = ""; 398 String samlpUri = ""; 399 if (includeNS) { 400 prefix = IFSConstants.LIB_PREFIX; 401 samlpPrefix = IFSConstants.PROTOCOL_PREFIX; 402 } 403 if (declareNS) { 404 if(minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 405 uri = IFSConstants.LIB_12_NAMESPACE_STRING; 406 } else { 407 uri = IFSConstants.LIB_NAMESPACE_STRING; 408 } 409 samlpUri = IFSConstants.PROTOCOL_NAMESPACE_STRING; 410 } 411 412 String instantString = DateUtils.toUTCDateFormat(issueInstant); 413 414 if (requestID != null) { 415 xml.append(IFSConstants.LEFT_ANGLE) 416 .append(prefix) 417 .append(IFSConstants.AUTHN_REQUEST) 418 .append(uri) 419 .append(IFSConstants.SPACE) 420 .append(samlpUri); 421 422 if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION && 423 id != null && !(id.length() == 0)){ 424 xml.append(IFSConstants.SPACE) 425 .append(IFSConstants.ID) 426 .append(IFSConstants.EQUAL_TO) 427 .append(IFSConstants.QUOTE) 428 .append(id) 429 .append(IFSConstants.QUOTE); 430 } 431 xml.append(IFSConstants.SPACE) 432 .append(IFSConstants.REQUEST_ID) 433 .append(IFSConstants.EQUAL_TO) 434 .append(IFSConstants.QUOTE) 435 .append(requestID) 436 .append(IFSConstants.QUOTE) 437 .append(IFSConstants.SPACE) 438 .append(IFSConstants.MAJOR_VERSION) 439 .append(IFSConstants.EQUAL_TO) 440 .append(IFSConstants.QUOTE) 441 .append(majorVersion) 442 .append(IFSConstants.QUOTE) 443 .append(IFSConstants.SPACE) 444 .append(IFSConstants.MINOR_VERSION) 445 .append(IFSConstants.EQUAL_TO) 446 .append(IFSConstants.QUOTE) 447 .append(minorVersion) 448 .append(IFSConstants.QUOTE) 449 .append(IFSConstants.SPACE) 450 .append(IFSConstants.ISSUE_INSTANT) 451 .append(IFSConstants.EQUAL_TO) 452 .append(IFSConstants.QUOTE) 453 .append(instantString) 454 .append(IFSConstants.QUOTE); 455 456 if (consentURI != null) { 457 xml.append(IFSConstants.SPACE) 458 .append(IFSConstants.CONSENT) 459 .append(IFSConstants.EQUAL_TO) 460 .append(IFSConstants.QUOTE) 461 .append(consentURI) 462 .append(IFSConstants.QUOTE); 463 } 464 xml.append(IFSConstants.RIGHT_ANGLE); 465 466 if((respondWiths != null) && 467 (respondWiths != Collections.EMPTY_LIST)) { 468 Iterator i = respondWiths.iterator(); 469 while (i.hasNext()) { 470 xml.append(IFSConstants.LEFT_ANGLE) 471 .append(samlpPrefix) 472 .append(IFSConstants.RESPONDWITH) 473 .append(IFSConstants.RIGHT_ANGLE) 474 .append((String) i.next()) 475 .append(IFSConstants.START_END_ELEMENT) 476 .append(samlpPrefix) 477 .append(IFSConstants.RESPONDWITH) 478 .append(IFSConstants.RIGHT_ANGLE); 479 } 480 } 481 482 if (signed) { 483 if (signatureString != null) { 484 xml.append(signatureString); 485 } else if (signature != null) { 486 signatureString = XMLUtils.print(signature); 487 xml.append(signatureString); 488 } 489 } 490 491 if ((extensions != null) && (!extensions.isEmpty())) { 492 for(Iterator iter = extensions.iterator(); iter.hasNext();) { 493 Extension extension = (Extension)iter.next(); 494 extension.setMinorVersion(minorVersion); 495 xml.append(extension.toXMLString()); 496 } 497 498 } 499 500 xml.append(IFSConstants.LEFT_ANGLE) 501 .append(prefix) 502 .append(IFSConstants.PROVIDER_ID) 503 .append(IFSConstants.RIGHT_ANGLE) 504 .append(providerId) 505 .append(IFSConstants.START_END_ELEMENT) 506 .append(prefix) 507 .append(IFSConstants.PROVIDER_ID) 508 .append(IFSConstants.RIGHT_ANGLE); 509 510 if (affiliationID != null) { 511 xml.append(IFSConstants.LEFT_ANGLE) 512 .append(prefix) 513 .append(IFSConstants.AFFILIATIONID) 514 .append(IFSConstants.RIGHT_ANGLE) 515 .append(affiliationID) 516 .append(IFSConstants.START_END_ELEMENT) 517 .append(prefix) 518 .append(IFSConstants.AFFILIATIONID) 519 .append(IFSConstants.RIGHT_ANGLE); 520 } 521 522 if (minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 523 String strFederate = IFSConstants.NAME_ID_POLICY_NONE; 524 if (federate) { 525 strFederate = IFSConstants.NAME_ID_POLICY_FEDERATED; 526 if (nameIDPolicy != null && nameIDPolicy.length()>0) { 527 strFederate = nameIDPolicy; 528 } 529 } 530 xml.append(IFSConstants.LEFT_ANGLE) 531 .append(prefix) 532 .append(IFSConstants.NAMEID_POLICY_ELEMENT) 533 .append(IFSConstants.RIGHT_ANGLE) 534 .append(strFederate) 535 .append(IFSConstants.START_END_ELEMENT) 536 .append(prefix) 537 .append(IFSConstants.NAMEID_POLICY_ELEMENT) 538 .append(IFSConstants.RIGHT_ANGLE); 539 } else { 540 String strFederate = IFSConstants.FALSE; 541 if (federate) { 542 strFederate = IFSConstants.TRUE; 543 } 544 xml.append(IFSConstants.LEFT_ANGLE) 545 .append(prefix) 546 .append(IFSConstants.FEDERATE) 547 .append(IFSConstants.RIGHT_ANGLE) 548 .append(strFederate) 549 .append(IFSConstants.START_END_ELEMENT) 550 .append(prefix) 551 .append(IFSConstants.FEDERATE) 552 .append(IFSConstants.RIGHT_ANGLE); 553 } 554 555 String strForceAuthn = IFSConstants.FALSE; 556 if (forceAuthn) { 557 strForceAuthn = IFSConstants.TRUE; 558 } 559 560 xml.append(IFSConstants.LEFT_ANGLE) 561 .append(prefix) 562 .append(IFSConstants.FORCE_AUTHN_ELEM) 563 .append(IFSConstants.RIGHT_ANGLE) 564 .append(strForceAuthn) 565 .append(IFSConstants.START_END_ELEMENT) 566 .append(prefix) 567 .append(IFSConstants.FORCE_AUTHN_ELEM) 568 .append(IFSConstants.RIGHT_ANGLE); 569 570 String strIsPassive = IFSConstants.FALSE; 571 if (isPassive) { 572 strIsPassive = IFSConstants.TRUE; 573 } 574 575 xml.append(IFSConstants.LEFT_ANGLE) 576 .append(prefix) 577 .append(IFSConstants.IS_PASSIVE_ELEM) 578 .append(IFSConstants.RIGHT_ANGLE) 579 .append(strIsPassive) 580 .append(IFSConstants.START_END_ELEMENT) 581 .append(prefix) 582 .append(IFSConstants.IS_PASSIVE_ELEM) 583 .append(IFSConstants.RIGHT_ANGLE); 584 585 if(protocolProfile != null && protocolProfile.length() != 0) { 586 xml.append(IFSConstants.LEFT_ANGLE) 587 .append(prefix) 588 .append(IFSConstants.PROTOCOL_PROFILE) 589 .append(IFSConstants.RIGHT_ANGLE) 590 .append(protocolProfile) 591 .append(IFSConstants.START_END_ELEMENT) 592 .append(prefix) 593 .append(IFSConstants.PROTOCOL_PROFILE) 594 .append(IFSConstants.RIGHT_ANGLE); 595 } 596 597 if(assertionConsumerServiceID != null) { 598 xml.append(IFSConstants.LEFT_ANGLE) 599 .append(prefix) 600 .append(IFSConstants.ASSERTION_CONSUMER_SVC_ID) 601 .append(IFSConstants.RIGHT_ANGLE) 602 .append(assertionConsumerServiceID) 603 .append(IFSConstants.START_END_ELEMENT) 604 .append(prefix) 605 .append(IFSConstants.ASSERTION_CONSUMER_SVC_ID) 606 .append(IFSConstants.RIGHT_ANGLE); 607 } 608 609 if(authnContext != null){ 610 authnContext.setMinorVersion(minorVersion); 611 xml.append(authnContext.toXMLString()); 612 } 613 614 if(relayState != null && relayState.length() != 0){ 615 xml.append(IFSConstants.LEFT_ANGLE) 616 .append(prefix) 617 .append(IFSConstants.RELAY_STATE) 618 .append(IFSConstants.RIGHT_ANGLE) 619 .append(XMLUtils.escapeSpecialCharacters(relayState)) 620 .append(IFSConstants.START_END_ELEMENT) 621 .append(prefix) 622 .append(IFSConstants.RELAY_STATE) 623 .append(IFSConstants.RIGHT_ANGLE); 624 } 625 626 if (minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 627 if (scoping != null) { 628 xml.append(scoping.toXMLString(true, false)); 629 } 630 } 631 632 if(minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { 633 if(authContextCompType != null && 634 authContextCompType.length() != 0) { 635 xml.append(IFSConstants.LEFT_ANGLE) 636 .append(prefix) 637 .append(IFSConstants.AUTHN_CONTEXT_COMPARISON) 638 .append(IFSConstants.RIGHT_ANGLE) 639 .append(authContextCompType) 640 .append(IFSConstants.START_END_ELEMENT) 641 .append(prefix) 642 .append(IFSConstants.AUTHN_CONTEXT_COMPARISON) 643 .append(IFSConstants.RIGHT_ANGLE); 644 } 645 } 646 647 xml.append(IFSConstants.START_END_ELEMENT) 648 .append(prefix) 649 .append(IFSConstants.AUTHN_REQUEST) 650 .append(IFSConstants.RIGHT_ANGLE); 651 } else{ 652 FSUtils.debug.error("FSAuthnRequest.toString: requestID is null "); 653 throw new FSMsgException("nullAuthnRequestID",null); 654 } 655 return xml.toString(); 656 } 657 658 /** 659 * Returns the <code>FSAuthnRequest</code> object. 660 * 661 * @param xml the XML string. 662 * @return <code>FSAuthnRequest</code> object. 663 * @throws FSMsgException if there is 664 * error creating the object. 665 */ 666 public static FSAuthnRequest parseXML(String xml) throws FSMsgException { 667 Document doc = XMLUtils.toDOMDocument(xml, FSUtils.debug); 668 if (doc == null) { 669 FSUtils.debug.error("FSAuthnRequest.parseXML:Error " 670 + "while parsing input xml string"); 671 throw new FSMsgException("parseError",null); 672 } 673 Element root = doc.getDocumentElement(); 674 return new FSAuthnRequest(root); 675 } 676 677 /** 678 * Returns Signed XML String representation of this object. 679 * 680 * @return signed XML String. 681 */ 682 public String getSignedXMLString(){ 683 return xmlString; 684 } 685 686 /** 687 * Returns the signature string. 688 * 689 * @return the signature string. 690 */ 691 public String getSignatureString(){ 692 return signatureString; 693 } 694 695 /** 696 * Returns a list of <code>Extension</code> objects. 697 * Each entry of the list is a <code>Extension</code> object. 698 * 699 * @return a list of <code>Extension</code> elements. 700 * @see #setExtensions(List) 701 */ 702 703 public List getExtensions() { 704 return extensions; 705 } 706 707 /** 708 * Sets <code>Extension</code> objects. 709 * Each entry of the list is a <code>Extension</code> object. 710 * 711 * @param extensions a list of <code>Extension</code> objects. 712 * @see #getExtensions 713 */ 714 public void setExtensions(List extensions) { 715 this.extensions = extensions; 716 } 717 718 /** 719 * Returns the value of Force Authentication attribute. 720 * 721 * @return the value of Force Authentication attribute. 722 */ 723 public boolean getForceAuthn() { 724 return forceAuthn; 725 } 726 727 /** 728 * Sets the value of Force Authentication attribute. 729 * 730 * @param forceAuthn value of Force Authentication attribute. 731 */ 732 public void setForceAuthn(boolean forceAuthn) { 733 this.forceAuthn = forceAuthn; 734 } 735 736 /** 737 * Returns the value of the <code>isPassive</code> attribute. 738 * 739 * @return value of <code>isPassive</code> attribute. 740 */ 741 public boolean getIsPassive() { 742 return isPassive; 743 } 744 745 /** 746 * Sets the value of the <code>IsPassive</code> attribute. 747 * 748 * @param isPassive value of <code>isPassive</code> attribute. 749 */ 750 public void setIsPassive(boolean isPassive) { 751 this.isPassive = isPassive; 752 } 753 754 /** 755 * Returns the value of the <code>Federate</code> attribute. 756 * 757 * @return the value fo the <code>Federate</code> attribute. 758 */ 759 public boolean getFederate() { 760 return federate; 761 } 762 763 /** 764 * Sets the value of the <code>Federate</code> attribute. 765 * 766 * @param fed the value of the <code>Federate</code> attribute. 767 */ 768 public void setFederate(boolean fed) { 769 federate = fed; 770 } 771 772 /** 773 * Returns the <code>NameIDPolicy</code> object. 774 * 775 * @return the <code>NameIDPolicy</code> object. 776 * @see #setNameIDPolicy(String) 777 */ 778 779 public String getNameIDPolicy() { 780 return nameIDPolicy; 781 } 782 783 /** 784 * Sets the <code>NameIDPolicy</code> object. 785 * 786 * @param nameIDPolicy the new <code>NameIDPolicy</code> object. 787 * @see #getNameIDPolicy 788 */ 789 public void setNameIDPolicy(String nameIDPolicy) { 790 this.nameIDPolicy = nameIDPolicy; 791 } 792 793 /** 794 * Returns the value of <code>ProtocolProfile<code> attribute. 795 * 796 * @return the value of <code>ProtocolProfile<code> attribute. 797 * @see #setProtocolProfile(String) 798 */ 799 public String getProtocolProfile() { 800 return protocolProfile; 801 } 802 803 /** 804 * Sets the value of <code>ProtocolProfile<code> attribute. 805 * 806 * @param protocolProf the value of <code>ProtocolProfile<code> attribute. 807 * @see #getProtocolProfile() 808 */ 809 public void setProtocolProfile(String protocolProf) { 810 protocolProfile = protocolProf; 811 } 812 813 /** 814 * Returns the value of RelayState attribute. 815 * 816 * @return the value of RelayState attribute. 817 * @see #setRelayState(String) 818 */ 819 public String getRelayState() { 820 return relayState; 821 } 822 823 /** 824 * Set the value of RelayState attribute. 825 * 826 * @param relaySt the value of RelayState attribute. 827 * @see #getRelayState() 828 */ 829 public void setRelayState(String relaySt) { 830 relayState = relaySt; 831 } 832 833 /** 834 * Returns the <code>RequestedAuthnContext</code> object. 835 * 836 * @return the <code>RequestedAuthnContext</code> object. 837 * @see #setAuthnContext(RequestAuthnContext) 838 */ 839 public RequestAuthnContext getAuthnContext() { 840 return authnContext; 841 } 842 843 /** 844 * Sets the <code>RequestedAuthnContext</code> object. 845 * 846 * @param authnCxt the <code>RequestAuthnContext</code> object. 847 * @see #getAuthnContext() 848 */ 849 public void setAuthnContext(RequestAuthnContext authnCxt) { 850 authnContext = authnCxt; 851 } 852 853 /** 854 * Returns the value of <code>ProviderID</code> attribute. 855 * 856 * @return the value of <code>ProviderID</code> attribute. 857 * @see #setProviderId(String). 858 */ 859 public String getProviderId() { 860 return providerId; 861 } 862 863 /** 864 * Sets the value of <code>ProviderID</code> attribute. 865 * 866 * @param provId the value of <code>ProviderID</code> attribute. 867 * @see #getProviderId() 868 */ 869 public void setProviderId(String provId) { 870 providerId = provId; 871 } 872 873 /** 874 * Returns the value of AuthContext Comparison attribute. 875 * 876 * @return he value of AuthContext Comparison attribute. 877 * @see #setAuthContextCompType(String) 878 */ 879 public String getAuthContextCompType() { 880 return authContextCompType; 881 } 882 883 /** 884 * Sets the value of AuthContext Comparison attribute. 885 * 886 * @param authType he value of AuthContext Comparison attribute. 887 * @see #getAuthContextCompType() 888 */ 889 public void setAuthContextCompType(String authType) { 890 authContextCompType = authType; 891 } 892 893 /** 894 * Returns the value of <code>id</code> attribute. 895 * 896 * @return the value of <code>id</code> attribute. 897 * @see #setID(String) 898 */ 899 public String getID() { 900 return id; 901 } 902 903 /** 904 * Sets the value of <code>id</code> attribute. 905 * 906 * @param id the value of <code>id</code> attribute. 907 * @see #getID() 908 */ 909 public void setID(String id) { 910 this.id = id; 911 } 912 913 /** 914 * Returns the value of the <code>MinorVersion</code> attribute. 915 * 916 * @return the value of the <code>MinorVersion</code> attribute. 917 * @see #setMinorVersion(int) 918 */ 919 public int getMinorVersion() { 920 return minorVersion; 921 } 922 923 /** 924 * Sets the value of the <code>MinorVersion</code> attribute. 925 * 926 * @param version the value of the <code>MinorVersion</code> attribute. 927 * @see #getMinorVersion() 928 */ 929 public void setMinorVersion(int version) { 930 minorVersion = version; 931 } 932 933 /** 934 * Returns the Affliation Identifier. 935 * 936 * @return the Affliation Identifier. 937 * @see #setAffiliationID(String) 938 */ 939 public String getAffiliationID() { 940 return affiliationID; 941 } 942 943 /** 944 * Sets the Affiliation Identifier. 945 * 946 * @param affiliationID the Affiliation Identifier. 947 * @see #getAffiliationID() 948 */ 949 public void setAffiliationID(String affiliationID) { 950 this.affiliationID = affiliationID; 951 } 952 953 /** 954 * Returns the Assertion Consumer Service Identifier. 955 * 956 * @return the Assertion Consumer Service Identifier. 957 * @see #setAssertionConsumerServiceID(String) 958 */ 959 public String getAssertionConsumerServiceID() { 960 return assertionConsumerServiceID; 961 } 962 963 /** 964 * Sets the Assertion Consumer Service Identifier. 965 * 966 * @param assertionConsumerServiceID the Assertion Consumer 967 * Service Identifier. 968 * @see #getAssertionConsumerServiceID 969 */ 970 public void setAssertionConsumerServiceID( 971 String assertionConsumerServiceID) { 972 this.assertionConsumerServiceID = assertionConsumerServiceID; 973 } 974 975 /** 976 * Returns the value of <code>consent</code> attribute. 977 * 978 * @return the value of <code>consent</code> attribute. 979 * @see #setConsent(String) 980 */ 981 public String getConsent() { 982 return consentURI; 983 } 984 985 /** 986 * Sets the value of <code>consent</code> attribute. 987 * 988 * @param consentURI the value of <code>consent</code> attribute. 989 * @see #getConsent() 990 */ 991 public void setConsent(String consentURI) { 992 this.consentURI = consentURI; 993 } 994 995 /** 996 * Sets the <code>FSScoping</code> object. 997 * 998 * @param scoping the <code>FSScoping</code> object. 999 * @see #getScoping() 1000 */ 1001 public void setScoping(FSScoping scoping) { 1002 this.scoping = scoping; 1003 } 1004 1005 /** 1006 * Returns the <code>FSScoping</code> object. 1007 * 1008 * @return the <code>FSScoping</code> object. 1009 * @see #setScoping(FSScoping) 1010 */ 1011 public FSScoping getScoping() { 1012 return scoping; 1013 } 1014 1015 /** 1016 * Validates the the <code>MajorVersion</code> property in the 1017 * <code>AuthnRequest</code>. 1018 * 1019 * @param majorVer the value of <code>MajorVersion</code> property 1020 * @throws FSMsgException if the <code>MajoorVersion</code> 1021 * is null or is invalid. 1022 */ 1023 private void parseMajorVersion(String majorVer) throws FSMsgException { 1024 try { 1025 majorVersion = Integer.parseInt(majorVer); 1026 } catch (NumberFormatException e) { 1027 if (FSUtils.debug.messageEnabled()) { 1028 FSUtils.debug.message("FSAuthnRequest(Element): invalid " 1029 + "MajorVersion", e); 1030 } 1031 throw new FSMsgException("wrongInput",null); 1032 } 1033 1034 if (majorVersion != IFSConstants.PROTOCOL_MAJOR_VERSION) { 1035 if (majorVersion > IFSConstants.PROTOCOL_MAJOR_VERSION) { 1036 if (FSUtils.debug.messageEnabled()) { 1037 FSUtils.debug.message("FSAuthnRequest(Element): " 1038 + "MajorVersion of the AuthnRequest is too high."); 1039 } 1040 throw new FSMsgException("requestVersionTooHigh",null); 1041 } else { 1042 if (FSUtils.debug.messageEnabled()) { 1043 FSUtils.debug.message("FSAuthnRequest(Element): " 1044 + "MajorVersion of the AuthnRequest is too low."); 1045 } 1046 throw new FSMsgException("requestVersionTooLow",null); 1047 } 1048 } 1049 1050 } 1051 /** 1052 * Validates the the <code>MinorVersion</code> property in the 1053 * <code>AuthnRequest</code>. 1054 * 1055 * @param minorVer the value of <code>MinorVersion</code> property 1056 * @throws FSMsgException if the <code>MinorVersion</code> 1057 * is null or is invalid. 1058 */ 1059 private void parseMinorVersion(String minorVer) throws FSMsgException { 1060 try { 1061 minorVersion = Integer.parseInt(minorVer); 1062 } catch (NumberFormatException e) { 1063 if (FSUtils.debug.messageEnabled()) { 1064 FSUtils.debug.message("FSAuthnRequest(Element): invalid " 1065 + "MinorVersion", e); 1066 } 1067 throw new FSMsgException("wrongInput",null); 1068 } 1069 if(minorVersion > IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 1070 if (FSUtils.debug.messageEnabled()) { 1071 FSUtils.debug.message("FSAuthnRequest.checkMinorVersion:"+ 1072 " Minor Version of the AuthnRequest is too high."); 1073 } 1074 throw new FSMsgException("requestVersionTooHigh",null); 1075 } else if (minorVersion < IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { 1076 if (FSUtils.debug.messageEnabled()) { 1077 FSUtils.debug.message("FSAuthnRequest.checkMinorVersion:" + 1078 " Minor Version of the AuthnRequest is too low."); 1079 } 1080 throw new FSMsgException("requestVersionTooLow",null); 1081 } 1082 1083 } 1084 1085 /** 1086 * Checks the value of the <code>MajorVersion</code> property 1087 * in the <code>AuthnRequest</code>. 1088 * 1089 * @param minorVer the value of <code>MajorVersion</code> property 1090 * @return integer value of <code>MajorVersion</code> property 1091 * @throws FSMsgException if the <code>MajorVersion</code> 1092 * is null or invalid. 1093 */ 1094 private static int checkMajorVersion(String majorVer) 1095 throws FSMsgException { 1096 int majorVersion; 1097 if (majorVer == null){ 1098 throw new FSMsgException("nullMajorVersion",null); 1099 } 1100 try { 1101 majorVersion = Integer.parseInt(majorVer); 1102 } catch (NumberFormatException e) { 1103 if (FSUtils.debug.messageEnabled()) { 1104 FSUtils.debug.message("FSAuthnRequest.checkMajorVersion: " 1105 + "invalid MajorVersion: " + e.getMessage()); 1106 } 1107 throw new FSMsgException("wrongInput",null); 1108 } 1109 1110 if (majorVersion != SAMLConstants.PROTOCOL_MAJOR_VERSION) { 1111 if (majorVersion > SAMLConstants.PROTOCOL_MAJOR_VERSION) { 1112 if (FSUtils.debug.messageEnabled()) { 1113 FSUtils.debug.message("FSAuthnRequest.checkMajorVersion: " 1114 + "MajorVersion of the AuthnRequest is too high" 1115 + majorVersion); 1116 } 1117 throw new FSMsgException("requestVersionTooHigh",null); 1118 } else { 1119 if (FSUtils.debug.messageEnabled()) { 1120 FSUtils.debug.message( 1121 "FSAuthnRequest.checkMajorVersion:MajorVersion of " 1122 + "the AuthnRequest is too low. " + majorVersion); 1123 } 1124 throw new FSMsgException("requestVersionTooLow",null); 1125 } 1126 } 1127 return majorVersion; 1128 } 1129 1130 /** 1131 * Checks the value of the <code>MinorVersion</code> property 1132 * in the <code>AuthnRequest</code>. 1133 * 1134 * @param minorVer the value of <code>MinorVersion</code> property 1135 * @return integer value of <code>MinorVersion</code> property 1136 * @throws FSMsgException if the <code>MinorVersion</code> 1137 * is null or invalid. 1138 */ 1139 private static int checkMinorVersion(String minorVer) 1140 throws FSMsgException { 1141 int minorVersion; 1142 if (minorVer == null){ 1143 throw new FSMsgException("nullMinorVersion",null); 1144 } 1145 try { 1146 minorVersion = Integer.parseInt(minorVer); 1147 } catch (NumberFormatException e) { 1148 if (FSUtils.debug.messageEnabled()) { 1149 FSUtils.debug.message("FSAuthnRequest.checkMinorVersion: " 1150 + "invalid MinorVersion", e); 1151 } 1152 throw new FSMsgException("wrongInput",null); 1153 } 1154 if(minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION || 1155 minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { 1156 return minorVersion; 1157 } 1158 if(minorVersion > IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 1159 if(FSUtils.debug.messageEnabled()) { 1160 FSUtils.debug.message("FSAuthnRequest.checkMinorVersion:"+ 1161 " Minor Version of the AuthnRequest is too high."); 1162 } 1163 throw new FSMsgException("requestVersionTooHigh",null); 1164 } else { 1165 if(FSUtils.debug.messageEnabled()) { 1166 FSUtils.debug.message("FSAuthnRequest.checkMinorVersion:" + 1167 " Minor Version of the AuthnRequest is too low."); 1168 } 1169 throw new FSMsgException("requestVersionTooLow",null); 1170 } 1171 } 1172 1173 /** 1174 * Returns an URL Encoded Query String. 1175 * 1176 * @return a url encoded query string. 1177 * @throws FSMsgException if there is an error. 1178 */ 1179 public String toURLEncodedQueryString() throws FSMsgException { 1180 if ((providerId == null) || (providerId.length() == 0)) { 1181 FSUtils.debug.error("FSAuthnRequest.toURLEncodedQueryString: " 1182 + "providerId is null in the request with requestId:" 1183 + requestID); 1184 String[] args = { requestID }; 1185 throw new FSMsgException("nullProviderIdWRequestId",args); 1186 } 1187 if ((requestID == null) || (requestID.length() == 0)){ 1188 requestID = SAMLUtils.generateID(); 1189 if (requestID == null) { 1190 FSUtils.debug.error("FSAuthnRequest.toURLEncodedQueryString: " 1191 + "couldn't generate RequestID."); 1192 throw new FSMsgException("errorGenerateID",null); 1193 } 1194 } 1195 1196 StringBuffer urlEncodedAuthnReq = new StringBuffer(300); 1197 1198 urlEncodedAuthnReq.append(IFSConstants.AUTH_REQUEST_ID) 1199 .append(IFSConstants.EQUAL_TO) 1200 .append(URLEncDec.encode(requestID)) 1201 .append(IFSConstants.AMPERSAND) 1202 .append(IFSConstants.MAJOR_VERSION) 1203 .append(IFSConstants.EQUAL_TO) 1204 .append(majorVersion) 1205 .append(IFSConstants.AMPERSAND) 1206 .append(IFSConstants.MINOR_VERSION) 1207 .append(IFSConstants.EQUAL_TO) 1208 .append(minorVersion) 1209 .append(IFSConstants.AMPERSAND); 1210 if ((extensions != null) && (!extensions.isEmpty())) { 1211 Extension extension = (Extension)extensions.get(0); 1212 urlEncodedAuthnReq.append(extension.toURLEncodedQueryString( 1213 QUERY_STRING_EXTENSION_PREFIX)).append(IFSConstants.AMPERSAND); 1214 1215 if (extensions.size() > 1) { 1216 if (FSUtils.debug.warningEnabled()) { 1217 FSUtils.debug.warning( 1218 "FSAuthnRequest.toURLEncodedQueryString: " + 1219 "only one Extension element is allowed and extras " + 1220 " will be removed"); 1221 } 1222 } 1223 } 1224 1225 urlEncodedAuthnReq.append(IFSConstants.PROVIDER_ID) 1226 .append(IFSConstants.EQUAL_TO) 1227 .append(URLEncDec.encode(providerId)) 1228 .append(IFSConstants.AMPERSAND); 1229 1230 if (consentURI != null) { 1231 urlEncodedAuthnReq.append(IFSConstants.CONSENT) 1232 .append(IFSConstants.EQUAL_TO) 1233 .append(URLEncDec.encode(consentURI)) 1234 .append(IFSConstants.AMPERSAND); 1235 } 1236 1237 if(affiliationID != null) { 1238 urlEncodedAuthnReq.append(IFSConstants.AFFILIATIONID) 1239 .append(IFSConstants.EQUAL_TO) 1240 .append(URLEncDec.encode(affiliationID)) 1241 .append(IFSConstants.AMPERSAND); 1242 } 1243 1244 if (issueInstant != null){ 1245 urlEncodedAuthnReq.append(IFSConstants.ISSUE_INSTANT) 1246 .append(IFSConstants.EQUAL_TO) 1247 .append(URLEncDec.encode( 1248 DateUtils.toUTCDateFormat(issueInstant))) 1249 .append(IFSConstants.AMPERSAND); 1250 } else { 1251 FSUtils.debug.error("FSAuthnRequest.toURLEncodedQueryString: " 1252 + "issueInstant missing"); 1253 String[] args = { IFSConstants.ISSUE_INSTANT }; 1254 throw new FSMsgException("missingAttribute",args); 1255 } 1256 1257 String strForceAuthn = IFSConstants.FALSE; 1258 if (forceAuthn) { 1259 strForceAuthn = IFSConstants.TRUE; 1260 } 1261 1262 urlEncodedAuthnReq.append(IFSConstants.FORCE_AUTHN_ELEM) 1263 .append(IFSConstants.EQUAL_TO) 1264 .append(strForceAuthn) 1265 .append(IFSConstants.AMPERSAND); 1266 1267 String strIsPassive = IFSConstants.FALSE; 1268 if (isPassive) { 1269 strIsPassive = IFSConstants.TRUE; 1270 } 1271 1272 urlEncodedAuthnReq.append(IFSConstants.IS_PASSIVE_ELEM) 1273 .append(IFSConstants.EQUAL_TO) 1274 .append(strIsPassive) 1275 .append(IFSConstants.AMPERSAND); 1276 1277 if (minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 1278 String strFederate = IFSConstants.NAME_ID_POLICY_NONE; 1279 if (federate) { 1280 strFederate = IFSConstants.NAME_ID_POLICY_FEDERATED; 1281 if (nameIDPolicy != null && nameIDPolicy.length() > 0) { 1282 strFederate = nameIDPolicy; 1283 } 1284 } 1285 urlEncodedAuthnReq.append(IFSConstants.NAMEID_POLICY_ELEMENT) 1286 .append(IFSConstants.EQUAL_TO) 1287 .append(strFederate) 1288 .append(IFSConstants.AMPERSAND); 1289 } else { 1290 String strFederate = IFSConstants.FALSE; 1291 if (federate) { 1292 strFederate = IFSConstants.TRUE; 1293 } 1294 urlEncodedAuthnReq.append(IFSConstants.FEDERATE) 1295 .append(IFSConstants.EQUAL_TO) 1296 .append(strFederate) 1297 .append(IFSConstants.AMPERSAND); 1298 } 1299 1300 if (protocolProfile != null && protocolProfile.length() != 0) { 1301 urlEncodedAuthnReq.append(IFSConstants.PROTOCOL_PROFILE) 1302 .append(IFSConstants.EQUAL_TO) 1303 .append(URLEncDec.encode(protocolProfile)) 1304 .append(IFSConstants.AMPERSAND); 1305 } 1306 1307 if (authnContext != null) { 1308 authnContext.setMinorVersion(minorVersion); 1309 urlEncodedAuthnReq.append(authnContext.toURLEncodedQueryString()); 1310 } 1311 1312 if (relayState != null && relayState.length() != 0) { 1313 urlEncodedAuthnReq.append(IFSConstants.RELAY_STATE) 1314 .append(IFSConstants.EQUAL_TO) 1315 .append(URLEncDec.encode(relayState)) 1316 .append(IFSConstants.AMPERSAND); 1317 } 1318 1319 if (scoping != null) { 1320 urlEncodedAuthnReq.append(scoping.toURLEncodedQueryString()); 1321 } 1322 1323 if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { 1324 if (authContextCompType != null 1325 && authContextCompType.length() != 0) { 1326 urlEncodedAuthnReq.append(IFSConstants.AUTHN_CONTEXT_COMPARISON) 1327 .append(IFSConstants.EQUAL_TO) 1328 .append(URLEncDec.encode(authContextCompType)) 1329 .append(IFSConstants.AMPERSAND); 1330 } 1331 } 1332 1333 int len = urlEncodedAuthnReq.length() - 1; 1334 if (urlEncodedAuthnReq.charAt(len) == '&') { 1335 urlEncodedAuthnReq = urlEncodedAuthnReq.deleteCharAt(len); 1336 } 1337 1338 return urlEncodedAuthnReq.toString(); 1339 } 1340 1341 /** 1342 * Returns a Base64 Encoded String. 1343 * 1344 * @return a Base64 Encoded String. 1345 * @throws FSMsgException if there is an error encoding 1346 * the string. 1347 */ 1348 public String toBASE64EncodedString() throws FSMsgException { 1349 if((providerId == null) || (providerId.length() == 0)){ 1350 FSUtils.debug.error("FSAuthnRequest.toBASE64EncodedString: " 1351 + "providerId is null in the request with requestId:" 1352 + requestID); 1353 String[] args = { requestID }; 1354 throw new FSMsgException("nullProviderIdWRequestId",args); 1355 } 1356 if ((requestID == null) || (requestID.length() == 0)) { 1357 requestID = SAMLUtils.generateID(); 1358 if (requestID == null) { 1359 FSUtils.debug.error("FSAuthnRequest.toBASE64EncodedString: " 1360 + "couldn't generate RequestID."); 1361 throw new FSMsgException("errorGenerateID",null); 1362 } 1363 } 1364 return Base64.encode(this.toXMLString().getBytes()); 1365 } 1366 1367 /** 1368 * Returns <code>FSAuthnRequest</code> object. The 1369 * object is creating by parsing the <code>HttpServletRequest</code> 1370 * object. 1371 * 1372 * @param request the <code>HttpServletRequest</code> object. 1373 * @throws FSMsgException if there is an error 1374 * creating <code>FSAuthnRequest</code> object. 1375 */ 1376 public static FSAuthnRequest parseURLEncodedRequest( 1377 HttpServletRequest request) throws FSMsgException { 1378 FSAuthnRequest retAuthnRequest = new FSAuthnRequest(); 1379 String authReqID = request.getParameter(IFSConstants.AUTH_REQUEST_ID); 1380 if (authReqID == null || authReqID.length() == 0) { 1381 throw new FSMsgException("nullAuthnRequestID",null); 1382 } 1383 retAuthnRequest.requestID = authReqID; 1384 1385 String instantString = 1386 request.getParameter(IFSConstants.ISSUE_INSTANT); 1387 if (instantString == null || instantString.length() == 0) { 1388 String[] args = { IFSConstants.ISSUE_INSTANT }; 1389 throw new FSMsgException("missingAttribute",args); 1390 } 1391 try{ 1392 retAuthnRequest.issueInstant = 1393 DateUtils.stringToDate(instantString); 1394 } catch (ParseException e){ 1395 throw new FSMsgException("parseError",null); 1396 } 1397 1398 retAuthnRequest.majorVersion = 1399 checkMajorVersion(request.getParameter( 1400 IFSConstants.MAJOR_VERSION)); 1401 1402 retAuthnRequest.minorVersion = 1403 checkMinorVersion(request.getParameter( 1404 IFSConstants.MINOR_VERSION)); 1405 1406 String providerId = request.getParameter(IFSConstants.PROVIDER_ID); 1407 if (providerId == null || providerId.length() == 0) { 1408 throw new FSMsgException("nullProviderIdInRequest",null); 1409 } else{ 1410 FSUtils.debug.message("ProviderID of the sender: " + providerId); 1411 retAuthnRequest.providerId = providerId; 1412 } 1413 1414 retAuthnRequest.affiliationID = 1415 request.getParameter(IFSConstants.AFFILIATIONID); 1416 1417 String forceAuthn = request.getParameter(IFSConstants.FORCE_AUTHN_ELEM); 1418 if ( forceAuthn != null && forceAuthn.length() != 0 1419 && (forceAuthn.equals(IFSConstants.TRUE) 1420 || forceAuthn.equals(IFSConstants.ONE))) { 1421 retAuthnRequest.forceAuthn = true; 1422 } else { 1423 retAuthnRequest.forceAuthn = false; 1424 } 1425 1426 String isPassive = request.getParameter(IFSConstants.IS_PASSIVE_ELEM); 1427 if (isPassive != null && isPassive.length() != 0 && 1428 (isPassive.equals(IFSConstants.TRUE) || 1429 isPassive.equals(IFSConstants.ONE))) 1430 { 1431 retAuthnRequest.isPassive = true; 1432 } else { 1433 retAuthnRequest.isPassive = false; 1434 } 1435 1436 if (retAuthnRequest.minorVersion 1437 == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 1438 String nameIDPolicy = 1439 request.getParameter(IFSConstants.NAMEID_POLICY_ELEMENT); 1440 1441 if (nameIDPolicy != null && 1442 (nameIDPolicy.equals( 1443 IFSConstants.NAME_ID_POLICY_FEDERATED) || 1444 nameIDPolicy.equals( 1445 IFSConstants.NAME_ID_POLICY_ONETIME)) 1446 ) { 1447 retAuthnRequest.federate = true; 1448 } 1449 retAuthnRequest.nameIDPolicy = nameIDPolicy; 1450 } else { 1451 String federate = request.getParameter(IFSConstants.FEDERATE); 1452 if (federate != null && 1453 federate.length() != 0 && 1454 (federate.equals(IFSConstants.TRUE)|| 1455 federate.equals(IFSConstants.ONE))) { 1456 retAuthnRequest.federate = true; 1457 } else { 1458 retAuthnRequest.federate = false; 1459 } 1460 } 1461 1462 String protocolProfile = 1463 request.getParameter(IFSConstants.PROTOCOL_PROFILE); 1464 if (protocolProfile != null && protocolProfile.length() != 0) { 1465 retAuthnRequest.protocolProfile = protocolProfile; 1466 } 1467 1468 String relayState = request.getParameter(IFSConstants.RELAY_STATE); 1469 if(relayState != null && relayState.length() != 0) { 1470 retAuthnRequest.setRelayState(relayState); 1471 } 1472 1473 String authnContextComparison = 1474 request.getParameter(IFSConstants.AUTHN_CONTEXT_COMPARISON); 1475 if(authnContextComparison != null && 1476 authnContextComparison.length() != 0) { 1477 retAuthnRequest.setAuthContextCompType(authnContextComparison); 1478 String authType = retAuthnRequest.getAuthContextCompType(); 1479 if(! (authType.equals(IFSConstants.MINIMUM) || 1480 authType.equals(IFSConstants.EXACT) || 1481 authType.equals(IFSConstants.MAXIMUM) || 1482 authType.equals(IFSConstants.BETTER)) ) { 1483 throw new FSMsgException("wrongInput",null); 1484 } 1485 } 1486 1487 retAuthnRequest.authnContext = 1488 RequestAuthnContext.parseURLEncodedRequest( 1489 request, retAuthnRequest.getMinorVersion()); 1490 1491 retAuthnRequest.scoping = FSScoping.parseURLEncodedRequest(request); 1492 1493 Extension extension = Extension.parseURLEncodedRequest(request, 1494 QUERY_STRING_EXTENSION_PREFIX, retAuthnRequest.getMinorVersion()); 1495 if (extension != null) { 1496 retAuthnRequest.extensions = new ArrayList(); 1497 retAuthnRequest.extensions.add(extension); 1498 } 1499 1500 return retAuthnRequest; 1501 } 1502 1503 /** 1504 * Returns <code>FSAuthnRequest</code> object. The object 1505 * is created by parsing an Base64 encode authentication 1506 * request string. 1507 * 1508 * @param encodedReq the encode string 1509 * @throws FSMsgException if there is an error 1510 * creating <code>FSAuthnRequest</code> object. 1511 */ 1512 public static FSAuthnRequest parseBASE64EncodedString(String encodedReq) 1513 throws FSMsgException { 1514 if (encodedReq != null && encodedReq.length() != 0) { 1515 String decodedAuthnReq = new String(Base64.decode(encodedReq)); 1516 if (FSUtils.debug.messageEnabled()) { 1517 FSUtils.debug.message( 1518 "FSAuthnRequest.parseBASE64EncodedString: " 1519 + "decoded input string: " + decodedAuthnReq); 1520 } 1521 return parseXML(decodedAuthnReq); 1522 } else{ 1523 if (FSUtils.debug.messageEnabled()) { 1524 FSUtils.debug.message( 1525 "FSAuthnRequest.parseBASE64EncodedString: " 1526 + "null String passed in as argument."); 1527 } 1528 throw new FSMsgException("nullInput",null); 1529 } 1530 } 1531 1532 /** 1533 * Signs the Request. 1534 * 1535 * @param certAlias the Certificate Alias. 1536 * @throws XMLSignatureException if <code>FSAuthnRequest</code> 1537 * cannot be signed. 1538 */ 1539 1540 public void signXML(String certAlias) throws SAMLException { 1541 FSUtils.debug.message("FSAuthnRequest.signXML: Called"); 1542 if (signed) { 1543 if (FSUtils.debug.messageEnabled()) { 1544 FSUtils.debug.message("FSAuthnRequest.signXML: " 1545 + "the assertion is " 1546 + "already signed."); 1547 } 1548 throw new SAMLResponderException(FSUtils.BUNDLE_NAME, 1549 "alreadySigned",null); 1550 } 1551 if (certAlias == null || certAlias.length() == 0) { 1552 throw new SAMLResponderException( 1553 FSUtils.BUNDLE_NAME,"cannotFindCertAlias",null); 1554 } 1555 try{ 1556 XMLSignatureManager manager = XMLSignatureManager.getInstance(); 1557 if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { 1558 signatureString = manager.signXML(this.toXMLString(true, true), 1559 certAlias, (String) null, IFSConstants.ID, 1560 this.id, false); 1561 } else if(minorVersion == 1562 IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { 1563 signatureString = 1564 manager.signXML(this.toXMLString(true, true), 1565 certAlias, (String) null, IFSConstants.REQUEST_ID, 1566 this.getRequestID(), false); 1567 } else { 1568 if (FSUtils.debug.messageEnabled()) { 1569 FSUtils.debug.message("invalid minor version."); 1570 } 1571 } 1572 1573 signature = 1574 XMLUtils.toDOMDocument(signatureString, FSUtils.debug) 1575 .getDocumentElement(); 1576 1577 signed = true; 1578 xmlString = this.toXMLString(true, true); 1579 } catch(Exception e){ 1580 throw new SAMLResponderException( 1581 FSUtils.BUNDLE_NAME,"signFailed",null); 1582 } 1583 } 1584 1585 /** 1586 * Unsupported Method. 1587 */ 1588 public void signXML() throws SAMLException { 1589 throw new SAMLException( 1590 FSUtils.BUNDLE_NAME,"unsupportedOperation",null); 1591 } 1592 1593 /** 1594 * Sets the Signature of the Element passed. 1595 * 1596 * @param elem the Document Element. 1597 * @return true if success otherwise false. 1598 */ 1599 public boolean setSignature(Element elem) { 1600 signatureString = XMLUtils.print(elem); 1601 return super.setSignature(elem); 1602 } 1603}