IDPSSOUtil.java revision ae5b5bc4ad012cbc81b9b4da033d316138f18391
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * of the Common Development and Distribution License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * (the License). You may not use this file except in
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You can obtain a copy of the License at
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * permission and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Header Notice in each file and include the License file
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below the CDDL Header,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * with the fields enclosed by brackets [] replaced by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * your own identifying information:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * $Id: IDPSSOUtil.java,v 1.56 2009/11/24 21:53:28 madan_ranganath Exp $
ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpotts * Portions Copyrighted 2010-2016 ForgeRock AS.
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura * Portions Copyrighted 2013 Nomura Research Institute, Ltd
ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpottsimport static org.forgerock.openam.utils.Time.*;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.AccountUtils;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.NameIDInfo;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.NewBoolean;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2Constants;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2Exception;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2FailoverUtils;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2Utils;
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbingsimport com.sun.identity.saml2.common.SOAPCommunicator;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.encode.URLEncDec;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.cot.CircleOfTrustManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.cot.CircleOfTrustDescriptor;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.multiprotocol.MultiProtocolUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.multiprotocol.SingleLogoutManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.xmlsig.KeyProvider;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.Assertion;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.AssertionFactory;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.Attribute;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.AttributeStatement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.AudienceRestriction;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.AuthnContext;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.AuthnStatement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.Conditions;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.EncryptedAssertion;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.EncryptedAttribute;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.EncryptedID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.Subject;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.SubjectConfirmation;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.SubjectConfirmationData;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.idpdiscovery.IDPDiscoveryConstants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.jaxb.entityconfig.IDPSSOConfigElement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.jaxb.metadata.AffiliationDescriptorType;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.jaxb.metadata.ArtifactResolutionServiceElement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.jaxb.metadata.AssertionConsumerServiceElement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.meta.SAML2MetaException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.meta.SAML2MetaManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.meta.SAML2MetaUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.plugins.IDPAccountMapper;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.plugins.IDPAttributeMapper;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.plugins.IDPAuthnContextInfo;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.plugins.IDPAuthnContextMapper;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.plugins.IDPECPSessionMapper;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.Artifact;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.AuthnRequest;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.NameIDPolicy;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.ProtocolFactory;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.Response;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.StatusCode;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.monitoring.FedMonAgent;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.monitoring.FedMonSAML2Svc;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.monitoring.MonitorManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionProvider;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.plugins.SAML2IdentityProviderAdapter;
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeperimport org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException;
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Lunaimport org.forgerock.openam.saml2.audit.SAML2EventLogger;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * The utility class is used by the identity provider to process
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the authentication request from a service provider and send back
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * a proper response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The identity provider can also send unsolicited response to a service
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * provider to do single sign on and/or federation.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // key name for name id format on SSOToken
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static final String NAMEID_FORMAT = "SAML2NameIDFormat";
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major private static final String REDIRECTED = "redirected";
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major private static final String REDIRECTED_TRUE = "redirected=true";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static SAML2MetaManager metaManager = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static CircleOfTrustManager cotManager = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static IDPSessionListener sessionListener = new IDPSessionListener();
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error("Error retrieving circle of trust");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error("Error retrieving metadata", sme);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionProvider = SessionManager.getProvider();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "IDPSSOUtil static block: Error getting SessionProvider.",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Does SSO with existing federation or new federation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * @param out the print writer for writing out presentation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpMetaAlias the meta alias of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param relayState the relay state
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna * @param auditor the auditor for logging SAML2 Events - may be null
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void doSSOFederate(HttpServletRequest request,
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest doSSOFederate(request, response, out, authnReq,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Does SSO with existing federation or new federation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * @param out the print writer for writing out presentation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpMetaAlias the meta alias of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param relayState the relay state
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param newSession Session used in IDP Proxy Case
dba874fb22099c605a3accab4c26632208dfa15aJon Thomas * @param auditor the auditor for logging SAML2 Events
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void doSSOFederate(HttpServletRequest request,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.doSSOFederate: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // log the authnRequest
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {spEntityID, idpMetaAlias, authnRequestStr};
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.RECEIVED_AUTHN_REQUEST, logdata, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // retrieve IDP entity id from meta alias
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get meta manager.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorMetaManager"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpEntityID = metaManager.getEntityByMetaAlias(idpMetaAlias);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get IDP Entity ID from meta.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster realm = SAML2MetaUtils.getRealmByMetaAlias(idpMetaAlias);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get IDP Entity ID from meta.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // check if the remote provider is valid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Issuer issuer = AssertionFactory.getInstance().createIssuer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!SAML2Utils.isSourceSiteValid(issuer, realm, idpEntityID)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "The remote provider is not valid.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidReceiver"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // Validate the RelayState URL.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (authnReq == null && (session == null || !isValidSessionInRealm(realm, session))) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // idp initiated and not logged in yet, need to authenticate
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (Boolean.parseBoolean(request.getParameter(REDIRECTED))) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.error(classMethod + "The IdP was not able to create a session");
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major LogUtil.error(Level.INFO, LogUtil.SSO_NOT_FOUND, data, session, null);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String ipAddress = ClientUtils.getClientIPAddress(request);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String sessionRealm = SAML2Utils.getSingleValuedSessionProperty(session,
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String[] data = {sessionRealm, realm, spEntityID, ipAddress, null};
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.error(classMethod + "The realm of the session (" + sessionRealm
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major + ") does not correspond to that of the IdP (" + realm + ")");
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major LogUtil.error(Level.INFO, LogUtil.INVALID_REALM_FOR_SESSION, data, session, null);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.error(classMethod + "Failed to retrieve realm from session", se);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, rbKey,
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major redirectAuthentication(request, response, authnReq, null, realm, idpEntityID, spEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "UnableToRedirectToAuth",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableToRedirectToAuth"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Invoke the IDP Adapter
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + " Invoking the "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "IDP Adapter");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPSSOUtil.getIDPAdapterClass(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // If the preSendResponse returns true we end here
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpAdapter.preSendResponse(authnReq, idpEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster realm, request, response, session, null, relayState)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } // else we continue with the logic. Beware of loops
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod + " There was a problem when invoking"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "the preSendResponse of the IDP Adapter: ", se2);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // End of invocation
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest sendResponseToACS(request, response, out, session, authnReq, spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpEntityID, idpMetaAlias, realm, nameIDFormat, relayState, null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Sends <code>Response</code> containing an <code>Assertion</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * back to the requesting service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * @param out the print writer for writing out presentation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param session user session
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpMetaAlias the meta alias of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param relayState the relay state
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param matchingAuthnContext the <code>AuthnContext</code> used to find
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * authentication type and scheme.
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public static void sendResponseToACS(HttpServletRequest request, HttpServletResponse response, PrintWriter out,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID, String idpEntityID, String idpMetaAlias,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm, String nameIDFormat, String relayState,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer returnedBinding = new StringBuffer();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major spEntityID, realm, authnReq, request, returnedBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acsBinding = returnedBinding.toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((acsURL == null) || (acsURL.trim().length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " no ACS URL found.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableTofindACSURL"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((acsBinding == null) || (acsBinding.trim().length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " no return binding found.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableTofindBinding"));
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major //check first if there is already an existing sessionindex associated with this SSOToken, if there is, then
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major //we need to redirect the request internally to the holder of the idpsession.
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major //The remoteServiceURL will be null if there is no sessionindex for this SSOToken, or there is, but it's
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major //local. If the remoteServiceURL is not null, we can start to send the request to the original server.
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major String remoteServiceURL = SAML2Utils.getRemoteServiceURL(getSessionIndex(session));
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major remoteServiceURL += SAML2Utils.removeDeployUri(request.getRequestURI()) + "?" + request.getQueryString();
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major SAML2Utils.debug.message("SessionIndex for this SSOToken is not local, forwarding the request to: "
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major SAML2Utils.sendRequestToOrigServer(request, response, remoteServiceURL);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major if (remoteRequestData != null && !remoteRequestData.isEmpty()) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major redirectUrl = remoteRequestData.get(SAML2Constants.AM_REDIRECT_URL);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major outputData = remoteRequestData.get(SAML2Constants.OUTPUT_DATA);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major responseCode = remoteRequestData.get(SAML2Constants.RESPONSE_CODE);
21d0d4af5fb4901318c27899c412bfe1e01763d7Sam Fraser if (redirectUrl != null && !redirectUrl.isEmpty()) {
21d0d4af5fb4901318c27899c412bfe1e01763d7Sam Fraser response.setStatus(Integer.valueOf(responseCode));
21d0d4af5fb4901318c27899c412bfe1e01763d7Sam Fraser // no redirect, perhaps an error page, return the content
21d0d4af5fb4901318c27899c412bfe1e01763d7Sam Fraser if (outputData != null && !outputData.isEmpty()) {
21d0d4af5fb4901318c27899c412bfe1e01763d7Sam Fraser SAML2Utils.debug.message("Printing the forwarded response");
21d0d4af5fb4901318c27899c412bfe1e01763d7Sam Fraser response.setContentType("text/html; charset=UTF-8");
21d0d4af5fb4901318c27899c412bfe1e01763d7Sam Fraser SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS() error in Request Routing", ioe);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major //end of request proxy
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // generate a response for the authn request
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major Response res = getResponse(request, session, authnReq, spEntityID, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpMetaAlias, realm, nameIDFormat, acsURL, affiliationID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " response is null");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableToCreateAssertion");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster //idp initiated case, will not send error response to sp
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.RESPONDER, null, errorMsg, idpEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, SAML2Constants.IDP_META_ALIAS, values);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " error setting idpMetaAlias into the session: ", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // call multi-federation protocol to set the protocol
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MultiProtocolUtils.addFederationProtocol(session,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // check if the COT cookie needs to be set
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (setCOTCookie(request, response, acsBinding, spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpEntityID, idpMetaAlias, realm, relayState, acsURL, res,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " Redirected to set COT cookie.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " Doesn't set COT cookie.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS:" +
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS: Invoking the IDP Adapter");
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major SAML2IdentityProviderAdapter idpAdapter = IDPSSOUtil.getIDPAdapterClass(realm, idpEntityID);
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major idpAdapter.preSignResponse(authnReq, res, idpEntityID, realm, request, session, relayState);
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS: There was a problem when invoking the "
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper sendResponse(request, response, out, acsBinding, spEntityID, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpMetaAlias, realm, relayState, acsURL, res, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " error response is null");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableToCreateErrorResponse"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static boolean setCOTCookie(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.setCOTCookie: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String writerURL = getWriterURL(realm, idpEntityID, spEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // could not find the writer URL, do not set the COT cookie
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // save the needed info into cache so they can be used later
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // when it is redirected back
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String cachedResID = SAML2Utils.generateIDWithServerID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.responseCache.put(cachedResID, cacheList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // construct redirect URL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster retURLSB.append(request.getScheme()).append("://")
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String retURL = URLEncDec.encode(retURLSB.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer redirectURLSB = new StringBuffer(200);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster redirectURLSB.append(IDPDiscoveryConstants.SAML2_COOKIE_NAME)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam * A convenience method to construct response with First-level and Second-level status code for
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam * SAML authentication requests.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param request The servlet request.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param response The servlet response.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param out The print writer for writing out presentation.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param idpMetaAlias The IdP's metaAlias.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param idpEntityID The IdP's entity ID.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param realm The realm where the IdP belongs to.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param authnReq The SAML AuthnRequest sent by the SP.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param relayState The RelayState value.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param spEntityID The SP's entity ID.
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam * @param firstlevelStatusCodeValue First-level status code value passed.
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam * @param secondlevelStatusCodeValue Second-level status code value passed.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @throws SAML2Exception If there was an error while creating or sending the response back to the SP.
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam public static void sendResponseWithStatus(HttpServletRequest request, HttpServletResponse response,
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam PrintWriter out, String idpMetaAlias, String idpEntityID,
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam String realm, AuthnRequest authnReq, String relayState,
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam String spEntityID, String firstlevelStatusCodeValue,
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam String secondlevelStatusCodeValue) throws SAML2Exception {
94c4282963f7db4f8703c196fecb5826a6c9b729Kamal Sivanandam Response res = SAML2Utils.getErrorResponse(authnReq, firstlevelStatusCodeValue, secondlevelStatusCodeValue,
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major StringBuffer returnedBinding = new StringBuffer();
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major String acsURL = IDPSSOUtil.getACSurl(spEntityID, realm, authnReq, request, returnedBinding);
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper sendResponse(request, response, out, acsBinding, spEntityID, idpEntityID, idpMetaAlias, realm, relayState,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Sends a response to service provider
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param request The servlet request.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param response The servlet response.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param out The print writer for writing out presentation.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param cachedResID the key used to retrieve response information
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * from the response information cache
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponse(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.sendResponse: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (ArrayList) IDPCache.responseCache.remove(cachedResID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((cacheList != null) && (cacheList.size() == 9)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpMetaAlias = (String) cacheList.get(3);
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper sendResponse(request, response, out, acsBinding, spEntityID, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpMetaAlias, realm, relayState, acsURL, res, session);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "unable to get response information from cache.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "UnableToGetResponseInfoFromCache"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Sends a response to service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsBinding the assertion consumer service binding
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpMetaAlias the meta alias of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param relayState the relay state
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the assertion consumer service <code>url</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param res the <code>SAML Response</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponse(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.sendResponse: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String nameIDString = SAML2Utils.getNameIDStringFromResponse(res);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // send the response back through HTTP POST or Artifact
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas if (acsBinding.equals(SAML2Constants.HTTP_POST)) {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // 4.1.4.5 POST-Specific Processing Rules (sstc-saml-profiles-errata-2.0-wd-06-diff.pdf)
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas //If response is not signed and POST binding is used, the assertion(s) MUST be signed.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // encryption is optional based on SP config settings.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas boolean signAssertion = true;
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // check if response needs to be signed.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas boolean signResponse = SAML2Utils.wantPOSTResponseSigned(realm, spEntityID, SAML2Constants.SP_ROLE);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // if signing response then signing assertion is optional
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // so will base on wantAssertionsSigned flag
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas signAssertion = wantAssertionsSigned(spEntityID, realm);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas signAndEncryptResponseComponents(realm, spEntityID, idpEntityID, res, signAssertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String encodedResMsg = SAML2Utils.encodeForPOST(resMsg);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata1 = {spEntityID, idpMetaAlias, resMsg};
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.POST_RESPONSE, logdata1, session, props);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest SAML2Utils.postToTarget(request, response, "SAMLResponse",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encodedResMsg, "RelayState", relayState, acsURL);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest LogUtil.error(Level.INFO, LogUtil.POST_TO_TARGET_FAILED, data, session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (acsBinding.equals(SAML2Constants.HTTP_ARTIFACT)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPSSOUtil.sendResponseArtifact(request, response, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major spEntityID, realm, acsURL, relayState, res, session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if (acsBinding.equals(SAML2Constants.PAOS)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // signing assertion is a must for ECP profile.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // encryption is optional based on SP config settings.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper IDPSSOUtil.sendResponseECP(request, response, out, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "unsupported return binding.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnSupportedReturnBinding"));
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * Returns a <code>SAML Response</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param request The HTTP request.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param session The user's session object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param authnReq The <code>AuthnRequest</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param recipientEntityID The entity ID of the response recipient.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param idpEntityID The entity ID of the identity provider.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param realm The realm name.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param nameIDFormat The <code>NameIDFormat</code>.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param acsURL The <code>ACS</code> service <code>url</code>.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param affiliationID AffiliationID for IDP initiated SSO.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param matchingAuthnContext the <code>AuthnContext</code> used to find authentication type and scheme.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @return the <code>SAML Response</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @throws SAML2Exception if the operation is not successful.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getResponse: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Response res = ProtocolFactory.getInstance().createResponse();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Status status = ProtocolFactory.getInstance().createStatus();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StatusCode statusCode = ProtocolFactory.getInstance().
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major Assertion assertion = getAssertion(request, session, authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major recipientEntityID, idpEntityID, idpMetaAlias, realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major nameIDFormat, acsURL, affiliationID, matchingAuthnContext);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SAML2InvalidNameIDPolicyException se) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StatusCode subStatusCode = ProtocolFactory.getInstance().
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster subStatusCode.setValue(SAML2Constants.INVALID_NAME_ID_POLICY);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // sp initiated case, need to set InResponseTo attribute
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // set the idp entity id as the response issuer
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Issuer issuer = AssertionFactory.getInstance().createIssuer();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major res.setDestination(XMLUtils.escapeSpecialCharacters(acsURL));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML Assertion</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param request The HTTP request.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param session The user's session object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param authnReq The <code>AuthnRequest</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param recipientEntityID The entity ID of the response recipient.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param idpEntityID The entity ID of the identity provider.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param realm The realm name.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param nameIDFormat The <code>NameIDFormat</code>.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param acsURL The <code>ACS</code> service <code>url</code>.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param affiliationID AffiliationID for IDP initiated SSO.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param matchingAuthnContext the <code>AuthnContext</code> used to find authentication type and scheme.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @return the <code>SAML Assertion</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @throws SAML2Exception if the operation is not successful.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getAssertion: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Assertion assertion = AssertionFactory.getInstance().createAssertion();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setVersion(SAML2Constants.VERSION_2_0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Issuer issuer = AssertionFactory.getInstance().createIssuer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NewBoolean isNewSessionIndex = new NewBoolean();
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura String sessionID = sessionProvider.getSessionID(session);
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura synchronized (sessionID) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authnStatement = getAuthnStatement(request, session, isNewSessionIndex, authnReq, idpEntityID, realm,
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura sessionIndex = authnStatement.getSessionIndex();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "This is a new IDP session with sessionIndex=" +
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura idpSession = (IDPSession) IDPCache.idpSessionsBySessionID.
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura // Set the metaAlias in the IDP session object
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura IDPCache.idpSessionsByIndices.put(sessionIndex, idpSession);
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura idpSession = (IDPSession)IDPCache.idpSessionsByIndices.
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura "a new IDP session has been saved in cache, " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionProvider.addListener(session, sessionListener);
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura "Unable to add session listener.");
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (idpSession == null && SAML2FailoverUtils.isSAML2FailoverEnabled()) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper // Read from SAML2 Token Repository
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper idpSessionCopy = (IDPSessionCopy) SAML2FailoverUtils.retrieveSAML2Token(sessionIndex);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper "Unable to obtain IDPSessionCopy from the SAML2 Token Repository for sessionIndex:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Copy back to IDPSession
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSessionCopy is null");
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura SAML2Utils.bundle.getString("IDPSessionIsNULL"));
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper (!SAML2FailoverUtils.isSAML2FailoverEnabled())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSession is null; SAML2 failover" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "is disabled");
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura SAML2Utils.bundle.getString("IDPSessionIsNULL"));
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura "This is an existing IDP session with sessionIndex="
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura sessionProvider.getSessionID(idpSession.getSession()));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AttributeStatement attrStatement = getAttributeStatement(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, idpEntityID, recipientEntityID, realm);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major assertion.setAttributeStatements(attrStatementList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the assertion effective time (in seconds)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int effectiveTime = getEffectiveTime(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the NotBefore skew (in seconds)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int notBeforeSkewTime = getNotBeforeSkewTime(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the subject element
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Subject subject = getSubject(session, authnReq, acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major recipientEntityID, effectiveTime, affiliationID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // register (spEntityID, nameID) with the sso token
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // for later logout use
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major NameIDandSPpair pair = new NameIDandSPpair(subject.getNameID(), spEntityID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major List<NameIDandSPpair> list = idpSession.getNameIDandSPpairs();
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major boolean found = false;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (nameIDandSPpair.getSPEntityID().equals(id)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Conditions conditions = getConditions(recipientEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String discoBootstrapEnabled = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID, SAML2Constants.DISCO_BOOTSTRAPPING_ENABLED);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major discoBootstrapEnabled.equalsIgnoreCase("true")) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List attrStatementList = assertion.getAttributeStatements();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setAttributeStatements(attrStatementList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DiscoveryBootstrap bootstrap = new DiscoveryBootstrap(session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major authnStatement.getAuthnContext().getAuthnContextClassRef(),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attrStatementList.add(bootstrap.getBootstrapStatement());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setAdvice(bootstrap.getCredentials());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (assertionCacheEnabled(realm, idpEntityID)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster userName = sessionProvider.getPrincipalName(session);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get principal name from the session.", se);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidSSOToken"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major List assertions = (List) IDPCache.assertionCache.get(cacheKey);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major assertions = (List) IDPCache.assertionCache.get(cacheKey);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.assertionCache.put(cacheKey, assertions);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster synchronized (assertions) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.assertionByIDCache.put(assertionID, assertion);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2FailoverUtils.saveSAML2Token(assertionID, cacheKey,
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper conditions.getNotOnOrAfter().getTime() / 1000);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper "Saving Assertion to SAML2 Token Repository. ID = " + assertionID);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod + "Unable to save Assertion to the SAML2 Token Repository", se);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper // Save to SAML2 Token Repository
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
ccf9d4a5c6453fa9f8b839baeee25147865fbb7dJames Phillpotts long sessionExpireTime = currentTimeMillis() / 1000 + (sessionProvider.getTimeLeft(session));
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper SAML2FailoverUtils.saveSAML2TokenWithoutSecondaryKey(sessionIndex, new IDPSessionCopy(idpSession),
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.message(classMethod + "SAVE IDPSession!");
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod + "Unable to get left-time from the session.", se);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod + "Unable to save IDPSession to the SAML2 Token Repository", se);
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * Returns a <code>SAML AuthnStatement</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param request The HTTP request.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param session The user's session.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param isNewSessionIndex A returned flag from which the caller knows if the session index in the returned
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * <code>AuthnStatement</code> is a new session index.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param authnReq The <code>AuthnRequest</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param idpEntityID The entity ID of the identity provider.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param realm The realm name.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param matchingAuthnContext The <code>AuthnContext</code> used to find authentication type and scheme.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @return The <code>SAML AuthnStatement</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @throws SAML2Exception If the operation is not successful.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static AuthnStatement getAuthnStatement(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getAuthnStatement: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AssertionFactory.getInstance().createAuthnStatement();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // will be used when we add SubjectLocality to the statement
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authInstant = DateUtils.stringToDate(values[0]);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "exception retrieving info from the session: ", e);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AuthnContext authnContext = matchingAuthnContext;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "exception retrieving auth level info from the session: ",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAuthnContextMapper.getAuthnContextFromAuthLevel(
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final Response idpResponse = (Response) request.getAttribute(SAML2Constants.SAML_PROXY_IDP_RESPONSE_KEY);
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major // IdP proxy case: we already received an assertion from the remote IdP and now the IdP proxy is generating
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major // a new SAML response for the SP.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major Set<String> authenticatingAuthorities = new LinkedHashSet<String>();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final List<Assertion> assertions = idpResponse.getAssertion();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authenticatingAuthorities.addAll(extractAuthenticatingAuthorities(assertion));
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major // According to SAML profile 4.1.4.2 each assertion within the SAML Response MUST have the same issuer, so
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major // this should suffice. We should have at least one assertion, since the IdP proxy's SP already accepted it.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authenticatingAuthorities.add(assertions.iterator().next().getIssuer().getValue());
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authnContext.setAuthenticatingAuthority(new ArrayList<String>(authenticatingAuthorities));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String sessionIndex = getSessionIndex(session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (sessionIndex == null) { // new sessionIndex
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionIndex = SAML2Utils.generateIDWithServerID();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "error setting session index into the session: ", e);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "SessionIndex (in AuthnStatement) =" + sessionIndex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authContextSet == null || authContextSet.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // cache the AuthContext to use in the case of session upgrade.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPCache.authnContextCache.put(sessionIndex, authContextSet);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML AttributeStatement</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param session the user's session
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param recipientEntityID the entity id of the response recipient
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML AttributeStatement</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static AttributeStatement getAttributeStatement(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, idpEntityID, recipientEntityID, realm);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((attributes == null) || (attributes.isEmpty())) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AssertionFactory.getInstance().createAttributeStatement();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns an <code>IDPAttributeMapper</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID the entity id of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>IDPAttributeMapper</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static IDPAttributeMapper getIDPAttributeMapper(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getIDPAttributeMapper: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAttributeMapperName = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID, SAML2Constants.IDP_ATTRIBUTE_MAPPER);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_ATTRIBUTE_MAPPER_CLASS;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_ATTRIBUTE_MAPPER_CLASS);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Class.forName(idpAttributeMapperName).newInstance();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got the IDPAttributeMapper from cache");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns an <code>IDPAuthnContextMapper</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID the entity id of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>IDPAuthnContextMapper</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings public static IDPAuthnContextMapper getIDPAuthnContextMapper(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getIDPAuthnContextMapper: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPAuthnContextMapper idpAuthnContextMapper = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAuthnContextMapperName = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_AUTHNCONTEXT_MAPPER_CLASS;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_AUTHNCONTEXT_MAPPER_CLASS);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAuthnContextMapper = (IDPAuthnContextMapper)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAuthnContextMapper = (IDPAuthnContextMapper)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Class.forName(idpAuthnContextMapperName).newInstance();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAuthnContextMapperName, idpAuthnContextMapper);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got the IDPAuthnContextMapper from cache");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns an <code>IDPECPSessionMapper</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID the entity id of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>IDPECPSessionMapper</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings public static IDPECPSessionMapper getIDPECPSessionMapper(String realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPECPSessionMapper idpECPSessionMapper = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpECPSessionMapperName = getAttributeValueFromIDPSSOConfig(realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpEntityID, SAML2Constants.IDP_ECP_SESSION_MAPPER_CLASS);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_ECP_SESSION_MAPPER_CLASS;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "IDPSSOUtil.getIDPECPSessionMapper: use " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_ECP_SESSION_MAPPER_CLASS);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Class.forName(idpECPSessionMapperName).newInstance();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "IDPSSOUtil.getIDPECPSessionMapper: " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got the IDPECPSessionMapper from cache");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.getIDPECPSessionMapper: " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML Subject</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param session the user's session
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the <code>ACS</code> service <code>url</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm The realm name
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param recipientEntityID the entity id of the response recipient
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param effectiveTime the effective time of the assertion
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param affiliationID affiliationID for IDP initiated SSO
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML Subject</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static Subject getSubject(Object session,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getSubject: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Subject subject = AssertionFactory.getInstance().createSubject();
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper boolean ignoreProfile = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster userName = sessionProvider.getPrincipalName(session);
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper ignoreProfile = SAML2Utils.isIgnoreProfileSet(session);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidSSOToken"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean allowCreate = true; // allow create is the default
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean isAffiliation = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster remoteEntityID = authnReq.getIssuer().getValue();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NameIDPolicy nameIDPolicy = authnReq.getNameIDPolicy();
ae5b5bc4ad012cbc81b9b4da033d316138f18391Jon Thomas boolean hasNameIDPolicy = nameIDPolicy != null &&
ae5b5bc4ad012cbc81b9b4da033d316138f18391Jon Thomas (StringUtils.isNotEmpty(nameIDPolicy.getSPNameQualifier())
ae5b5bc4ad012cbc81b9b4da033d316138f18391Jon Thomas || StringUtils.isNotEmpty(nameIDPolicy.getFormat()));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // this will take care of affiliation
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spNameQualifier = nameIDPolicy.getSPNameQualifier();
5bd78872486a30b19b4df7895dd0afecb18b169cJonathan Scudder if (spNameQualifier != null && !spNameQualifier.isEmpty()) {
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major AffiliationDescriptorType affiDesc = metaManager.getAffiliationDescriptor(realm, spNameQualifier);
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major if (affiDesc.getAffiliateMember().contains(remoteEntityID)) {
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // IDP initialted SSO
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AffiliationDescriptorType affiDesc = metaManager.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "affiliationNotFound"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (affiDesc.getAffiliateMember().contains(recipientEntityID)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "spNotAffiliationMember"));
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spsso = getSPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "metaDataError"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major metaManager.getIDPSSODescriptor(realm, idpEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "metaDataError"));
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDFormat = SAML2Utils.verifyNameIDFormat(nameIDFormat, spsso, idpsso);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major boolean isTransient = SAML2Constants.NAMEID_TRANSIENT_FORMAT.equals(nameIDFormat);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major IDPAccountMapper idpAccountMapper = SAML2Utils.getIDPAccountMapper(realm, idpEntityID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //Use-cases for NameID persistence:
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //* transient NameID -> The NameID MUST NOT be stored
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //* ignored user profile mode -> The NameID CANNOT be stored
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //* for any other cases -> The NameID MAY be stored based on customizable logic
66133206d795e0ddb43a02d309c75629f2af73ebMark de Reeper boolean shouldPersistNameID = !isTransient && !ignoreProfile
66133206d795e0ddb43a02d309c75629f2af73ebMark de Reeper && idpAccountMapper.shouldPersistNameIDFormat(realm, idpEntityID, remoteEntityID, nameIDFormat);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster userID = sessionProvider.getPrincipalName(session);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major SAML2Utils.debug.error(classMethod + "Unable to get principal name from the session.", se);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDInfo = AccountUtils.getAccountFederation(userID, idpEntityID, remoteEntityID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major AccountUtils.removeAccountFederation(nameIDInfo, userID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major DoManageNameID.removeIDPFedSession(remoteEntityID, nameID.getValue());
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major throw new SAML2InvalidNameIDPolicyException(SAML2Utils.bundle.getString("cannotCreateNameID"));
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major nameID = idpAccountMapper.getNameID(session, idpEntityID, spNameQualifier, realm, nameIDFormat);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major SAML2Utils.debug.message(classMethod + " shouldPersistNameID = " + shouldPersistNameID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major // write federation info into the persistent datastore
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.isDualRole(idpEntityID, realm)) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.DUAL_ROLE, false);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.IDP_ROLE,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AccountUtils.setAccountFederation(nameIDInfo, userName);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.userIDByTransientNameIDValue.put(nameID.getValue(),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SubjectConfirmation sc = getSubjectConfirmation(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get subject confirmation");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("noSubjectConfirmation"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML SubjectConfirmation</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param inResponseTo the request id of the <code>AuthnRequest</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the <code>ACS</code> service <code>url</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param effectiveTime the effective time of the assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML SubjectConfirmation</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static SubjectConfirmation getSubjectConfirmation(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String inResponseTo, String acsURL, int effectiveTime)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SubjectConfirmation sc = AssertionFactory.getInstance().
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sc.setMethod(SAML2Constants.SUBJECT_CONFIRMATION_METHOD_BEARER);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SubjectConfirmationData scd = AssertionFactory.getInstance().
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster scd.setRecipient(XMLUtils.escapeSpecialCharacters(acsURL));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster date.setTime(date.getTime() + effectiveTime * 1000);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML Conditions</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param audienceEntityID the entity id of the audience
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param effectiveTime the effective time of the assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML Conditions</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected static Conditions getConditions(String audienceEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int notBeforeSkewTime, int effectiveTime) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getConditions: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Conditions conditions = AssertionFactory.getInstance().
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster date.setTime(date.getTime() - notBeforeSkewTime * 1000);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster date.setTime(date.getTime() + effectiveTime * 1000);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AudienceRestriction ar = getAudienceRestriction(audienceEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get Audience Restriction");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("noAudienceRestriction"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML AudienceRestriction</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param audienceEntityID the entity id of the audience
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML AudienceRestriction</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static AudienceRestriction getAudienceRestriction(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String audienceEntityID) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AudienceRestriction ar = AssertionFactory.getInstance().
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the assertion consumer service <code>URL</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param rBinding the binding used to send back <code>Response</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the assertion consumer service <code>URL</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getACSurl(String spEntityID,
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major acsURL = authnReq.getAssertionConsumerServiceURL();
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major acsIndex = authnReq.getAssertionConsumerServiceIndex();
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major acsBinding = request.getParameter(SAML2Constants.BINDING);
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major return getACSurl(spEntityID, realm, acsURL, acsBinding, acsIndex, request, rBinding);
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * Returns the assertion consumer service <code>URL</code>.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param spEntityID The entity id of the service provider.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param realm The realm name of the identity provider.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param acsURL AssertionConsumerServiceURL in AuthnRequest.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param binding ProtocolBinding in AuthnRequest.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param index AssertionConsumerServiceIndex in AuthnRequest.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param request The <code>HttpServletRequest</code> object.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param rBinding The binding used to send back <code>Response</code>.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @return The assertion consumer service <code>URL</code>.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @throws SAML2Exception if the operation is not successful.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major public static String getACSurl(String spEntityID, String realm, String acsURL, String binding, Integer index,
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major HttpServletRequest request, StringBuffer rBinding) throws SAML2Exception {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major if (binding != null && !binding.trim().isEmpty()
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major && !binding.startsWith(SAML2Constants.BINDING_PREFIX)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // convert short format binding to long format
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major binding = SAML2Constants.BINDING_PREFIX + binding;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer returnedBinding = new StringBuffer();
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major if ((binding != null) && (binding.trim().length() != 0)) {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major acsURL = IDPSSOUtil.getACSurlFromMetaByBinding(spEntityID, realm, binding, returnedBinding);
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major acsURL = getDefaultACSurl(spEntityID, realm, returnedBinding);
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major acsURL = IDPSSOUtil.getACSurlFromMetaByIndex(spEntityID, realm, acsIndex, returnedBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (isACSurlValidInMetadataSP(acsURL, spEntityID, realm)) {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major binding = getBindingForAcsUrl(spEntityID, realm, acsURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception("libSAML2", "invalidAssertionConsumerServiceURL", args);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the default assertion consumer service url and binding
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * from the metadata.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the assertion consumer service url with returned binding.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
80849398a45dca1fb917716907d6ec99be6222c2Peter Major StringBuffer returnedBinding) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getDefaultACSurl: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (i == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the assertion consumer service url binding from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the metadata.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the assertion consumer service url binding
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getBindingForAcsUrl: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (location != null && location.equals(acsURL)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the assertion consumer service <code>URL</code> from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * meta data by binding
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param desiredBinding the desired binding
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param returnedBinding the binding used to send back
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * <code>Response</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the assertion consumer service <code>URL</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getACSurlFromMetaByBinding(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getACSurlFromMetaByBinding: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (i == 0) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get valid Assertion " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Consumer Service URL");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the assertion consumer service <code>URL</code> from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * meta data by binding
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsIndex the <code>ACS</code> index
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param returnedBinding the binding used to send back
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * <code>Response</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the assertion consumer service <code>URL</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getACSurlFromMetaByIndex: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (i == 0) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get valid Assertion " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Consumer Service URL");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * This method opens a URL connection to the target specified and
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * sends artifact response to it using the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>HttpServletResponse</code> object.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the assertion consumer service <code>URL</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param relayState the value of the <code>RelayState</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param res the <code>SAML Response</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param session user session
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param props property map including nameIDString for logging
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponseArtifact(HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID, String spEntityID, String realm, String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String relayState, Response res, Object session, Map props)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.sendResponseArtifact: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPSSODescriptorElement idpSSODescriptorElement = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpSSODescriptorElement = metaManager.getIDPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get IDP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.IDP_METADATA_ERROR, data, session, props);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get IDP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.IDP_METADATA_ERROR, data, session, props);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpSSODescriptorElement.getArtifactResolutionService().get(0);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get ArtifactResolutionServiceElement from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.IDP_METADATA_ERROR, data, session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster art = ProtocolFactory.getInstance().createArtifact(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.CANNOT_CREATE_ARTIFACT, data, session, props);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major response.SC_INTERNAL_SERVER_ERROR, "errorCreateArtifact",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorCreateArtifact"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.responsesByArtifacts.put(artStr, res);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper long expireTime = getValidTimeofResponse(realm, idpEntityID, res) / 1000;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper SAML2FailoverUtils.saveSAML2TokenWithoutSecondaryKey(artStr,
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.message(classMethod + "Saved Response to SAML2 Token Repository using key "
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod + "Unable to save Response to the SAML2 Token Repository", se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String messageEncoding = SAML2Utils.getAttributeValueFromSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.RESPONSE_ARTIFACT_MESSAGE_ENCODING);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (messageEncoding.equals(SAML2Constants.FORM_ENCODING))) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {idpEntityID, realm, acsURL};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.access(Level.INFO, LogUtil.SEND_ARTIFACT, logdata,
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest SAML2Utils.postToTarget(request, response, SAML2Constants.SAML_ART,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (acsURL.contains("?") ? "&" : "?") + "SAMLart=" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((relayState != null) && (relayState.trim().length() != 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {idpEntityID, realm, redirectURL};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.access(Level.INFO, LogUtil.SEND_ARTIFACT, logdata,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method sends SAML Response back to ECP.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param request The servlet request.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param response The servlet response.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param out The print writer for writing out presentation.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the assertion consumer service <code>URL</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param res the <code>SAML Response</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponseECP(HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID, String realm, String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major ECPFactory ecpFactory = ECPFactory.getInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ECPResponse ecpResponse = ecpFactory.createECPResponse();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ecpResponse.setActor(SAML2Constants.SOAP_ACTOR_NEXT);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ecpResponse.setAssertionConsumerServiceURL(acsURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String header = ecpResponse.toXMLString(true, true);
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings SOAPMessage reply = SOAPCommunicator.getInstance().createSOAPMessage(header, body,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {idpEntityID, realm, acsURL, ""};
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings logdata[3] = SOAPCommunicator.getInstance().soapMessageToString(reply);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.access(Level.INFO, LogUtil.SEND_ECP_RESPONSE, logdata,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Need to call saveChanges because we're
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // going to use the MimeHeaders to set HTTP
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // response information. These MimeHeaders
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // are generated as part of the save.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.putHeaders(reply.getMimeHeaders(), response);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Write out the message on the response stream
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper ByteArrayOutputStream stream = new ByteArrayOutputStream();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseECP", ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO, LogUtil.SEND_ECP_RESPONSE_FAILED, data,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the session index of an <code>IDPSession</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param session the session corresponding to the <code>IDPSession</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the session index string
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getSessionIndex(Object session) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getSessionIndex: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "error retrieving session index from the session: ", e);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major classMethod + "Returning sessionIndex=" + index);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * Returns the authentication service <code>URL</code> of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param hostEntityId the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @return the authentication service <code>URL</code> of the
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getAuthenticationServiceURL(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getAuthenticationServiceURL: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String authUrl = getAttributeValueFromIDPSSOConfig(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authUrl == null) || (authUrl.trim().length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // need to get it from the request
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int secondSlashIndex = uri.indexOf("/", firstSlashIndex + 1);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster deploymentURI = uri.substring(0, secondSlashIndex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + "auth url=:" + authUrl);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String classMethod = "IDPSSOUtil.getAttributeValueFromIDPSSOConfig: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPSSOConfigElement config = metaManager.getIDPSSOConfig(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map attrs = SAML2MetaUtils.getAttributes(config);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Redirects to authenticate service
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param reqID the <code>AuthnRequest ID</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.redirectAuthentication: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the authentication service url
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Pass spEntityID to IdP Auth Module
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // find out the authentication method, e.g. module=LDAP, from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // authn context mapping
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Set authnTypeAndValues = info.getAuthnTypeAndValues();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major StringBuffer authSB = new StringBuffer((String) iter.next());
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String gotoURL = request.getRequestURL().toString();
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major //We are appending redirected=true to the goto URL so that we can tell if the user was already redirected
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major //to the login interface for authentication.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major gotoURL += "?" + gotoQuery + "&" + REDIRECTED_TRUE;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "New URL for authentication: " + newURL.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // TODO: here we should check if the new URL is one
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // the same web container, if yes, forward,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // if not, redirect
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Signs an <code>Assertion</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param assertion The <code>Assertion</code> to be signed
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.signAssertion: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster KeyProvider kp = KeyUtil.getKeyProviderInstance();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get a key provider instance.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("nullKeyProvider"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpSignCertAlias = SAML2Utils.getSigningCertAlias(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get the hosted IDP signing certificate alias.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("missingSigningCertAlias"));
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper key = kp.getPrivateKey(idpSignCertAlias, encryptedKeyPass);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper assertion.sign(key, kp.getX509Certificate(idpSignCertAlias));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Signs and encrypts the components of a <code>SAML Response</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * based on the service provider meta data. If the flag of
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * encrypting <code>Assertion</code> is on, then the embedded
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>Assertion</code> object will be encrypted; if the flag
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * of encrypting <code>Assertion</code> is off and the flag of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * encrypting <code>NameID</code> is on, then the <code>NameID</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * embedded in the <code>Assertion</code> will be encrypted; if the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * flag of encrypting <code>Assertion</code> is off and the flag of
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * encrypting <code>Attribute</code> is on, then the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>Attribute</code> embedded in the <code>Assertion</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * will be encrypted. If the flag signAssertion is on, then the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>Assertion</code> will be signed. It will be signed before
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * it is encrypted and after its embedded <code>NameID</code> or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>Attribute</code> is encrypted.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param res The <code>Response</code> whose components may be
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * encrypted based on the service provider meta data setting
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param signAssertion A flag to indicate if <code>Assertion</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * signing is required
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static void signAndEncryptResponseComponents(String realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.signAndEncryptResponseComponents: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean toEncryptAssertion = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean toEncryptNameID = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean toEncryptAttribute = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((assertions == null) || (assertions.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Assertion assertion = (Assertion) assertions.get(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the encryption related flags from the SP Entity Config
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster toEncryptAssertion = (wantAssertionEncrypted != null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (wantAssertionEncrypted.equals(SAML2Constants.TRUE));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster toEncryptNameID = (wantNameIDEncrypted != null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (wantNameIDEncrypted.equals(SAML2Constants.TRUE));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster toEncryptAttribute = (wantAttributeEncrypted != null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (wantAttributeEncrypted.equals(SAML2Constants.TRUE));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // all encryption flags are off, no encryption needed
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // get the encryption information
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster EncInfo encInfo = KeyUtil.getEncInfo(spSSODescriptorElement,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failed to get service provider encryption key info.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableToFindEncryptKeyInfo"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // sign assertion first, then encrypt the assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // we only encrypt the Assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster EncryptedAssertion encryptedAssertion = assertion.encrypt(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getWrappingKey(), encInfo.getDataEncAlgorithm(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failed to encrypt the assertion.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("FailedToEncryptAssertion"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setAssertion(new ArrayList()); // reset assertion list
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + "Assertion encrypted.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // we only encrypt NameID and/or Attribute.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // encrypt NameID and/or Attribute first, then sign the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // assertion if applicable
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // we need to encrypt the NameID
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failed to encrypt the NameID.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "FailedToEncryptNameID"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + "NameID encrypted.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // we need to encrypt the Attribute
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List attributeStatements = assertion.getAttributeStatements();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // to hold all the AttributeStatements
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (AttributeStatement) attributeStatements.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List attributes = attributeStatement.getAttribute();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((attributes == null) || (attributes.size() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // holds all the encrypted Attributes in this statement
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Attribute attribute = (Attribute) attributes.get(j);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failed to encrypt the Attribute.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "FailedToEncryptAttribute"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attributeStatement.setEncryptedAttribute(eaList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attributeStatement.setAttribute(new ArrayList());
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Attribute encrypted.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major private static String getWriterURL(String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String classMethod = "IDPSSOUtil.getWriterURL: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // get cot list of the idp
80849398a45dca1fb917716907d6ec99be6222c2Peter Major metaManager.getIDPSSOConfig(realm, idpEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpConfigAttrsMap = SAML2MetaUtils.getAttributes(idpEntityCfg);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((idpConfigAttrsMap == null) || (idpConfigAttrsMap.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (List) idpConfigAttrsMap.get(SAML2Constants.COT_LIST);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((idpCOTList == null) || (idpCOTList.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // get cot list of the sp
80849398a45dca1fb917716907d6ec99be6222c2Peter Major spConfigAttrsMap = SAML2MetaUtils.getAttributes(spEntityCfg);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((spConfigAttrsMap == null) || (spConfigAttrsMap.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major List spCOTList = (List) spConfigAttrsMap.get(SAML2Constants.COT_LIST);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((spCOTList == null) || (spCOTList.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // retain in the idpCOTList the intersection of two lists
80849398a45dca1fb917716907d6ec99be6222c2Peter Major writerURL = cotDescriptor.getSAML2WriterServiceURL();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((writerURL != null) && (writerURL.trim().length() != 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod + "Error retreiving of "
80849398a45dca1fb917716907d6ec99be6222c2Peter Major } catch (Exception e) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Not able to getting writer URL : ", e);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * Returns the effective time from the IDP
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * extended metadata . If the attreibute is not
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * defined in the metadata then defaults to
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * a value of 600 seconds (5 minutes).
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @return the effective time value in seconds.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major protected static int getEffectiveTime(String realm, String idpEntityID) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int effectiveTime = SAML2Constants.ASSERTION_EFFECTIVE_TIME;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String effectiveTimeStr = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.ASSERTION_EFFECTIVE_TIME_ATTRIBUTE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster effectiveTime = Integer.parseInt(effectiveTimeStr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.getEffectiveTime: " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got effective time from config:" + effectiveTime);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.getEffectiveTime: " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Failed to get assertion effective time from " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster effectiveTime = SAML2Constants.ASSERTION_EFFECTIVE_TIME;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the NotBefore skew time from the IDP
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * extended metadata . If the attreibute is not
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * defined in the metadata then defaults to
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * a value of 600 seconds (5 minutes).
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the NotBefore skew value in seconds.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected static int getNotBeforeSkewTime(String realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getNotBeforeSkewTime:";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.NOTBEFORE_ASSERTION_SKEW_DEFAULT;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the assertion effective time (in seconds)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String skewTimeStr = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.ASSERTION_NOTBEFORE_SKEW_ATTRIBUTE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster notBeforeSkewTime = Integer.parseInt(skewTimeStr);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got NotBefore skew time from config:"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod + "IDP SSO config: ", nfe);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.NOTBEFORE_ASSERTION_SKEW_DEFAULT;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + "NotBefore Skew time :" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static boolean assertionCacheEnabled(String realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String enabled = SAML2Utils.getAttributeValueFromSSOConfig(realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "true".equalsIgnoreCase(enabled) ? true : false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static byte[] stringToByteArray(String input) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major public static long getValidTimeofResponse(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm, String idpEntityID, Response response)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // in seconds
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int timeskew = SAML2Constants.ASSERTION_TIME_SKEW_DEFAULT;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String timeskewStr = getAttributeValueFromIDPSSOConfig(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (timeskewStr != null && timeskewStr.trim().length() > 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster timeskew = SAML2Constants.ASSERTION_TIME_SKEW_DEFAULT;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message("timeskew = " + timeskew);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((assertions == null) || (assertions.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // failed case
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Assertion assertion = (Assertion) assertions.get(0);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major long ret = notOnOrAfter.getTime() + timeskew * 1000;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + " is invalid.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidTimeOnResponse"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * Signs SAMLv2 Response.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID the identity provider entity identifier
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the SAMLv2 <code>Response</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws <code>SAML2Exception</code> if there is an
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * error signing the response.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major private static void signResponse(String realm, String idpEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil:signResponse";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster KeyProvider kp = KeyUtil.getKeyProviderInstance();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get a key provider instance.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("nullKeyProvider"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpSignCertAlias = SAML2Utils.getSigningCertAlias(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Unable to get the hosted IDP signing certificate alias.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("missingSigningCertAlias"));
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper key = kp.getPrivateKey(idpSignCertAlias, encryptedKeyPass);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper response.sign(key, kp.getX509Certificate(idpSignCertAlias));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML2IdentityProviderAdapter</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID the entity id of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML2IdenityProviderAdapter</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings public static SAML2IdentityProviderAdapter getIDPAdapterClass(String realm, String idpEntityID)
7da3f239ac3deab008336f663f21e82d5d01aeadJonathan Scudder return SAML2Utils.getIDPAdapterClass(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Validates if the Assertion Consumer Service URL acsURL exists in the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * metadata of the Service Provider spEntityID
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the assertion consumer service <code>URL</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @return true if the assertion consumer service URL was found
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * false otherwise
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static boolean isACSurlValidInMetadataSP(String acsURL,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean isValidACSurl = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.isACSurlValidInMetadataSP: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + " acsURL=" + acsURL +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Found in the metadata");
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * Returns the the value of the wantAssertionsSigned property
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param spEntityID ID of the SP entity to be retrieved.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param realm The realm under which the entity resides.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @return boolean value of the wantAssertionsSigned property.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @throws SAML2MetaException if unable to retrieve the service
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * provider's SSO descriptor.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas private static boolean wantAssertionsSigned(String realm, String spEntityID) throws SAML2Exception {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas String method = "IPDSSOUtil:wantAssertionsSigned : ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SAML2Utils.debug.message(method + ": realm - " + realm + "/: spEntityID - " + spEntityID);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptor = getSPSSODescriptor(spEntityID, realm, method);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas return spSSODescriptor.isWantAssertionsSigned();
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * Returns the service provider's SSO descriptor in an entity under the realm.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param realm The realm under which the entity resides.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param spEntityID ID of the SP entity to be retrieved.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param classMethod the calling class method
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @return <code>SPSSODescriptorElement</code> for the entity
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @throws SAML2Exception if entity is not found
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas private static SPSSODescriptorElement getSPSSODescriptor(String realm,
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptor = null;
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SAML2Utils.debug.error(classMethod + "Unable to get meta manager.");
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas throw new SAML2Exception(SAML2Utils.bundle.getString("errorMetaManager"));
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas spSSODescriptor = metaManager.getSPSSODescriptor(realm, spEntityID);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas + "Unable to get SP SSO Descriptor from metadata, descriptor is null.");
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SAML2Utils.debug.error(classMethod + "Unable to get SP SSO Descriptor from metadata, descriptor is null.");
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * Check that the authenticated session belongs to the same realm where the IDP is defined.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * @param realm The realm where the IdP is defined.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * @param session The Session object of the authenticated user.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * @return true If the session was initiated in the same realm as the session's realm.
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings public static boolean isValidSessionInRealm(String realm, Object session) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String classMethod = "IDPSSOUtil.isValidSessionInRealm: ";
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major boolean isValidSessionInRealm = false;
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major // A user can only be authenticated in one realm
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String sessionRealm = SAML2Utils.getSingleValuedSessionProperty(session, SAML2Constants.ORGANIZATION);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (sessionRealm != null && !sessionRealm.isEmpty()) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.warning(classMethod + "Invalid realm for the session:" + sessionRealm
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.error(classMethod + "Could not retrieve the session information", ex);
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major private static List<String> extractAuthenticatingAuthorities(Assertion assertion) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final List<String> authenticatingAuthorities = new ArrayList<String>();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final List<AuthnStatement> authnStatements = assertion.getAuthnStatements();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major for (AuthnStatement authnStatement : authnStatements) {