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




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.