IDPSSOUtil.java revision 0cd8368ca65c58915ee90bc73d84e65f3da9e120
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 $
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper * Portions Copyrighted 2010-2013 ForgeRock, Inc
80849398a45dca1fb917716907d6ec99be6222c2Peter Majorimport com.iplanet.dpro.session.exceptions.StoreException;
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;
89503929c8983c48e2049c77284b52e79ad37c32jeff.schenkimport com.sun.identity.saml2.common.SAML2RepositoryFactory;
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;
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";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static SAML2MetaManager metaManager = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static CircleOfTrustManager cotManager = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static IDPSessionListener sessionListener = new IDPSessionListener();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("Error retreiving 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
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 * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void doSSOFederate(HttpServletRequest request,
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
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
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.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // idp initiated and not logged in yet, need to authenticate
80849398a45dca1fb917716907d6ec99be6222c2Peter Major redirectAuthentication(request, response, authnReq,
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
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sendResponseToACS(request, response, 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
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.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponseToACS(HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response, Object session, AuthnRequest authnReq,
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);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major if (redirectUrl != null && !redirectUrl.isEmpty()) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major response.setStatus(Integer.valueOf(responseCode));
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major // no redirect, perhaps an error page, return the content
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major if (outputData != null && !outputData.isEmpty()) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major SAML2Utils.debug.message("Printing the forwarded response");
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major response.setContentType("text/html; charset=UTF-8");
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major 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
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Response res = getResponse(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:" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sendResponse(request, response, 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;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Sends a response to service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
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);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sendResponse(request, response, 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);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // send the response back through HTTP POST or Artifact
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsBinding.equals(SAML2Constants.HTTP_POST)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // check if response needs to be signed.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // if response is signed then assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // will not be signed for POST Profile
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean signAssertion = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // signing assertion is a must for POST profile if
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // response signing is not enabled.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // encryption is optional based on SP config settings.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster 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);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.postToTarget(response, "SAMLResponse",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encodedResMsg, "RelayState", relayState, acsURL);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "postToTarget failed.", e);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.POST_TO_TARGET_FAILED, data, session, props);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("postToTargetFailed"));
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.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPSSOUtil.sendResponseECP(request, response, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "unsupported return binding.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnSupportedReturnBinding"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML Response</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param session the user's session object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param recipientEntityID the entity id of the response recipient
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the <code>ACS</code> service <code>url</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param affiliationID affiliationID for IDP initiated SSO
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param matchingAuthnContext the <code>AuthnContext</code> used to find
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * authentication type and scheme.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML Response</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter 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().
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Assertion assertion = getAssertion(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 * @param session the user's session object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param recipientEntityID the entity id of the response recipient
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the <code>ACS</code> service <code>url</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param affiliationID affiliationID for IDP initiated SSO
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param matchingAuthnContext the <code>AuthnContext</code> used to find
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * authentication type and scheme.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML Assertion</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter 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();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AuthnStatement authnStatement = getAuthnStatement(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, isNewSessionIndex, authnReq, idpEntityID, realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String sessionIndex = authnStatement.getSessionIndex();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "This is a new IDP session with sessionIndex=" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpSession = (IDPSession) IDPCache.idpSessionsBySessionID.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Set the metaAlias in the IDP session object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.idpSessionsByIndices.put(sessionIndex, idpSession);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "a new IDP session has been saved in cache, " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionProvider.addListener(session, sessionListener);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to add session listener.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpSession = (IDPSession) IDPCache.idpSessionsByIndices.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Read from DataBase
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2RepositoryFactory.getInstance().retrieveSAML2Token(sessionIndex);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error("Unable to obtain the IDPSessionCopy from the CTS Repository: " + se.getMessage(), se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Copy back to IDPSession
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSessionCopy is null");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("IDPSessionIsNULL"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSession is null; SAML2 failover" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "is disabled");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("IDPSessionIsNULL"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "This is an existing IDP session with sessionIndex="
80849398a45dca1fb917716907d6ec99be6222c2Peter Major 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 nameIDFormat, isNewFederation, realm, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major recipientEntityID, effectiveTime, affiliationID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // register (spEntityID, nameID) with the sso token
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // for later logout use
80849398a45dca1fb917716907d6ec99be6222c2Peter Major List list = (List) idpSession.getNameIDandSPpairs();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (isNewFederation.getValue()) { // new federation case
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else { // existing federation case
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < n; i++) {
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);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2RepositoryFactory.getInstance().saveSAML2Token(assertionID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error("Unable to save the Assertion to the CTS Repository: " + se.getMessage(), se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Save to persistent datastore
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster long sessionExpireTime = System.currentTimeMillis() / 1000 +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2RepositoryFactory.getInstance().saveSAML2Token(sessionIndex,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major new IDPSessionCopy(idpSession), sessionExpireTime, null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod + "DB error!");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get left-time from the session.", se);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidSSOToken"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error("Unable to save the IDPSession to the CTS Repository: "+se.getMessage(),se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML AuthnStatement</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param session the user's session
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param isNewSessionIndex a returned flag from which the caller
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * knows if the session index in the returned
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * <code>AuthnStatement</code> is a new session index
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param matchingAuthnContext the <code>AuthnContext</code> used to find
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * authentication type and scheme.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML AuthnStatement</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter 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(
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
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster 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
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster 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 isNewFederation a returned flag from which the caller
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * knows if this is a new federation case
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();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // this will take care of affiliation
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spNameQualifier = nameIDPolicy.getSPNameQualifier();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AffiliationDescriptorType affiDesc = metaManager.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major getAffiliationDescriptor(realm, spNameQualifier);
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"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPSSODescriptorElement spsso = metaManager.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"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster nameIDFormat = SAML2Utils.verifyNameIDFormat(nameIDFormat, spsso,
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper // Even if the user profile is set to ignore, we must attempt to persist
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper // if the NameIDFormat is set to persistent.
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper if (ignoreProfile && SAML2Constants.PERSISTENT.equals(nameIDFormat)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "ignoreProfile was true but NameIDFormat is Persistent => setting ignoreProfile to false");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster userID = sessionProvider.getPrincipalName(session);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get principal name from the session.", se);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidSSOToken"));
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper nameIDInfo = AccountUtils.getAccountFederation(userID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // existing federation
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AccountUtils.removeAccountFederation(nameIDInfo, userID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DoManageNameID.removeIDPFedSession(remoteEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major nameIDFormat.equals(SAML2Constants.PERSISTENT)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("cannotCreateNameID"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.getIDPAccountMapper(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster nameID = idpAccountMapper.getNameID(session, idpEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // If the IdP has received a request from a remote SP for which it has
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // been configured not to persist the Federation if unspecified NameID
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Format has been set
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean spDoNotWriteFedInfoInIdP = isSPDoNotWriteFedInfoInIdP(realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.UNSPECIFIED.equals(nameIDFormat);
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper boolean writeFedInfo = !ignoreProfile && !isTransient && !spDoNotWriteFedInfoInIdP;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + " writeFedInfo = " + writeFedInfo);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // write federation info the into persistent datastore
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.isDualRole(idpEntityID, realm)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major nameID, SAML2Constants.IDP_ROLE, isAffiliation);
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,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = authnReq.getAssertionConsumerServiceURL();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsBinding = request.getParameter(SAML2Constants.BINDING);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((acsBinding != null) && (acsBinding.trim().length() != 0) &&
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (!acsBinding.startsWith(SAML2Constants.BINDING_PREFIX))) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // convert short format binding to long format
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsBinding = SAML2Constants.BINDING_PREFIX + acsBinding;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer returnedBinding = new StringBuffer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((acsBinding != null) && (acsBinding.trim().length() != 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = IDPSSOUtil.getACSurlFromMetaByBinding(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spEntityID, realm, acsBinding, returnedBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (isACSurlValidInMetadataSP(acsURL, spEntityID, realm)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsBinding == null || acsBinding.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsBinding = 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: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPSSODescriptorElement spSSODescriptorElement = null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get meta manager.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorMetaManager"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spSSODescriptorElement = metaManager.getSPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
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: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPSSODescriptorElement spSSODescriptorElement = null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get meta manager.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorMetaManager"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spSSODescriptorElement = metaManager.getSPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
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: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPSSODescriptorElement spSSODescriptorElement = null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get meta manager.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorMetaManager"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spSSODescriptorElement = metaManager.getSPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
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: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPSSODescriptorElement spSSODescriptorElement = null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get meta manager.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorMetaManager"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spSSODescriptorElement = metaManager.getSPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
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);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2RepositoryFactory.getInstance().saveSAML2Token(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major artStr, res.toXMLString(true, true), expireTime / 1000,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Save Response to DB!");
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,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.postToTarget(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,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major } catch (Exception e) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod + "DB Error!", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method sends SAML Response back to ECP.
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 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);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SOAPMessage reply = SAML2Utils.createSOAPMessage(header, body,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {idpEntityID, realm, acsURL, ""};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster logdata[3] = SAML2Utils.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
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();
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
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPSSODescriptorElement spSSODescriptorElement = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod + "Unable to get meta manager.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorMetaManager"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spSSODescriptorElement = metaManager.getSPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // 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
7da3f239ac3deab008336f663f21e82d5d01aeadJonathan Scudder static SAML2IdentityProviderAdapter getIDPAdapterClass(String realm, String idpEntityID)
7da3f239ac3deab008336f663f21e82d5d01aeadJonathan Scudder return SAML2Utils.getIDPAdapterClass(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns <code>true</code> or <code>false</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * depending if the flag spDoNotWriteFederationInfo is set in the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * SP Extended metadata
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the Service Provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param metaManager the SAML2MetaMAnager used to read the extendede metadata
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>true/false</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static Boolean isSPDoNotWriteFedInfoInIdP(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm, String spEntityID, SAML2MetaManager metaManager)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String methodName = "isSPDoNotWriteFedInfoInIdp";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil." + methodName + "Entering");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String SPDoNotWriteFedInfo = getAttributeValueFromSPSSOConfig(realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Constants.SP_DO_NOT_WRITE_FEDERATION_INFO);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SPDoNotWriteFedInfo != null && !SPDoNotWriteFedInfo.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil." + methodName +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major ": SPDoNotWriteFedInfo is: " + SPDoNotWriteFedInfo);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster isSPDoNotWriteFedInfoEnabled = SPDoNotWriteFedInfo.equalsIgnoreCase("true");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil." + methodName +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ": SPDoNotWriteFedInfo is: not configured");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil." + methodName +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get the spDoNotWriteFedInfo flag.", ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Retrieves attribute value for a given attribute name from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SPSSOConfig</code>.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param orgName realm or organization name the service provider resides in
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param hostEntityId hosted service provider's Entity ID.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param sm <code>SAML2MetaManager</code> instance to perform meta
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * operations.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param attrName name of the attribute whose value ot be retrived.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return value of the attribute; or <code>null</code> if the attribute
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * if not configured, or an error occured in the process.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static String getAttributeValueFromSPSSOConfig(String orgName,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPSSOConfigElement config = sm.getSPSSOConfig(orgName,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map attrs = SAML2MetaUtils.getAttributes(config);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster result = ((String) value.iterator().next()).trim();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.getAttributeValueFromSPSSO"
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: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SPSSODescriptorElement spSSODescriptorElement = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod + "Unable to get meta manager.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorMetaManager"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spSSODescriptorElement = metaManager.getSPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get SP SSO Descriptor from meta.");
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");