/** * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: FSSSOAndFedHandler.java,v 1.12 2009/11/04 00:06:11 exu Exp $ * * Portions Copyrighted 2015 ForgeRock AS. */ package com.sun.identity.federation.services.fednsso; import com.sun.identity.common.SystemConfigurationUtil; import com.sun.identity.federation.services.FSSessionManager; import com.sun.identity.federation.services.FSSession; import com.sun.identity.federation.services.FSSessionPartner; import com.sun.identity.federation.services.FSAssertionManager; import com.sun.identity.federation.services.FSAuthnDecisionHandler; import com.sun.identity.federation.services.FSAuthContextResult; import com.sun.identity.federation.services.FSIDPProxy; import com.sun.identity.federation.services.FSRealmIDPProxy; import com.sun.identity.federation.services.logout.FSTokenListener; import com.sun.identity.federation.services.util.FSNameIdentifierHelper; import com.sun.identity.federation.services.util.FSServiceUtils; import com.sun.identity.federation.services.util.FSSignatureManager; import com.sun.identity.federation.services.util.FSSignatureUtil; import com.sun.identity.federation.meta.IDFFMetaException; import com.sun.identity.federation.meta.IDFFMetaManager; import com.sun.identity.federation.meta.IDFFMetaUtils; import com.sun.identity.federation.message.FSAuthnRequest; import com.sun.identity.federation.message.FSAuthnResponse; import com.sun.identity.federation.message.FSAssertion; import com.sun.identity.federation.message.FSResponse; import com.sun.identity.federation.message.FSSAMLRequest; import com.sun.identity.federation.message.FSScoping; import com.sun.identity.federation.jaxb.entityconfig.BaseConfigType; import com.sun.identity.federation.key.KeyUtil; import com.sun.identity.federation.common.FSUtils; import com.sun.identity.federation.common.IFSConstants; import com.sun.identity.federation.common.FSException; import com.sun.identity.federation.common.FSRedirectException; import com.sun.identity.federation.common.LogUtil; import com.sun.identity.federation.accountmgmt.FSAccountManager; import com.sun.identity.federation.accountmgmt.FSAccountFedInfo; import com.sun.identity.federation.accountmgmt.FSAccountFedInfoKey; import com.sun.identity.federation.accountmgmt.FSAccountMgmtException; import com.sun.identity.liberty.ws.meta.jaxb.IDPDescriptorType; import com.sun.identity.liberty.ws.meta.jaxb.SPDescriptorType; import com.sun.identity.plugin.session.SessionException; import com.sun.identity.plugin.session.SessionManager; import com.sun.identity.plugin.session.SessionProvider; import com.sun.identity.saml.assertion.NameIdentifier; import com.sun.identity.saml.common.SAMLException; import com.sun.identity.saml.common.SAMLUtils; import com.sun.identity.saml.protocol.Status; import com.sun.identity.saml.protocol.StatusCode; import com.sun.identity.saml.xmlsig.XMLSignatureManager; import com.sun.identity.saml2.xmlsig.SigManager; import com.sun.identity.shared.encode.Base64; import com.sun.identity.shared.encode.URLEncDec; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Set; import java.util.List; import java.util.ArrayList; import java.util.Enumeration; import java.util.logging.Level; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.IOException; import java.io.ByteArrayInputStream; /** * Base class for IDP side handler that handles single sign on * and federation requests. */ public abstract class FSSSOAndFedHandler { private static FSIDPProxy proxyFinder = null; private static FSRealmIDPProxy realmProxyFinder = null; protected static IDFFMetaManager metaManager = null; protected HttpServletRequest request = null; protected HttpServletResponse response = null; protected SPDescriptorType spDescriptor = null; protected BaseConfigType spConfig = null; protected String spEntityId = null; protected String relayState = null; protected FSAuthnRequest authnRequest = null; protected Object ssoToken = null; protected String metaAlias = null; protected IDPDescriptorType hostedDesc = null; protected BaseConfigType hostedConfig = null; protected String realm = null; protected String hostedEntityId = null; protected Status noFedStatus = null; protected FSAccountManager accountManager = null; static { metaManager = FSUtils.getIDFFMetaManager(); try { String proxyFinderClass = SystemConfigurationUtil.getProperty( "com.sun.identity.federation.proxyfinder"); if ((proxyFinderClass != null) && (proxyFinderClass.length() != 0)) { Object proxyClass = Thread.currentThread().getContextClassLoader().loadClass( proxyFinderClass).newInstance(); if (proxyClass instanceof FSRealmIDPProxy) { realmProxyFinder = (FSRealmIDPProxy)proxyClass; } else if (proxyClass instanceof FSIDPProxy) { proxyFinder = (FSIDPProxy)proxyClass; } } } catch (Exception ex) { FSUtils.debug.error("FSSSOAndFedHandler:Static Init Failed", ex); } } /** * Sets meta alias of the host identity provider. * @param metaAlias meta alias of the provider. */ public void setMetaAlias(String metaAlias) { this.metaAlias = metaAlias; try { accountManager = FSAccountManager.getInstance(metaAlias); } catch (FSAccountMgmtException e) { FSUtils.debug.error( "FSSSOAndFedHandler: couldn't obtain account manager:", e); } } /** * Sets host identity provider's entity ID. * @param hostedEntityId entity ID to be set * @see #getHostedEntityId() */ public void setHostedEntityId(String hostedEntityId) { this.hostedEntityId = hostedEntityId; } /** * Sets host identity provider's meta descriptor. * @param hostedDesc hosted meta descriptor to be set */ public void setHostedDescriptor(IDPDescriptorType hostedDesc) { this.hostedDesc = hostedDesc; } /** * Sets host identity provider's extended meta. * @param hostedConfig host identity provider's extended meta to be set */ public void setHostedDescriptorConfig(BaseConfigType hostedConfig) { this.hostedConfig = hostedConfig; } /** * Gets hosted provider id. * @return hosted provider id. * @see #setHostedEntityId(String) */ public String getHostedEntityId(){ return hostedEntityId; } /** * Gets the realm under which the entity resides. * @return the realm under which the entity resides. * @see #setRealm(String) */ public String getRealm() { return realm; } /** * Sets the realm under which the entity resides. * @param realm The realm under which the entity resides. * @see #getRealm() */ public void setRealm(String realm) { this.realm = realm; } /** * Default constructor. */ protected FSSSOAndFedHandler() { } /** * Constructor. * @param request HttpServletRequest object * @param response HttpServletResponse object * @param authnRequest authentication request * @param spDescriptor SP's provider descriptor * @param spConfig SP's provider extended meta * @param spEntityId SP's entity id * @param relayState where to go after single sign on is done * @param ssoToken token of the user to be single sign-oned */ public FSSSOAndFedHandler( HttpServletRequest request, HttpServletResponse response, FSAuthnRequest authnRequest, SPDescriptorType spDescriptor, BaseConfigType spConfig, String spEntityId, String relayState, Object ssoToken) { this.request = request; this.response = response; this.relayState = relayState; this.authnRequest = authnRequest; this.spDescriptor = spDescriptor; this.spConfig = spConfig; this.spEntityId = spEntityId; this.ssoToken = ssoToken; } /** * Constructor. * @param request HttpServletRequest object * @param response HttpServletResponse object * @param authnRequest authentication request * @param spDescriptor SP's provider descriptor * @param spConfig SP's extended meta * @param spEntityId SP's entity id * @param relayState where to go after single sign on is done */ public FSSSOAndFedHandler( HttpServletRequest request, HttpServletResponse response, FSAuthnRequest authnRequest, SPDescriptorType spDescriptor, BaseConfigType spConfig, String spEntityId, String relayState) { this.request = request; this.response = response; this.authnRequest = authnRequest; this.spDescriptor = spDescriptor; this.spConfig = spConfig; this.spEntityId = spEntityId; this.relayState = relayState; } /** * Constructor. * @param request HttpServletRequest object * @param response HttpServletResponse object */ public FSSSOAndFedHandler( HttpServletRequest request, HttpServletResponse response) { this.request = request; this.response = response; } /** * Handles authentication request. * @param authnRequest FSAuthnRequest object * @return true if the request is handled successfully; * false otherwise. */ public boolean processPreAuthnSSO(FSAuthnRequest authnRequest) { FSUtils.debug.message("FSSSOAndFedHandler.processPreAuthnSSO: Called"); String loginURL = null; List authenticationContextClassRef = null; String currentAuthnContextRef = null; String authType = null; FSAuthContextResult authnResult = null; FSSessionManager sessionMgr = FSSessionManager.getInstance(metaAlias); if (authnRequest.getAuthnContext() != null){ authenticationContextClassRef = authnRequest.getAuthnContext().getAuthnContextClassRefList(); if (authenticationContextClassRef == null) { String authCtxRefDefault = IFSConstants.DEFAULT_AUTHNCONTEXT_PASSWORD; authenticationContextClassRef = new ArrayList(); authenticationContextClassRef.add(authCtxRefDefault); } authType = authnRequest.getAuthContextCompType(); currentAuthnContextRef = null; } boolean authenticated = true; Object ssoToken = null; try { SessionProvider sessionProvider = SessionManager.getProvider(); ssoToken = sessionProvider.getSession(request); if (ssoToken == null) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPreAuthnSSO: " + "session is null. User is not authenticated."); } authenticated = false; } else if(!sessionProvider.isValid(ssoToken)) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPreAuthnSSO: " + "session is not valid. User is not authenticated."); } authenticated = false; } else { FSSession ssoSession = sessionMgr.getSession(ssoToken); if (ssoSession != null) { currentAuthnContextRef = ssoSession.getAuthnContext(); if (currentAuthnContextRef != null){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: User has an existing " + "valid session with authnContext: " + currentAuthnContextRef); } } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: User's authentication" + " context information not found using " + "default authentication context"); } currentAuthnContextRef = IDFFMetaUtils.getFirstAttributeValueFromConfig( hostedConfig, IFSConstants.DEFAULT_AUTHNCONTEXT); } } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.process" + "PreAuthnSSO: User's authenticated session " + "information is not present in FSSessionManager. " + "using default authentication context"); } currentAuthnContextRef = IDFFMetaUtils.getFirstAttributeValueFromConfig( hostedConfig, IFSConstants.DEFAULT_AUTHNCONTEXT); } authenticated = true; } if (authenticated) { // add a listener. TODO : more than one listeners could be // added in case of multiple SPs try { sessionProvider.addListener(ssoToken, new FSTokenListener(metaAlias)); } catch (Exception e) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPreAuthnSSO: " + "Couldn't add listener to session:", e); } } } } catch(SessionException se) { FSUtils.debug.message("FSSSOAndFedHandler.processPreAuthnSSO: " + "SSOException Occured: User does not have session " + se.getMessage()); authenticated = false; } //Initiate proxying if (!authenticated) { try { boolean isProxy = isIDPProxyEnabled(authnRequest); if (isProxy && !authnRequest.getFederate()) { String preferredIDP = getPreferredIDP(authnRequest); if (preferredIDP != null) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.process" + "PreAuthnSSO:IDP to be proxied" + preferredIDP); } sendProxyAuthnRequest(authnRequest, preferredIDP); return true; } //else continue for the local authentication. } } catch (FSRedirectException re) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandle.processPreAuthnSSO:" + "Redirecting for the proxy handling."); } return true; } catch (Exception ex) { FSUtils.debug.error("FSSSOAndFedHandler.processPreAuthnSSO:" + "Exception occured while processing for the proxy.", ex); return false; } } try { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.processPreAuthnSSO: " + "User's authentication status: " + authenticated); } FSAuthnDecisionHandler authnDecisionHandler = new FSAuthnDecisionHandler(realm, hostedEntityId,request); List defAuthnCxtList = new ArrayList(); defAuthnCxtList.add(IDFFMetaUtils.getFirstAttributeValueFromConfig( hostedConfig, IFSConstants.DEFAULT_AUTHNCONTEXT)); if (authnRequest.getIsPassive()){ if (authnRequest.getForceAuthn()){ if (FSUtils.debug.warningEnabled()) { FSUtils.debug.warning("FSSSOAndFedHandler.PreAuthnSSO: " + "IDP is passive can't force authentication."); } return false; } else { if (authenticated){ if (authenticationContextClassRef != null){ authnResult = authnDecisionHandler.decideAuthnContext( authenticationContextClassRef, currentAuthnContextRef, authType); } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: User's " + "authentication context is default"); } authnResult = authnDecisionHandler.getURLForAuthnContext( defAuthnCxtList, authType); } if (authnResult == null) { return false; } if (authnResult.getLoginURL() != null) { // When it's not null., // we should show the login page // may be it'asking for higher auth context. loginURL = authnResult.getLoginURL(); loginURL = formatLoginURL(loginURL, authnResult.getAuthContextRef()); FSUtils.forwardRequest(request, response, loginURL); return true; } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: User's " + "authentication " + "context is evaluated to be valid"); } return processPostAuthnSSO(authnRequest); } } else { if (FSUtils.debug.warningEnabled()) { FSUtils.debug.warning( "FSSSOAndFedHandler.processPreAuthnSSO: " + "IDP is passive and user is not authenticated"); } noFedStatus = new Status( new StatusCode("samlp:Responder", new StatusCode("lib:NoPassive", null)), FSUtils.bundle.getString( "AuthnRequestProcessingFailed"), null); return false; } } } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: AuthnRequest is active"); } if (authnRequest.getForceAuthn()){ if (authenticationContextClassRef != null){ authnResult = authnDecisionHandler.getURLForAuthnContext( authenticationContextClassRef, authType); } else { authnResult = authnDecisionHandler.getURLForAuthnContext( defAuthnCxtList); } if (authnResult == null || authnResult.getLoginURL() == null || authnResult.getLoginURL().length() == 0) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPreAuthnSSO:" + "AuthnDecision engine failed to take a " + "authn decision"); } return false; } else { if (ssoToken != null) { try { SessionManager.getProvider().invalidateSession( ssoToken, request, response); } catch (SessionException ssoe) { FSUtils.debug.error( "FSSSOAndFedHandler.processPreAuthnSSO:" + "Unable to invalidate the sso session."); } ssoToken = null; } loginURL = authnResult.getLoginURL(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPreAuthnSSO: " + "AuthnDecision engine returned: " + loginURL); } } loginURL = formatLoginURL(loginURL, authnResult.getAuthContextRef()); FSUtils.forwardRequest(request, response, loginURL); response.flushBuffer (); return true; } else { if (authenticated){ if (authenticationContextClassRef != null){ authnResult = authnDecisionHandler.decideAuthnContext( authenticationContextClassRef, currentAuthnContextRef, authType); } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: User's " + "authentication " + "context is default"); } authnResult = authnDecisionHandler.getURLForAuthnContext( defAuthnCxtList, authType); } if (authnResult == null){ return false; } else if(authnResult.getLoginURL() == null){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: User's " + "authentication " + "context is evaluated to be valid"); } return processPostAuthnSSO(authnRequest); } else if(authnResult.getLoginURL().length() == 0){ return false; } else { loginURL = authnResult.getLoginURL(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPreAuthnSSO" + ": AuthnDecision engine returned: " + loginURL); } } loginURL = formatLoginURL(loginURL, authnResult.getAuthContextRef()); FSUtils.forwardRequest(request, response, loginURL); return true; } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: AuthnRequest is active"); } //redirect for authentication authnContextRef if (authenticationContextClassRef != null){ authnResult = authnDecisionHandler.getURLForAuthnContext( authenticationContextClassRef, authType); } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processPreAuthnSSO: User's " + "authentication " + "context is default"); } authnResult = authnDecisionHandler.getURLForAuthnContext( defAuthnCxtList, authType); } if (authnResult == null || authnResult.getLoginURL() == null || authnResult.getLoginURL().length() == 0) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler. processPreAuthnSSO: " + " AuthnDecision engine" + " failed to take a decision"); } noFedStatus = new Status( new StatusCode("samlp:Responder", new StatusCode("lib:NoAuthnContext", null)), FSUtils.bundle.getString( "AuthnRequestProcessingFailed"), null); return false; } else { loginURL = authnResult.getLoginURL(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPreAuthnSSO: " + "AuthnDecision engine returned: " + loginURL); } } loginURL = formatLoginURL(loginURL, authnResult.getAuthContextRef()); FSUtils.forwardRequest(request, response, loginURL); return true; } } } } catch(Exception e){ FSUtils.debug.error("FSSSOAndFedHandler.processPreAuthnSSO: " + "Exception occured"); return processPostAuthnSSO(authnRequest); } } /** * Generates local login url. * @param loginUrl authentication base url * @param authnContext requested AuthnContextRef * @return local login url with appropriate parameters */ public String formatLoginURL( String loginUrl, String authnContext ) { FSUtils.debug.message("FSSSOAndFedHandler.formatLoginURL: Called"); try { if (loginUrl == null){ FSUtils.debug.error("FSSSOAndFedHandler.formatLoginURL: "); return null; } //create return url String ssoUrl = hostedDesc.getSingleSignOnServiceURL(); StringBuffer returnUrl = new StringBuffer(ssoUrl); if (ssoUrl.indexOf('?') == -1) { returnUrl.append("?"); } else { returnUrl.append("&"); } returnUrl.append(IFSConstants.AUTHN_INDICATOR_PARAM) .append("=").append(IFSConstants.AUTHN_INDICATOR_VALUE) .append("&").append(IFSConstants.AUTHN_CONTEXT) .append("=").append(URLEncDec.encode(authnContext)) .append("&").append(IFSConstants.REALM) .append("=").append(URLEncDec.encode(realm)) .append("&").append(IFSConstants.PROVIDER_ID_KEY) .append("=").append(URLEncDec.encode(hostedEntityId)) .append("&").append(IFSConstants.META_ALIAS) .append("=").append(URLEncDec.encode(metaAlias)) .append("&").append(IFSConstants.AUTH_REQUEST_ID) .append("=").append(URLEncDec.encode( authnRequest.getRequestID())); //create goto url String postLoginUrl = FSServiceUtils.getBaseURL(request) + IFSConstants.POST_LOGIN_PAGE; StringBuffer gotoUrl = new StringBuffer(postLoginUrl); if (postLoginUrl.indexOf('?') == -1) { gotoUrl.append("?"); } else { gotoUrl.append("&"); } gotoUrl.append(IFSConstants.LRURL).append("=") .append(URLEncDec.encode(returnUrl.toString())) .append("&").append(IFSConstants.SSOKEY).append("=") .append(IFSConstants.SSOVALUE).append("&") .append(IFSConstants.META_ALIAS).append("=").append(metaAlias); //create redirect url StringBuffer redirectUrl = new StringBuffer(100); redirectUrl.append(loginUrl); if (loginUrl.indexOf('?') == -1) { redirectUrl.append("?"); } else { redirectUrl.append("&"); } redirectUrl.append(IFSConstants.GOTO_URL_PARAM).append("=") .append(URLEncDec.encode(gotoUrl.toString())); redirectUrl.append("&").append(IFSConstants.ORGKEY).append("=") .append(URLEncDec.encode(realm)); //will change //request.getSession(true) // .setAttribute(IFSConstants.AUTHN_CONTEXT, authnContext); int len = redirectUrl.length() - 1; if (redirectUrl.charAt(len) == '&') { redirectUrl = redirectUrl.deleteCharAt(len); } return redirectUrl.toString(); } catch(Exception e){ FSUtils.debug.error( "FSSSOAndFedHandler.formatLoginURL: Exception: " ,e); return null; } } /** * Handles authentication request after local login. * @param authnRequest FSAuthnRequest object * @return true if the request is handled successfully; * false otherwise. */ public boolean processPostAuthnSSO(FSAuthnRequest authnRequest) { FSUtils.debug.message("FSSSOAndFedHandler.processPostAuthnSSO: Called"); SessionProvider sessionProvider = null; try { sessionProvider = SessionManager.getProvider(); if (ssoToken == null) { ssoToken = sessionProvider.getSession(request); } if ((ssoToken == null) || (!sessionProvider.isValid(ssoToken))) { FSUtils.debug.error("FSSSOAndFedHandler.processPostAuthnSSO: " + "session is not valid."); return false; } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPostAuthnSSO: " + "session is valid."); } } } catch(SessionException se) { FSUtils.debug.error("FSSSOAndFedHandler.processPostAuthnSSO: ", se); return false; } //save session String userID = null; String sessionID = null; try { userID = sessionProvider.getPrincipalName(ssoToken); sessionID = sessionProvider.getSessionID(ssoToken); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processPostAuthnSSO: " + "UserID of the principal in the session: " + userID + "sessionID of the session: " + sessionID); } } catch(SessionException ex){ FSUtils.debug.error("FSSSOAndFedHandler.processPostAuthnSSO: " + "SessionException occured. " + "Principal information not found in the session: ", ex); return false; } FSSessionManager sessionManager = FSSessionManager.getInstance(metaAlias); FSSession session = sessionManager.getSession(userID, sessionID); if (session != null){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.processPostAuthnSSO: " + "An existing SSO session found with ID:" + session.getSessionID()); } session.addSessionPartner( new FSSessionPartner(spEntityId, false)); sessionManager.addSession(userID, session); } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.processPostAuthnSSO: " + "No existing SSO session found. " + "Entering a new session to the session manager with ID: " + sessionID); } session = new FSSession(sessionID); String sessionIndex = SAMLUtils.generateID(); session.setSessionIndex(sessionIndex); session.addSessionPartner( new FSSessionPartner(spEntityId, false)); sessionManager.addSession(userID, session); } // check for federation String autoFedStr = IDFFMetaUtils.getFirstAttributeValueFromConfig( hostedConfig, IFSConstants.ENABLE_AUTO_FEDERATION); if (authnRequest.getFederate() || (autoFedStr != null && autoFedStr.equalsIgnoreCase("true"))) { FSAccountFedInfo fedInfo = doAccountFederation(ssoToken, authnRequest, session); NameIdentifier spNI = null; NameIdentifier idpNI = null; if(fedInfo == null){ FSUtils.debug.error("FSSSOAndFedHandler.processPostAuthnSSO: " + "Accountfederation failed"); return false; } else { spNI = fedInfo.getRemoteNameIdentifier(); idpNI = fedInfo.getLocalNameIdentifier(); if (idpNI == null){ idpNI = fedInfo.getRemoteNameIdentifier(); if (idpNI == null) { FSUtils.debug.error("FSSSOAndFedHandler.processPost" + "AuthnSSO: Opaque handle not found"); return false; } } if (spNI == null){ spNI = idpNI; } } return doSingleSignOn(ssoToken, authnRequest.getRequestID(), spNI, idpNI); } else { return doSingleSignOn(ssoToken, authnRequest.getRequestID()); } } protected FSAuthnResponse createAuthnResponse( Object ssoToken, String inResponseTo, NameIdentifier userHandle, NameIdentifier idpHandle) { FSUtils.debug.message( "FSSSOAndFedHandler.createAuthnResponse: Called"); FSAuthnResponse authnResponse = null; try { String requestID = authnRequest.getRequestID(); FSAssertionManager am = FSAssertionManager.getInstance(metaAlias); FSAssertion assertion = null; SessionProvider sessionProvider = SessionManager.getProvider(); assertion = am.createFSAssertion( sessionProvider.getSessionID(ssoToken), null, realm, spEntityId, userHandle, idpHandle, inResponseTo, authnRequest.getMinorVersion()); StatusCode statusCode = new StatusCode( IFSConstants.STATUS_CODE_SUCCESS); Status status = new Status(statusCode); List contents = new ArrayList(); contents.add(assertion); authnResponse = new FSAuthnResponse(null, requestID, status, contents, relayState); authnResponse.setMinorVersion(authnRequest.getMinorVersion()); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.createAuthnResponse: " + "CHECK1: " + hostedEntityId); } authnResponse.setProviderId(hostedEntityId); } catch(FSException se) { FSUtils.debug.error( "FSSSOAndFedHandler.createAuthnResponse: FSException: ", se); return null; } catch(SAMLException se) { FSUtils.debug.error("FSSSOAndFedHandler.createAuthnResponse: " + "SAMLException: ", se); return null; } catch (SessionException se) { FSUtils.debug.error("FSSSOAndFedHandler.createAuthnResponse: " + "SessionException: ", se); return null; } // sign AuthnResponse return authnResponse; } protected boolean doSingleSignOn( Object ssoToken, String inResponseTo, NameIdentifier spHandle, NameIdentifier idpHandle) { return false; } protected boolean doSingleSignOn( Object ssoToken, String inResponseTo) { FSUtils.debug.message("FSSSOAndFedHandler.doSingleSignOn(2): Called"); try { String securityDomain = authnRequest.getProviderId(); String affiliationID = authnRequest.getAffiliationID(); if (affiliationID != null) { securityDomain = affiliationID; } SessionProvider sessionProvider = SessionManager.getProvider(); String userID = sessionProvider.getPrincipalName(ssoToken); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.doSingleSignOn: " + "Initiating SSO for user with ID: " + userID); } FSAccountFedInfo accountInfo = accountManager.readAccountFedInfo( userID, securityDomain); if (accountInfo == null) { FSUtils.debug.error( "FSSSOAndFedHandler.doSingleSignOn: Account Federation " + "Information not found for user with ID: " + userID); noFedStatus = new Status( new StatusCode("samlp:Responder", new StatusCode("lib:FederationDoesNotExist", null)), FSUtils.bundle.getString("AuthnRequestProcessingFailed"), null); String[] data = { userID }; LogUtil.error(Level.INFO, LogUtil.USER_ACCOUNT_FEDERATION_INFO_NOT_FOUND, data, ssoToken); return false; } if (accountInfo != null && accountInfo.isFedStatusActive() && accountInfo.getLocalNameIdentifier() != null) { // Check if this is 6.2 NameIdentifier localNI = accountInfo.getLocalNameIdentifier(); String qualifier = localNI.getNameQualifier(); if (qualifier != null && qualifier.equals(hostedEntityId)) { localNI = new NameIdentifier( localNI.getName(), securityDomain); NameIdentifier remoteNI = accountInfo.getRemoteNameIdentifier(); if (remoteNI != null) { remoteNI = new NameIdentifier(remoteNI.getName(), securityDomain); } FSAccountFedInfoKey newFedKey = new FSAccountFedInfoKey( securityDomain, localNI.getName()); accountInfo = new FSAccountFedInfo( securityDomain, localNI, remoteNI, false); accountManager.writeAccountFedInfo( userID, newFedKey, accountInfo); FSAccountFedInfoKey oldFedKey = new FSAccountFedInfoKey( hostedEntityId, localNI.getName()); accountManager.removeAccountFedInfoKey(userID, oldFedKey); } } NameIdentifier idpNI = accountInfo.getLocalNameIdentifier(); if (idpNI == null){ idpNI = accountInfo.getRemoteNameIdentifier(); if (idpNI == null) { FSUtils.debug.error("FSSSOAndFedHandler.doSingleSignOn: " + "NameIdentifier not found"); return false; } } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.doSingleSignOn: " + "IDP generated opaque handle: " + idpNI.getName()); } } NameIdentifier spNI = accountInfo.getRemoteNameIdentifier(); if (spNI == null){ spNI = idpNI; } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.doSingleSignOn: " + "SP generated opaque handle: " + spNI.getName()); } } return doSingleSignOn(ssoToken, inResponseTo, spNI, idpNI); } catch(Exception e){ FSUtils.debug.error("FSSSOAndFedHandler.doSingleSignOn: " + "Exception during Single Sign-On:", e); return false; } } protected FSAccountFedInfo doAccountFederation( Object ssoToken, FSAuthnRequest authnRequest, FSSession session) { FSUtils.debug.message("FSSSOAndFedHandler.doAccountFederation: Called"); String nameIDPolicy = authnRequest.getNameIDPolicy(); String affiliationID = authnRequest.getAffiliationID(); boolean isAffiliationFed = false; if (affiliationID != null) { try { isAffiliationFed = metaManager.isAffiliateMember( realm, hostedEntityId, affiliationID); } catch (Exception e) { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.doAccount" + "Federation:Error in checking for the affiliation:", e); } } } try { SessionProvider sessionProvider = SessionManager.getProvider(); String userID = sessionProvider.getPrincipalName(ssoToken); FSAccountFedInfo existActInfo = null; if (isAffiliationFed) { existActInfo = accountManager.readAccountFedInfo( userID, affiliationID); if (existActInfo != null && existActInfo.isFedStatusActive()) { return existActInfo; } } // Check if there is an existing fed info String nameQualifier = authnRequest.getProviderId(); existActInfo = accountManager.readAccountFedInfo( userID, nameQualifier); if (existActInfo != null && existActInfo.isFedStatusActive()) { return existActInfo; } FSNameIdentifierHelper nameHelper = new FSNameIdentifierHelper(hostedConfig); String opaqueHandle = nameHelper.createNameIdentifier(); if (opaqueHandle == null){ FSUtils.debug.error("FSSSOAndFedHandler.doAccountFederation: " + "Could not generate handle"); return null; } if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.doAccountFederation: " + "Generated handle: " + opaqueHandle); } if (isAffiliationFed) { nameQualifier = affiliationID; } NameIdentifier ni = new NameIdentifier(opaqueHandle, nameQualifier); if (authnRequest.getMinorVersion() == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { if (nameIDPolicy == null || !nameIDPolicy.equals(IFSConstants.NAME_ID_POLICY_ONETIME)) { ni.setFormat(IFSConstants.NI_FEDERATED_FORMAT_URI); } else { ni.setFormat(IFSConstants.NI_ONETIME_FORMAT_URI); } } FSAccountFedInfo accountInfo = new FSAccountFedInfo( authnRequest.getProviderId(), ni, null, false); FSAccountFedInfoKey fedKey = null; if (isAffiliationFed) { fedKey = new FSAccountFedInfoKey(affiliationID, opaqueHandle); accountInfo.setAffiliation(true); } else { fedKey = new FSAccountFedInfoKey( authnRequest.getProviderId(), opaqueHandle); } if (nameIDPolicy == null || !nameIDPolicy.equals("onetime")) { accountManager.writeAccountFedInfo(userID, fedKey, accountInfo); } else { session.setOneTime(true); session.setAccountFedInfo(accountInfo); session.setUserID(userID); } return accountInfo; } catch(Exception ex){ FSUtils.debug.error("FSSSOAndFedHandler.doAccountFederation: " + "Exception when doing account federation", ex); return null; } } protected void returnErrorResponse() { } /** * Processes SAML request. * @param samlRequest FSSAMLRequest object * @return generated FSResponse object */ public FSResponse processSAMLRequest(FSSAMLRequest samlRequest) { FSUtils.debug.error("FSSSOAndFedHandler.processSAMLRequest: " + "Call should not resolve here, abstract class."); return null; } /** * Processes authentication request. * @param authnRequest authentication request * @param bPostAuthn true indicates it's post authentication; * false indicates it's pre authentication. */ public void processAuthnRequest( FSAuthnRequest authnRequest, boolean bPostAuthn ) { FSUtils.debug.message("FSSSOAndFedHandler.processAuthnRequest: Called"); this.authnRequest = authnRequest; String message = null; String inResponseTo = authnRequest.getRequestID(); Status status = null; FSAuthnResponse errResponse = null; spEntityId = authnRequest.getProviderId(); try { spDescriptor = metaManager.getSPDescriptor(realm, spEntityId); spConfig = metaManager.getSPDescriptorConfig(realm, spEntityId); if (!metaManager.isTrustedProvider( realm, hostedEntityId, spEntityId)) { FSUtils.debug.error( "FSSSOAndFedHandler.processAuthnRequest: " + "RemoteProvider is not trusted"); message = FSUtils.bundle.getString( "AuthnRequestProcessingFailed"); status = new Status( new StatusCode("samlp:Responder"), message, null); errResponse = new FSAuthnResponse(null, inResponseTo, status, null, relayState); errResponse.setMinorVersion( authnRequest.getMinorVersion()); sendAuthnResponse(errResponse); return; } if (bPostAuthn){ if (processPostAuthnSSO(authnRequest)){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler." + "processAuthnRequest: AuthnRequest Processing " + "successful"); } return; } else { if (FSUtils.debug.warningEnabled()) { FSUtils.debug.warning( "FSSSOAndFedHandler.processAuthnRequest: " + "AuthnRequest Processing failed"); } message = FSUtils.bundle.getString( "AuthnRequestProcessingFailed"); if (noFedStatus != null) { status = noFedStatus; } else { status = new Status( new StatusCode("samlp:Responder"), message, null); } errResponse = new FSAuthnResponse(null, inResponseTo, status, null, relayState); errResponse.setMinorVersion(authnRequest.getMinorVersion()); sendAuthnResponse(errResponse); return; } } else { boolean authnRequestSigned = spDescriptor.isAuthnRequestsSigned(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processAuthnRequest: " + "ProviderID : " + spEntityId + " AuthnRequestSigned :this is for testing " + authnRequestSigned); } if (FSServiceUtils.isSigningOn()){ if (authnRequestSigned){ //verify request signature if (!verifyRequestSignature(authnRequest)){ FSUtils.debug.error("FSSSOAndFedHandler." + "processAuthnRequest: " + "AuthnRequest Signature Verification Failed"); message = FSUtils.bundle.getString( "signatureVerificationFailed"); String[] data = { message }; LogUtil.error(Level.INFO, LogUtil.SIGNATURE_VERIFICATION_FAILED, data, ssoToken); status = new Status( new StatusCode("samlp:Responder", new StatusCode( "lib:UnsignedAuthnRequest", null)), message, null); errResponse = new FSAuthnResponse(null, inResponseTo, status, null, relayState); errResponse.setMinorVersion( authnRequest.getMinorVersion()); sendAuthnResponse(errResponse); return; } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler. processAuthnRequest" + ": AuthnRequest Signature Verified"); } } } } if (processPreAuthnSSO(authnRequest)){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.processAuthnRequest: " + "AuthnRequest Processing successful"); } return; } else { if (FSUtils.debug.warningEnabled()) { FSUtils.debug.warning( "FSSSOAndFedHandler.processAuthnRequest: " + "AuthnRequest Processing failed"); } String[] data = { FSUtils.bundle.getString( "AuthnRequestProcessingFailed") }; LogUtil.error(Level.INFO, LogUtil.AUTHN_REQUEST_PROCESSING_FAILED, data, ssoToken); message = FSUtils.bundle.getString( "AuthnRequestProcessingFailed"); status = new Status( new StatusCode("samlp:Responder"), message, null); if (noFedStatus != null) { status = noFedStatus; } errResponse = new FSAuthnResponse(null, inResponseTo, status, null, relayState); errResponse.setMinorVersion(authnRequest.getMinorVersion()); sendAuthnResponse(errResponse); return; } } } catch(Exception e){ ByteArrayOutputStream out = new ByteArrayOutputStream(); e.printStackTrace(new PrintStream(out)); FSUtils.debug.error("FSSSOAndFedHandler.processAuthnRequest: " + "Exception Occured: " + e.getMessage() + "Stack trace is " + out.toString()); message = FSUtils.bundle.getString("AuthnRequestProcessingFailed"); try { status = new Status( new StatusCode("samlp:Responder"), message, null); errResponse = new FSAuthnResponse(null, inResponseTo, status, null, relayState); errResponse.setMinorVersion(authnRequest.getMinorVersion()); sendAuthnResponse(errResponse); } catch(Exception ex){ if (FSUtils.debug.messageEnabled()){ FSUtils.debug.message( "FSSSOAndFedHandler.processAuthnRequest: " + "Exception Occured: ", ex); } } } } protected void sendAuthnResponse( FSAuthnResponse authnResponse ) { FSUtils.debug.error("FSSSOAndFedHandler.sendAuthnResponse: " + "Call should not resolve here. error"); } /** * Sets remote SP provider descriptor. * @param spDescriptor remote SP provider descriptor. * @see #getProvider() */ public void setSPDescriptor(SPDescriptorType spDescriptor) { this.spDescriptor = spDescriptor; } /** * Returns remote SP provider descriptor. * * @return remote SP provider descriptor */ public SPDescriptorType getProvider() { return spDescriptor; } protected boolean verifyRequestSignature(FSAuthnRequest authnRequest) { FSUtils.debug.message( "FSSSOAndFedHandler.verifyRequestSignature: Called"); try { X509Certificate cert = KeyUtil.getVerificationCert( spDescriptor, spEntityId, false); if (cert == null) { if(FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.verifyRequestSignature: " + "couldn't obtain this site's cert."); } throw new FSException(IFSConstants.NO_CERT, null); } if (request.getMethod().equals("GET")){ if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.verifyRequestSignature: " + "Request is sent by GET" ); } String sigAlg = request.getParameter("SigAlg"); String encSig = request.getParameter("Signature"); if (sigAlg == null || sigAlg.length() == 0 || encSig == null || encSig.length() == 0) { return false; } String algoId = null; if (sigAlg.equals(IFSConstants.ALGO_ID_SIGNATURE_DSA)) { algoId = IFSConstants.ALGO_ID_SIGNATURE_DSA_JCA; } else if (sigAlg.equals(IFSConstants.ALGO_ID_SIGNATURE_RSA)) { algoId = IFSConstants.ALGO_ID_SIGNATURE_RSA_JCA; } else { FSUtils.debug.error( "FSSSOAndFedHandler.signAndReturnQueryString: " + "Invalid signature algorithim"); return false; } String queryString = request.getQueryString(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.verifyRequest" + "Signature: queryString:" + queryString); } int sigIndex = queryString.indexOf("&Signature"); String newQueryString = queryString.substring(0, sigIndex); byte[] signature = null; if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.verifyRequestSignature: " + "Signature: " + encSig + "Algorithm: " + algoId); } signature = Base64.decode(encSig); FSSignatureManager fsmanager = FSSignatureManager.getInstance(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.verifyRequestSignature: " + "String to be verified: " + newQueryString); } return fsmanager.verifySignature(newQueryString, signature, algoId, cert); } else { if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message( "FSSSOAndFedHandler.verifyRequestSignature: " + "Request is sent by POST "); } int minorVersion=authnRequest.getMinorVersion(); if (minorVersion == IFSConstants.FF_11_PROTOCOL_MINOR_VERSION) { return SigManager.getSigInstance().verify( authnRequest.getSignedXMLString(), IFSConstants.ID, Collections.singleton(cert)); } else if (minorVersion == IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { return SigManager.getSigInstance().verify( authnRequest.getSignedXMLString(), IFSConstants.REQUEST_ID, Collections.singleton(cert)); } else { FSUtils.debug.message("invalid minor version."); return false; } } } catch(Exception e){ FSUtils.debug.error("FSSSOAndFedHandler.verifyRequestSignature: " + "Exception occured while verifying SP's signature:", e); return false; } } /** * Removes meta alias from request parameters. * @param request HttpServletRequest object * @return parameter string which doesn't contain meta alias */ public static String cleanMetaAlias(HttpServletRequest request) { FSUtils.debug.message("FSSSOAndFedHandler.cleanMetaAlias: Called"); Enumeration paramEnum = request.getParameterNames(); String returnString = new String(); while (paramEnum.hasMoreElements()) { String paramKey = (String)paramEnum.nextElement(); if (paramKey.equalsIgnoreCase(IFSConstants.META_ALIAS)) { FSUtils.debug.message( "FSSSOAndFedHandler.cleanMetaAlias: found metaAlias"); } else { String paramValue = request.getParameter(paramKey); if (returnString == null || returnString.length() < 1) { returnString = paramKey + "=" + URLEncDec.encode(paramValue); } else { returnString = returnString + "&" + paramKey + "=" + URLEncDec.encode(paramValue); } } } if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.cleanMetaAlias: " + " returning with " + returnString); } return returnString; } /** * Sends a new AuthnRequest to the authenticating provider. * @param authnRequest original AuthnRequest sent by the service provider. * @param preferredIDP IDP to be proxied. * @exception FSException for any federation failure. * @exception IOException if there is a failure in redirection. */ protected void sendProxyAuthnRequest ( FSAuthnRequest authnRequest, String preferredIDP ) throws FSException, IOException { FSAuthnRequest newAuthnRequest = getNewAuthnRequest(authnRequest); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.sendProxyAuthnRequest:" + "New Authentication request:" + newAuthnRequest.toXMLString()); } FSSessionManager sessManager = FSSessionManager.getInstance( IDFFMetaUtils.getMetaAlias( realm, hostedEntityId, IFSConstants.SP, null)); String requestID = newAuthnRequest.getRequestID(); sessManager.setAuthnRequest(requestID, newAuthnRequest); sessManager.setProxySPDescriptor(requestID, spDescriptor); sessManager.setProxySPAuthnRequest(requestID, authnRequest); sessManager.setIDPEntityID(requestID, preferredIDP); String targetURL = null; SPDescriptorType localDescriptor = null; BaseConfigType localDescriptorConfig = null; try { IDPDescriptorType idpDescriptor = metaManager.getIDPDescriptor(realm, preferredIDP); targetURL = idpDescriptor.getSingleSignOnServiceURL(); if (targetURL == null) { FSUtils.debug.error( "FSSSOAndFedHandler.sendProxyAuthnRequest: Single " + "Sign-on service is not found for the proxying IDP"); return; } localDescriptor = metaManager.getSPDescriptor( realm, hostedEntityId); localDescriptorConfig = metaManager.getSPDescriptorConfig(realm, hostedEntityId); } catch (Exception e) { FSUtils.debug.error( "FSSSOAndFedHandler.sendProxyAuthnRequest:",e); return; } String queryString = newAuthnRequest.toURLEncodedQueryString(); if (FSServiceUtils.isSigningOn()) { String certAlias = IDFFMetaUtils.getFirstAttributeValueFromConfig( localDescriptorConfig, IFSConstants.SIGNING_CERT_ALIAS); if (localDescriptor.isAuthnRequestsSigned()) { queryString = FSSignatureUtil.signAndReturnQueryString( queryString, certAlias); } } StringBuffer tmpURL = new StringBuffer(1000); if (targetURL.indexOf("?") != -1) { tmpURL.append(targetURL).append("&").append(queryString); } else { tmpURL.append(targetURL).append("?").append(queryString); } String redirectURL = tmpURL.toString(); if (FSUtils.debug.messageEnabled()) { FSUtils.debug.message("FSSSOAndFedHandler.sendProxyAuthnRequest:" + "SSO URL to be redirected" + redirectURL); } response.setStatus(response.SC_MOVED_TEMPORARILY); response.setHeader("Location", redirectURL); response.sendRedirect(redirectURL); } /** * Checks if the identity provider is configured for proxying the * authentication requests for a requesting service provider. * @param authnRequest Authentication Request. * @return true if the IDP is configured for proxying. * @exception FSException for any failure. */ protected boolean isIDPProxyEnabled(FSAuthnRequest authnRequest) throws FSException { if (authnRequest.getMinorVersion() != IFSConstants.FF_12_PROTOCOL_MINOR_VERSION) { return false; } FSScoping scoping = authnRequest.getScoping(); if (scoping != null && scoping.getProxyCount() == 0) { return false; } String enabledString = IDFFMetaUtils.getFirstAttributeValueFromConfig( spConfig, IFSConstants.ENABLE_IDP_PROXY); if (enabledString != null && enabledString.equalsIgnoreCase("true")) { return true; } else { return false; } } /** * Gets the preferred IDP Id to be proxied. This method makes use of an * SPI to determine the preffered IDP. * @param authnRequest original Authn Request. * @return String preferred IDP to be proxied. */ private String getPreferredIDP(FSAuthnRequest authnRequest) throws FSRedirectException { if (realmProxyFinder != null) { return realmProxyFinder.getPreferredIDP( authnRequest, realm, hostedEntityId, request, response); } else { return proxyFinder.getPreferredIDP( authnRequest, hostedEntityId, request, response); } } /** * Constructs new authentication request by using the original request * that is sent by the service provider to the proxying IDP. * @param origRequest Original Authn Request * @return FSAuthnRequest new authn request. * @exception FSException for failure in creating new authn request. */ private FSAuthnRequest getNewAuthnRequest( FSAuthnRequest origRequest ) throws FSException { // New Authentication request should only be a single sign-on request. try { FSAuthnRequest newRequest = new FSAuthnRequest(null, origRequest.getRespondWith(), hostedEntityId, origRequest.getForceAuthn(), origRequest.getIsPassive(), false, origRequest.getNameIDPolicy(), origRequest.getProtocolProfile(), origRequest.getAuthnContext(), origRequest.getRelayState(), origRequest.getAuthContextCompType()); newRequest.setMinorVersion( IFSConstants.FF_12_PROTOCOL_MINOR_VERSION); FSScoping scoping = origRequest.getScoping(); if (scoping != null) { int proxyCount = scoping.getProxyCount(); if (proxyCount > 0 ) { FSScoping newScoping = new FSScoping(); newScoping.setProxyCount(proxyCount-1); newScoping.setIDPList(scoping.getIDPList()); newRequest.setScoping(newScoping); } } return newRequest; } catch (Exception ex) { FSUtils.debug.error("FSSSOAndFedHandler.getNewAuthnRequest:" + "Error in creating new authn request.", ex); throw new FSException(ex); } } }