001/*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2008 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: NameIDMapping.java,v 1.6 2009/11/20 21:41:16 exu Exp $
026 *
027 * Portions Copyrighted 2013-2015 ForgeRock AS.
028 */
029package com.sun.identity.saml2.profile;
030
031import java.security.PrivateKey;
032import java.security.cert.X509Certificate;
033import java.util.Date;
034import java.util.Iterator;
035import java.util.List;
036import java.util.Map;
037import java.util.Set;
038import javax.xml.soap.SOAPException;
039import javax.xml.soap.SOAPMessage;
040
041import com.sun.identity.saml2.common.SOAPCommunicator;
042import com.sun.identity.saml2.jaxb.entityconfig.IDPSSOConfigElement;
043import org.w3c.dom.Element;
044
045import com.sun.identity.plugin.session.SessionException;
046import com.sun.identity.plugin.session.SessionManager;
047import com.sun.identity.plugin.session.SessionProvider;
048import com.sun.identity.saml.xmlsig.KeyProvider;
049import com.sun.identity.saml2.assertion.AssertionFactory;
050import com.sun.identity.saml2.assertion.EncryptedID;
051import com.sun.identity.saml2.assertion.Issuer;
052import com.sun.identity.saml2.assertion.NameID;
053import com.sun.identity.saml2.common.AccountUtils;
054import com.sun.identity.saml2.common.NameIDInfo;
055import com.sun.identity.saml2.common.SAML2Constants;
056import com.sun.identity.saml2.common.SAML2Exception;
057import com.sun.identity.saml2.common.SAML2SDKUtils;
058import com.sun.identity.saml2.common.SAML2Utils;
059import com.sun.identity.saml2.jaxb.entityconfig.BaseConfigType;
060import com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement;
061import com.sun.identity.saml2.jaxb.metadata.NameIDMappingServiceElement;
062import com.sun.identity.saml2.jaxb.metadata.RoleDescriptorType;
063import com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement;
064import com.sun.identity.saml2.key.EncInfo;
065import com.sun.identity.saml2.key.KeyUtil;
066import com.sun.identity.saml2.meta.SAML2MetaException;
067import com.sun.identity.saml2.meta.SAML2MetaManager;
068import com.sun.identity.saml2.plugins.IDPAccountMapper;
069import com.sun.identity.saml2.protocol.NameIDMappingRequest;
070import com.sun.identity.saml2.protocol.NameIDMappingResponse;
071import com.sun.identity.saml2.protocol.NameIDPolicy;
072import com.sun.identity.saml2.protocol.ProtocolFactory;
073import com.sun.identity.saml2.protocol.Status;
074
075import com.sun.identity.shared.xml.XMLUtils;
076
077/**
078 * This class provides methods to send or process
079 * <code>NameIDMappingRequest</code>.
080 *
081 * @supported.api
082 */
083
084public class NameIDMapping {
085    static ProtocolFactory pf = ProtocolFactory.getInstance();
086    static AssertionFactory af = AssertionFactory.getInstance();
087    static SAML2MetaManager metaManager = null;
088    static KeyProvider keyProvider = KeyUtil.getKeyProviderInstance(); 
089
090    static SessionProvider sessionProvider = null;
091    
092    static {
093        try {
094            metaManager= new SAML2MetaManager();
095            sessionProvider = SessionManager.getProvider();
096        } catch (SAML2MetaException se) {
097            SAML2Utils.debug.error(SAML2Utils.bundle.getString(
098                "errorMetaManager"), se);
099        } catch (SessionException sessE) {
100            SAML2Utils.debug.error("Error retrieving session provider.", sessE);
101        }
102    }
103    
104    /**
105     * Parses the request parameters and builds the NameIDMappingRequest to
106     * sent to remote identity provider.
107     *
108     * @param session user session.
109     * @param realm the realm of hosted entity
110     * @param spEntityID entity ID of hosted service provider
111     * @param idpEntityID entity ID of remote idendity provider
112     * @param targetSPEntityID entity ID of target entity ID of service
113     *     provider
114     * @param targetNameIDFormat format of target Name ID
115     * @param paramsMap Map of all other parameters
116     *
117     * @return the <code>NameIDMappingResponse</code>
118     * @throws SAML2Exception if error initiating request to remote entity.
119     *
120     * @supported.api
121     */
122    public static NameIDMappingResponse initiateNameIDMappingRequest(
123        Object session, String realm, String spEntityID, String idpEntityID,
124        String targetSPEntityID, String targetNameIDFormat,
125        Map paramsMap) throws SAML2Exception {
126            
127        if (spEntityID == null) {
128            throw new SAML2Exception(
129                SAML2Utils.bundle.getString("nullSPEntityID"));
130        }
131                
132        if (idpEntityID == null)  {
133            throw new SAML2Exception(
134                SAML2Utils.bundle.getString("nullIDPEntityID"));
135        }
136
137        String userID = null;
138
139        try {
140            userID = sessionProvider.getPrincipalName(session);
141        } catch (SessionException e) {
142            if (SAML2Utils.debug.messageEnabled()) {
143                SAML2Utils.debug.message(
144                    "NameIDMapping.createNameIDMappingRequest: ", e);
145            }
146        }
147
148        if (userID == null) {
149            throw new SAML2Exception(
150                SAML2Utils.bundle.getString("invalidSSOToken"));
151        }
152        
153        if (SAML2Utils.debug.messageEnabled()) {
154            SAML2Utils.debug.message(
155                "NameIDMapping.initiateNameMappingRequest:" +
156                " IDP EntityID is : " + idpEntityID);
157            SAML2Utils.debug.message(
158                "NameIDMapping.initiateNameMappingRequest:" +
159                " SP HOST EntityID is : " + spEntityID); 
160            SAML2Utils.debug.message(
161                "NameIDMapping.initiateNameMappingRequest:" +
162                " target SP EntityID is : " + targetSPEntityID); 
163        }
164        
165        try {
166            // nameIDMappingService
167            String binding = 
168                SAML2Utils.getParameter(paramsMap, SAML2Constants.BINDING); 
169            if (binding == null) {
170                binding = SAML2Constants.SOAP;
171            } else if (!binding.equals(SAML2Constants.SOAP)) {
172                throw new SAML2Exception(
173                    SAML2Utils.bundle.getString("nimServiceBindingUnsupport"));
174            }
175
176            String nimURL = SAML2Utils.getParameter(paramsMap,
177                "nimURL");
178            if (nimURL == null) {
179                NameIDMappingServiceElement nameIDMappingService =
180                    getNameIDMappingService(realm, idpEntityID, binding);
181
182                if (nameIDMappingService != null) {
183                    nimURL = nameIDMappingService.getLocation();
184                }
185            }
186            if (SAML2Utils.debug.messageEnabled()) {
187                SAML2Utils.debug.message(
188                    "NameIDMapping.initiateNameMappingRequest:" +
189                    " nimURL" + nimURL);
190            }
191
192            if (nimURL == null) {
193                throw new SAML2Exception(
194                    SAML2Utils.bundle.getString("nimServiceNotFound"));
195            }
196
197            NameIDMappingRequest nimRequest = createNameIDMappingRequest(
198                userID, realm, spEntityID, idpEntityID, nimURL,
199                targetSPEntityID, targetNameIDFormat);
200
201            signNIMRequest(nimRequest, realm, spEntityID, false);
202
203            BaseConfigType config = metaManager.getIDPSSOConfig(realm,
204                idpEntityID);
205
206            nimURL = SAML2SDKUtils.fillInBasicAuthInfo(config, nimURL);
207
208            return doNIMBySOAP(nimRequest.toXMLString(true,true), nimURL, 
209                realm, spEntityID);
210
211        } catch (SAML2MetaException sme) {
212            throw new SAML2Exception(
213                SAML2Utils.bundle.getString("metaDataError"));            
214        }
215    }
216    
217    public static NameIDMappingResponse processNameIDMappingRequest(
218        NameIDMappingRequest nimRequest, String realm, String idpEntityID)
219        throws SAML2Exception {
220
221        NameIDMappingResponse nimResponse = null;
222        String spEntityID = nimRequest.getIssuer().getValue();
223        if (spEntityID == null)  {
224            throw new SAML2Exception(
225                SAML2Utils.bundle.getString("nullSPEntityID"));
226        }
227
228        String responseID = SAML2Utils.generateID();
229        if (responseID == null) {
230            SAML2Utils.debug.error(
231                SAML2Utils.bundle.getString("failedToGenResponseID"));
232        }
233        nimResponse = pf.createNameIDMappingResponse();
234        nimResponse.setID(responseID);
235        nimResponse.setInResponseTo(nimRequest.getID());
236        nimResponse.setVersion(SAML2Constants.VERSION_2_0);
237        nimResponse.setIssueInstant(new Date());
238        nimResponse.setIssuer(SAML2Utils.createIssuer(idpEntityID)); 
239
240        SAML2Utils.verifyRequestIssuer(realm, idpEntityID,
241            nimRequest.getIssuer(), nimRequest.getID());
242
243
244        NameIDPolicy nameIDPolicy = nimRequest.getNameIDPolicy();
245        String targetSPEntityID = nameIDPolicy.getSPNameQualifier();
246        String format = nameIDPolicy.getFormat();
247
248        Status status = null;
249
250        if ((format != null) && (format.length() != 0) &&
251            (!format.equals(SAML2Constants.PERSISTENT)) &&
252            (!format.equals(SAML2Constants.UNSPECIFIED))) {
253
254            nimResponse.setNameID(nimRequest.getNameID());
255            nimResponse.setEncryptedID(nimRequest.getEncryptedID());
256            status = SAML2Utils.generateStatus(
257            SAML2Constants.INVALID_NAME_ID_POLICY,
258                 SAML2Utils.bundle.getString("targetNameIDFormatUnsupported"));
259        } else if ((targetSPEntityID == null) ||
260            (targetSPEntityID.length() == 0) ||
261            targetSPEntityID.equals(spEntityID)) {
262
263            nimResponse.setNameID(nimRequest.getNameID());
264            nimResponse.setEncryptedID(nimRequest.getEncryptedID());
265            status = SAML2Utils.generateStatus(
266                SAML2Constants.INVALID_NAME_ID_POLICY,
267                SAML2Utils.bundle.getString("targetNameIDNoChange"));
268        } else {
269            // check if source SP has account fed
270            // if yes then get nameid of targetSP
271            IDPAccountMapper idpAcctMapper = SAML2Utils.getIDPAccountMapper(
272                realm, idpEntityID);
273
274            NameID nameID = getNameID(nimRequest, realm, idpEntityID);
275            String userID = idpAcctMapper.getIdentity(nameID, idpEntityID,
276                spEntityID, realm);
277            NameIDInfo targetNameIDInfo = null;
278            if (userID != null) {
279                targetNameIDInfo = AccountUtils.getAccountFederation(userID,
280                    idpEntityID, targetSPEntityID);
281            }
282            if (targetNameIDInfo == null) {
283                nimResponse.setNameID(nimRequest.getNameID());
284                nimResponse.setEncryptedID(nimRequest.getEncryptedID());
285                status = SAML2Utils.generateStatus(
286                    SAML2Constants.INVALID_NAME_ID_POLICY,
287                    SAML2Utils.bundle.getString("targetNameIDNotFound"));
288            } else {
289                NameID targetSPNameID = targetNameIDInfo.getNameID();
290                if (SAML2Utils.debug.messageEnabled()) {
291                    SAML2Utils.debug.message(
292                        "NameIDMapping.processNameIDMappingRequest: " +
293                        "User ID = " + userID + ", name ID = " +
294                        targetSPNameID.toXMLString(true,true));
295                }
296
297                nimResponse.setEncryptedID(getEncryptedID(targetSPNameID,
298                    realm, spEntityID, SAML2Constants.SP_ROLE));
299                status = SAML2Utils.generateStatus(
300                    SAML2Constants.SUCCESS, null);
301            }
302        }
303
304        nimResponse.setStatus(status);
305        signNIMResponse(nimResponse, realm, idpEntityID, false);
306
307        return nimResponse;
308    }
309    
310    static private NameIDMappingRequest createNameIDMappingRequest(
311        String userID, String realm, String spEntityID, String idpEntityID,
312        String destination, String targetSPEntityID, String targetNameIDFormat)
313        throws SAML2Exception {
314
315        if (SAML2Utils.debug.messageEnabled()) {
316            SAML2Utils.debug.message(
317                "NameIDMapping.createNameIDMappingRequest: User ID : " +
318                userID);
319        }
320        
321        NameIDMappingRequest nimRequest = pf.createNameIDMappingRequest();
322        
323        nimRequest.setID(SAML2Utils.generateID());
324        nimRequest.setVersion(SAML2Constants.VERSION_2_0);
325        nimRequest.setDestination(XMLUtils.escapeSpecialCharacters(
326            destination));
327        nimRequest.setIssuer(SAML2Utils.createIssuer(spEntityID));
328        nimRequest.setIssueInstant(new Date());
329
330        setNameIDForNIMRequest(nimRequest, realm, spEntityID, idpEntityID,
331            targetSPEntityID, targetNameIDFormat, userID);
332        return nimRequest;
333    }
334
335    static private NameIDMappingResponse doNIMBySOAP(
336        String nimRequestXMLString, String nimURL, String realm,
337        String spEntityID) throws SAML2Exception {
338
339        if (SAML2Utils.debug.messageEnabled()) {
340            SAML2Utils.debug.message("NameIDMapping.doNIMBySOAP: " +
341                "NIMRequestXMLString : " + nimRequestXMLString);
342            SAML2Utils.debug.message("NameIDMapping.doNIMBySOAP: " +
343                "NIMRedirectURL : " + nimURL);
344        }
345        
346        SOAPMessage resMsg = null;
347        try {
348            resMsg = SOAPCommunicator.getInstance().sendSOAPMessage(nimRequestXMLString, nimURL,
349                    true);
350        } catch (SOAPException se) {
351            SAML2Utils.debug.error("NameIDMapping.doNIMBySOAP: ", se);
352            throw new SAML2Exception(SAML2Utils.bundle.getString(
353                "invalidSOAPMessge"));
354        }
355
356        Element nimRespElem = SOAPCommunicator.getInstance().getSamlpElement(resMsg,
357                SAML2Constants.NAME_ID_MAPPING_RESPONSE);
358        NameIDMappingResponse nimResponse = 
359             pf.createNameIDMappingResponse(nimRespElem);
360        
361        if (SAML2Utils.debug.messageEnabled()) {
362            SAML2Utils.debug.message("NameIDMapping.doNIMBySOAP: " +
363                "NameIDMappingResponse without SOAP envelope:\n" +
364                nimResponse.toXMLString(true,true));
365        }
366
367
368        String idpEntityID = nimResponse.getIssuer().getValue();
369        Issuer resIssuer = nimResponse.getIssuer();
370        String requestId = nimResponse.getInResponseTo();
371        SAML2Utils.verifyResponseIssuer(realm, spEntityID, resIssuer,
372            requestId);
373                    
374        if (!verifyNIMResponse(nimResponse, realm, idpEntityID)) {
375            throw new SAML2Exception(
376                SAML2Utils.bundle.getString("invalidSignInResponse"));
377        }
378
379        return nimResponse;
380    }
381
382    static private void setNameIDForNIMRequest(NameIDMappingRequest nimRequest,
383        String realm, String spEntityID, String idpEntityID,
384        String targetSPEntityID, String targetNameIDFormat, String userID)
385        throws SAML2Exception {
386
387        if (SAML2Utils.debug.messageEnabled()) {
388            SAML2Utils.debug.message("NameIDMapping.setNameIDForNIMRequest: " +
389                "user ID = " + userID);
390        }
391
392        NameID nameID = AssertionFactory.getInstance().createNameID();
393        NameIDInfo info = AccountUtils.getAccountFederation(userID, spEntityID,
394            idpEntityID);
395        nameID.setValue(info.getNameIDValue());
396        nameID.setFormat(info.getFormat());
397        nameID.setNameQualifier(idpEntityID);
398        nameID.setSPNameQualifier(spEntityID);
399
400        NameIDPolicy nameIDPolicy =
401            ProtocolFactory.getInstance().createNameIDPolicy();
402        nameIDPolicy.setSPNameQualifier(targetSPEntityID);
403        nameIDPolicy.setFormat(targetNameIDFormat);
404        nimRequest.setNameIDPolicy(nameIDPolicy);
405
406        boolean needEncryptIt = SAML2Utils.getWantNameIDEncrypted(realm,
407            idpEntityID, SAML2Constants.IDP_ROLE);
408        if (!needEncryptIt) {
409            if (SAML2Utils.debug.messageEnabled()) {
410                SAML2Utils.debug.message(
411                    "NameIDMapping.setNameIDForNIMRequest: "  +
412                    "NamID doesn't need to be encrypted.");
413            }
414            nimRequest.setNameID(nameID);
415            return;
416        }
417        
418        EncryptedID encryptedID = getEncryptedID(nameID, realm, idpEntityID,
419            SAML2Constants.IDP_ROLE);
420
421        nimRequest.setEncryptedID(encryptedID);
422    }    
423
424    /**
425     * Returns first NameIDMappingService matching specified binding in an
426     * entity under the realm.
427     *
428     * @param realm The realm under which the entity resides.
429     * @param entityId ID of the entity to be retrieved.
430     * @param binding bind type need to has to be matched.
431     * @return <code>ManageNameIDServiceElement</code> for the entity or null
432     * @throws SAML2MetaException if unable to retrieve the first identity
433     *     provider's SSO configuration.
434     * @throws SessionException invalid or expired single-sign-on session
435     */
436    static public NameIDMappingServiceElement getNameIDMappingService(
437        String realm, String entityId, String binding)
438        throws SAML2MetaException {
439
440
441        IDPSSODescriptorElement idpSSODesc = metaManager.getIDPSSODescriptor(
442            realm, entityId);
443        if (idpSSODesc == null) {
444            SAML2Utils.debug.error(SAML2Utils.bundle.getString("noIDPEntry"));
445            return null;
446        }
447
448        List list = idpSSODesc.getNameIDMappingService();
449
450        NameIDMappingServiceElement nimService = null;
451        if ((list != null) && !list.isEmpty()) {
452            if (binding == null) {
453                return (NameIDMappingServiceElement)list.get(0);
454            }
455            Iterator it = list.iterator();
456            while (it.hasNext()) {
457                nimService = (NameIDMappingServiceElement)it.next();  
458                if (binding.equalsIgnoreCase(nimService.getBinding())) {
459                    return nimService;
460                }
461            }
462        }
463        return null;
464    }
465        
466    static EncryptedID getEncryptedID(NameID nameID, String realm,
467        String entityID, String role) throws SAML2Exception {
468
469        RoleDescriptorType roled = null;
470
471        if (role.equals(SAML2Constants.SP_ROLE)) {
472            roled = metaManager.getSPSSODescriptor(realm, entityID);
473        } else {
474            roled = metaManager.getIDPSSODescriptor(realm, entityID);
475        }
476
477        EncInfo encInfo = KeyUtil.getEncInfo(roled, entityID, role);
478        
479        if (encInfo == null) {
480            throw new SAML2Exception(
481                SAML2Utils.bundle.getString("UnableToFindEncryptKeyInfo"));
482        }
483        
484        EncryptedID encryptedID = nameID.encrypt(encInfo.getWrappingKey(), 
485            encInfo.getDataEncAlgorithm(), encInfo.getDataEncStrength(),
486            entityID);
487
488        return encryptedID;
489    }    
490
491    private static void signNIMRequest(NameIDMappingRequest nimRequest, 
492        String realm, String spEntityID, boolean includeCert)
493        throws SAML2Exception {
494
495        String alias = SAML2Utils.getSigningCertAlias(realm, spEntityID,
496            SAML2Constants.SP_ROLE);
497        
498        if (SAML2Utils.debug.messageEnabled()) {
499            SAML2Utils.debug.message("NameIDMapping.signNIMRequest: " +
500                "Cert Alias is : " + alias);
501            SAML2Utils.debug.message("NameIDMapping.signNIMRequest: " +
502                "NIMRequest before sign : " +
503                nimRequest.toXMLString(true, true));
504        }
505        PrivateKey signingKey = keyProvider.getPrivateKey(alias);
506        X509Certificate signingCert = null;
507        if (includeCert) {
508            signingCert = keyProvider.getX509Certificate(alias);
509        }
510        
511        if (signingKey != null) {
512            nimRequest.sign(signingKey, signingCert);
513        } else {
514            throw new SAML2Exception(
515                SAML2Utils.bundle.getString("missingSigningCertAlias"));
516        }
517        
518        if (SAML2Utils.debug.messageEnabled()) {
519            SAML2Utils.debug.message("NameIDMapping.signNIMRequest: " +
520                "NIMRequest after sign : " +
521                nimRequest.toXMLString(true, true));
522        }
523    }
524
525    static void signNIMResponse(NameIDMappingResponse nimResponse,
526        String realm, String idpEntityID, boolean includeCert)
527        throws SAML2Exception {
528
529        String alias = SAML2Utils.getSigningCertAlias(realm, idpEntityID,
530            SAML2Constants.IDP_ROLE);
531        if (SAML2Utils.debug.messageEnabled()) {
532            SAML2Utils.debug.message("NameIDMapping.signNIMResponse: " +
533                realm);
534            SAML2Utils.debug.message("NameIDMapping.signNIMResponse: " +
535                idpEntityID);
536            SAML2Utils.debug.message("NameIDMapping.signNIMResponse: " +
537                alias);
538
539        }
540
541        String encryptedKeyPass =
542                SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
543        PrivateKey signingKey;
544        if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
545            signingKey = keyProvider.getPrivateKey(alias);
546        } else {
547            signingKey = keyProvider.getPrivateKey(alias, encryptedKeyPass);
548        }
549        X509Certificate signingCert = null;
550        if (includeCert) {
551            signingCert = keyProvider.getX509Certificate(alias);
552        }
553
554        if (signingKey != null) {
555            nimResponse.sign(signingKey, signingCert); 
556        } else {
557            SAML2Utils.debug.error("NameIDMapping.signNIMResponse: " +
558                "Incorrect configuration for Signing Certificate.");
559            throw new SAML2Exception(
560                SAML2Utils.bundle.getString("metaDataError"));
561        }
562
563    }
564
565    private static boolean verifyNIMResponse(NameIDMappingResponse nimResponse,
566        String realm, String idpEntityID) throws SAML2Exception {
567
568        IDPSSODescriptorElement idpSSODesc = metaManager.getIDPSSODescriptor(
569            realm, idpEntityID);
570        Set<X509Certificate> signingCerts = KeyUtil.getVerificationCerts(idpSSODesc, idpEntityID,
571                SAML2Constants.IDP_ROLE);
572        
573        if (!signingCerts.isEmpty()) {
574            boolean valid = nimResponse.isSignatureValid(signingCerts);
575            if (SAML2Utils.debug.messageEnabled()) {
576                SAML2Utils.debug.message("NameIDMapping.verifyNIMResponse: " +
577                    "Signature is : " + valid);
578            }
579            return valid;
580        } else {
581            throw new SAML2Exception(SAML2Utils.bundle.getString("missingSigningCertAlias"));
582        }
583    }
584
585    private static NameID getNameID(NameIDMappingRequest nimRequest, String realm, String idpEntityID) {
586        NameID nameID = nimRequest.getNameID();
587        if (nameID == null) {
588            EncryptedID encryptedID = nimRequest.getEncryptedID();
589            try {
590                final IDPSSOConfigElement idpSsoConfig = metaManager.getIDPSSOConfig(realm, idpEntityID);
591                nameID = encryptedID.decrypt(KeyUtil.getDecryptionKeys(idpSsoConfig));
592            } catch (SAML2Exception ex) {
593                if (SAML2Utils.debug.messageEnabled()) {
594                    SAML2Utils.debug.message("NameIDMapping.getNameID:", ex);
595                }
596                return null;
597            }
598        }
599
600        if (!SAML2Utils.isPersistentNameID(nameID)) {
601            return null;
602        }
603
604        return nameID;
605    }
606}