07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major/*
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 *
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 * opensso/legal/CDDLv1.0.txt
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * permission and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Header Notice in each file and include the License file
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * at opensso/legal/CDDLv1.0.txt.
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 *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * $Id: IDPSSOUtil.java,v 1.56 2009/11/24 21:53:28 madan_ranganath Exp $
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * Portions Copyrighted 2010-2015 ForgeRock AS.
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura * Portions Copyrighted 2013 Nomura Research Institute, Ltd
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpackage com.sun.identity.saml2.profile;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.AccountUtils;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.NameIDInfo;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.NewBoolean;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2Constants;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2Exception;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2FailoverUtils;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport com.sun.identity.saml2.common.SAML2Utils;
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbingsimport com.sun.identity.saml2.common.SOAPCommunicator;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.encode.URLEncDec;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.DateUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.xml.XMLUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.cot.CircleOfTrustManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.cot.CircleOfTrustDescriptor;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.cot.COTException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.multiprotocol.MultiProtocolUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.multiprotocol.SingleLogoutManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml.common.SAMLUtils;
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.Issuer;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.NameID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.Subject;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.SubjectConfirmation;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.SubjectConfirmationData;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.ecp.ECPFactory;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.ecp.ECPResponse;
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.logging.LogUtil;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.key.EncInfo;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.key.KeyUtil;
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.Status;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.StatusCode;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.monitoring.FedMonAgent;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.monitoring.FedMonSAML2Svc;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.monitoring.MonitorManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionProvider;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.plugin.session.SessionException;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.plugins.SAML2IdentityProviderAdapter;
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeperimport org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException;
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Lunaimport org.forgerock.openam.saml2.audit.SAML2EventLogger;
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Majorimport org.forgerock.openam.utils.ClientUtils;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeperimport java.io.ByteArrayOutputStream;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.IOException;
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Majorimport java.io.PrintWriter;
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeperimport java.security.PrivateKey;
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Majorimport java.util.LinkedHashSet;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.logging.Level;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.ArrayList;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Date;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.HashMap;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.HashSet;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Iterator;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.List;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Map;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Set;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.servlet.http.HttpServletRequest;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.servlet.http.HttpServletResponse;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.xml.soap.SOAPMessage;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpublic class IDPSSOUtil {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // key name for name id format on SSOToken
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static final String NAMEID_FORMAT = "SAML2NameIDFormat";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static final String NULL = "null";
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major private static final String REDIRECTED = "redirected";
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major private static final String REDIRECTED_TRUE = "redirected=true";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static SAML2MetaManager metaManager = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static CircleOfTrustManager cotManager = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static IDPSessionListener sessionListener = new IDPSessionListener();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static SessionProvider sessionProvider = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static FedMonAgent agent;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static FedMonSAML2Svc saml2Svc;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster metaManager = new SAML2MetaManager();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster cotManager = new CircleOfTrustManager();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (COTException ce) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error("Error retrieving circle of trust");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SAML2MetaException sme) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error("Error retrieving metadata", sme);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionProvider = SessionManager.getProvider();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException se) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "IDPSSOUtil static block: Error getting SessionProvider.",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major se);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster agent = MonitorManager.getAgent();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster saml2Svc = MonitorManager.getSAML2Svc();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper private IDPSSOUtil() {
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper }
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Does SSO with existing federation or new federation
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * @param out the print writer for writing out presentation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpMetaAlias the meta alias of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param relayState the relay state
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna * @param auditor the auditor for logging SAML2 Events - may be null
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void doSSOFederate(HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response,
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest PrintWriter out,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnRequest authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpMetaAlias,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String nameIDFormat,
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna String relayState,
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna SAML2EventLogger auditor)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest doSSOFederate(request, response, out, authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major spEntityID, idpMetaAlias, nameIDFormat,
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna relayState, null, auditor);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Does SSO with existing federation or new federation
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * @param out the print writer for writing out presentation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpMetaAlias the meta alias of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param relayState the relay state
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param newSession Session used in IDP Proxy Case
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna * @param auditor the auditor for logging SAML2 Events - may be null
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void doSSOFederate(HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response,
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest PrintWriter out,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnRequest authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpMetaAlias,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String nameIDFormat,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String relayState,
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna Object newSession,
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna SAML2EventLogger auditor)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.doSSOFederate: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Object session = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (newSession != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster session = newSession;
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna auditor.setSSOTokenId(session);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster session = sessionProvider.getSession(request);
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna if (null != auditor) {
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna auditor.setAuthTokenId(session);
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException se) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.warningEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.warning(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major classMethod + "No session yet.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // log the authnRequest
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String authnRequestStr = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authnReq != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authnRequestStr = authnReq.toXMLString();
6ee2adce4b7ba1c7cdee88dce16cc901d1a1e1ceDavid Luna auditor.setRequestId(authnReq.getID());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {spEntityID, idpMetaAlias, authnRequestStr};
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.access(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.RECEIVED_AUTHN_REQUEST, logdata, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // retrieve IDP entity id from meta alias
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpEntityID = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String realm = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (metaManager == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get meta manager.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorMetaManager"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpEntityID = metaManager.getEntityByMetaAlias(idpMetaAlias);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((idpEntityID == null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major || (idpEntityID.trim().length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get IDP Entity ID from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpEntityID};
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.error(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.INVALID_IDP, data, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("metaDataError"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster realm = SAML2MetaUtils.getRealmByMetaAlias(idpMetaAlias);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SAML2MetaException sme) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get IDP Entity ID from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpMetaAlias};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.IDP_METADATA_ERROR, data, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("metaDataError"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // check if the remote provider is valid
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authnReq == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Issuer issuer = AssertionFactory.getInstance().createIssuer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster issuer.setValue(spEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!SAML2Utils.isSourceSiteValid(issuer, realm, idpEntityID)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.warningEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.warning(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "The remote provider is not valid.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidReceiver"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // Validate the RelayState URL.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.validateRelayStateURL(realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major relayState,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.IDP_ROLE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (authnReq == null && (session == null || !isValidSessionInRealm(realm, session))) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // idp initiated and not logged in yet, need to authenticate
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (Boolean.parseBoolean(request.getParameter(REDIRECTED))) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (session == null) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String[] data = {idpEntityID};
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.error(classMethod + "The IdP was not able to create a session");
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major LogUtil.error(Level.INFO, LogUtil.SSO_NOT_FOUND, data, session, null);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major } else {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major try {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String ipAddress = ClientUtils.getClientIPAddress(request);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String sessionRealm = SAML2Utils.getSingleValuedSessionProperty(session,
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Constants.ORGANIZATION);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String[] data = {sessionRealm, realm, spEntityID, ipAddress, null};
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.error(classMethod + "The realm of the session (" + sessionRealm
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major + ") does not correspond to that of the IdP (" + realm + ")");
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major LogUtil.error(Level.INFO, LogUtil.INVALID_REALM_FOR_SESSION, data, session, null);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major } catch (SessionException se) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.error(classMethod + "Failed to retrieve realm from session", se);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String rbKey = "UnableToDOSSOOrFederation";
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, rbKey,
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.bundle.getString(rbKey));
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major } else {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major redirectAuthentication(request, response, authnReq, null, realm, idpEntityID, spEntityID);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (IOException ioe) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to redirect to authentication.", ioe);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAMLUtils.sendError(request, response,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major response.SC_INTERNAL_SERVER_ERROR,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "UnableToRedirectToAuth",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableToRedirectToAuth"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Invoke the IDP Adapter
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + " Invoking the "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "IDP Adapter");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2IdentityProviderAdapter idpAdapter =
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPSSOUtil.getIDPAdapterClass(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpAdapter != null) {
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 return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } // else we continue with the logic. Beware of loops
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SAML2Exception se2) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod + " There was a problem when invoking"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + "the preSendResponse of the IDP Adapter: ", se2);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // End of invocation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest sendResponseToACS(request, response, out, session, authnReq, spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpEntityID, idpMetaAlias, realm, nameIDFormat, relayState, null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Sends <code>Response</code> containing an <code>Assertion</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * back to the requesting service provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param request the <code>HttpServletRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param response the <code>HttpServletResponse</code> object
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest * @param out the print writer for writing out presentation
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param session user session
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param spEntityID the entity id of the service provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpMetaAlias the meta alias of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param relayState the relay state
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param matchingAuthnContext the <code>AuthnContext</code> used to find
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * authentication type and scheme.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest public static void sendResponseToACS(HttpServletRequest request, HttpServletResponse response, PrintWriter out,
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest Object session, AuthnRequest authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID, String idpEntityID, String idpMetaAlias,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm, String nameIDFormat, String relayState,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnContext matchingAuthnContext)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer returnedBinding = new StringBuffer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acsURL = IDPSSOUtil.getACSurl(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major spEntityID, realm, authnReq, request, returnedBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acsBinding = returnedBinding.toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((acsURL == null) || (acsURL.trim().length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " no ACS URL found.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpMetaAlias};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.NO_ACS_URL, data, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableTofindACSURL"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((acsBinding == null) || (acsBinding.trim().length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " no return binding found.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpMetaAlias};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.NO_RETURN_BINDING, data, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableTofindBinding"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String affiliationID = request.getParameter(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.AFFILIATION_ID);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major
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 if (remoteServiceURL != null) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major remoteServiceURL += SAML2Utils.removeDeployUri(request.getRequestURI()) + "?" + request.getQueryString();
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major if (SAML2Utils.debug.messageEnabled()) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major SAML2Utils.debug.message("SessionIndex for this SSOToken is not local, forwarding the request to: "
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major + remoteServiceURL);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major }
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major String redirectUrl = null;
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major String outputData = null;
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major String responseCode = null;
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major HashMap<String, String> remoteRequestData =
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 }
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major try {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major if (redirectUrl != null && !redirectUrl.isEmpty()) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major response.sendRedirect(redirectUrl);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major } else {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major if (responseCode != null) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major response.setStatus(Integer.valueOf(responseCode));
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major }
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");
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest out.println(outputData);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major return;
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major }
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major }
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major } catch (IOException ioe) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major if (SAML2Utils.debug.messageEnabled()) {
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS() error in Request Routing", ioe);
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major }
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major }
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major return;
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major }
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major //end of request proxy
33fc82147580d6f2d1299f6282e1cf8a28212bc5Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // generate a response for the authn request
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major Response res = getResponse(request, session, authnReq, spEntityID, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpMetaAlias, realm, nameIDFormat, acsURL, affiliationID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major matchingAuthnContext);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (res == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " response is null");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String errorMsg =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableToCreateAssertion");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (authnReq == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster //idp initiated case, will not send error response to sp
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(errorMsg);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major res = SAML2Utils.getErrorResponse(authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.RESPONDER, null, errorMsg, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] values = {idpMetaAlias};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionProvider.setProperty(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, SAML2Constants.IDP_META_ALIAS, values);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " error setting idpMetaAlias into the session: ", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (res != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // call multi-federation protocol to set the protocol
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MultiProtocolUtils.addFederationProtocol(session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SingleLogoutManager.SAML2);
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,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " Redirected to set COT cookie.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " Doesn't set COT cookie.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " Response is: " + res.toXMLString());
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major try {
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major SAML2Utils.debug.message("IDPSSOUtil.sendResponseToACS: Invoking the IDP Adapter");
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major SAML2IdentityProviderAdapter idpAdapter = IDPSSOUtil.getIDPAdapterClass(realm, idpEntityID);
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major if (idpAdapter != null) {
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major idpAdapter.preSignResponse(authnReq, res, idpEntityID, realm, request, session, relayState);
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major }
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major } catch (SAML2Exception se) {
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS: There was a problem when invoking the "
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major + "preSendResponse of the IDP Adapter: ", se);
079f146cc6b658c00ec79e35a47d027c5039588aPeter Major }
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper sendResponse(request, response, out, acsBinding, spEntityID, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpMetaAlias, realm, relayState, acsURL, res, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseToACS:" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major " error response is null");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableToCreateErrorResponse"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static boolean setCOTCookie(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsBinding,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpMetaAlias,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String relayState,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Response res,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Object session) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.setCOTCookie: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String writerURL = getWriterURL(realm, idpEntityID, spEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (writerURL == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // could not find the writer URL, do not set the COT cookie
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // save the needed info into cache so they can be used later
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // when it is redirected back
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ArrayList cacheList = new ArrayList(9);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cacheList.add(0, acsBinding);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cacheList.add(1, spEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cacheList.add(2, idpEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cacheList.add(3, idpMetaAlias);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cacheList.add(4, realm);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cacheList.add(5, relayState);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cacheList.add(6, acsURL);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cacheList.add(7, res);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster cacheList.add(8, session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String cachedResID = SAML2Utils.generateIDWithServerID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.responseCache.put(cachedResID, cacheList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // construct redirect URL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer retURLSB = new StringBuffer(100);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster retURLSB.append(request.getScheme()).append("://")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(request.getServerName()).append(":")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(request.getServerPort())
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(request.getRequestURI())
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append("?")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(SAML2Constants.RES_INFO_ID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append("=")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(cachedResID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String retURL = URLEncDec.encode(retURLSB.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer redirectURLSB = new StringBuffer(200);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster redirectURLSB.append(writerURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (writerURL.indexOf("?") > 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster redirectURLSB.append("&");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster redirectURLSB.append("?");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster redirectURLSB.append(IDPDiscoveryConstants.SAML2_COOKIE_NAME)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append("=")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(idpEntityID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append("&")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(SAML2Constants.RELAY_STATE)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append("=")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(retURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String redirectURL = redirectURLSB.toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Writer redirect URL: " + redirectURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major response.sendRedirect(redirectURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (IOException ioe) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to send redirect: ", ioe);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major /**
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * A convenience method to construct NoPassive SAML error responses for SAML passive authentication requests.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major *
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param request The servlet request.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param response The servlet response.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param out The print writer for writing out presentation.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param idpMetaAlias The IdP's metaAlias.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param idpEntityID The IdP's entity ID.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param realm The realm where the IdP belongs to.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param authnReq The SAML AuthnRequest sent by the SP.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param relayState The RelayState value.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @param spEntityID The SP's entity ID.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major * @throws SAML2Exception If there was an error while creating or sending the response back to the SP.
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major */
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper public static void sendNoPassiveResponse(HttpServletRequest request, HttpServletResponse response, PrintWriter out,
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major String idpMetaAlias, String idpEntityID, String realm, AuthnRequest authnReq, String relayState,
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major String spEntityID) throws SAML2Exception {
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major Response res = SAML2Utils.getErrorResponse(authnReq, SAML2Constants.RESPONDER, SAML2Constants.NOPASSIVE, null,
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major idpEntityID);
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major StringBuffer returnedBinding = new StringBuffer();
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major String acsURL = IDPSSOUtil.getACSurl(spEntityID, realm, authnReq, request, returnedBinding);
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major String acsBinding = returnedBinding.toString();
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper sendResponse(request, response, out, acsBinding, spEntityID, idpEntityID, idpMetaAlias, realm, relayState,
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major acsURL, res, null);
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major }
34f7fc919553f0b520d0008264f1c5af819a3861Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Sends a response to service provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param request The servlet request.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param response The servlet response.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param out The print writer for writing out presentation.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param cachedResID the key used to retrieve response information
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * from the response information cache
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponse(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response,
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper PrintWriter out,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String cachedResID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.sendResponse: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major ArrayList cacheList =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (ArrayList) IDPCache.responseCache.remove(cachedResID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((cacheList != null) && (cacheList.size() == 9)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsBinding = (String) cacheList.get(0);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID = (String) cacheList.get(1);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID = (String) cacheList.get(2);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpMetaAlias = (String) cacheList.get(3);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm = (String) cacheList.get(4);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String relayState = (String) cacheList.get(5);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsURL = (String) cacheList.get(6);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Response res = (Response) cacheList.get(7);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Object session = cacheList.get(8);
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper sendResponse(request, response, out, acsBinding, spEntityID, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpMetaAlias, realm, relayState, acsURL, res, session);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major } else {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "unable to get response information from cache.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "UnableToGetResponseInfoFromCache"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Sends a response to service provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponse(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response,
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper PrintWriter out,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsBinding,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpMetaAlias,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String relayState,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Response res,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Object session)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.sendResponse: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String nameIDString = SAML2Utils.getNameIDStringFromResponse(res);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map props = new HashMap();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster props.put(LogUtil.NAME_ID, nameIDString);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // send the response back through HTTP POST or Artifact
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas if (acsBinding.equals(SAML2Constants.HTTP_POST)) {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // 4.1.4.5 POST-Specific Processing Rules (sstc-saml-profiles-errata-2.0-wd-06-diff.pdf)
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas //If response is not signed and POST binding is used, the assertion(s) MUST be signed.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // encryption is optional based on SP config settings.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas boolean signAssertion = true;
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // check if response needs to be signed.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas boolean signResponse = SAML2Utils.wantPOSTResponseSigned(realm, spEntityID, SAML2Constants.SP_ROLE);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // if signing response then signing assertion is optional
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // so will base on wantAssertionsSigned flag
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas if (signResponse) {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas signAssertion = wantAssertionsSigned(spEntityID, realm);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas signAndEncryptResponseComponents(realm, spEntityID, idpEntityID, res, signAssertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signResponse) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major signResponse(realm, idpEntityID, res);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String resMsg = res.toXMLString(true, true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "SAML Response content :\n" + resMsg);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String encodedResMsg = SAML2Utils.encodeForPOST(resMsg);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata1 = {spEntityID, idpMetaAlias, resMsg};
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.access(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.POST_RESPONSE, logdata1, session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest SAML2Utils.postToTarget(request, response, "SAMLResponse",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encodedResMsg, "RelayState", relayState, acsURL);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest } catch (SAML2Exception saml2E) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {acsURL};
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest LogUtil.error(Level.INFO, LogUtil.POST_TO_TARGET_FAILED, data, session, props);
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest throw saml2E;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
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.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signAndEncryptResponseComponents(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster realm, spEntityID, idpEntityID, res, true);
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper IDPSSOUtil.sendResponseECP(request, response, out, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, acsURL, res);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "unsupported return binding.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnSupportedReturnBinding"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * Returns a <code>SAML Response</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param request The HTTP request.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param session The user's session object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param authnReq The <code>AuthnRequest</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param recipientEntityID The entity ID of the response recipient.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param idpEntityID The entity ID of the identity provider.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param realm The realm name.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param nameIDFormat The <code>NameIDFormat</code>.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param acsURL The <code>ACS</code> service <code>url</code>.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param affiliationID AffiliationID for IDP initiated SSO.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param matchingAuthnContext the <code>AuthnContext</code> used to find authentication type and scheme.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @return the <code>SAML Response</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @throws SAML2Exception if the operation is not successful.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static Response getResponse(
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Object session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnRequest authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String recipientEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpMetaAlias,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String nameIDFormat,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String affiliationID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnContext matchingAuthnContext)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getResponse: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Response res = ProtocolFactory.getInstance().createResponse();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Status status = ProtocolFactory.getInstance().createStatus();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (status == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StatusCode statusCode = ProtocolFactory.getInstance().
80849398a45dca1fb917716907d6ec99be6222c2Peter Major createStatusCode();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (statusCode == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List assertionList = new ArrayList();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major Assertion assertion = getAssertion(request, session, authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major recipientEntityID, idpEntityID, idpMetaAlias, realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major nameIDFormat, acsURL, affiliationID, matchingAuthnContext);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (assertion == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major classMethod + "Unable to get Assertion.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major assertionList.add(assertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setAssertion(assertionList);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster statusCode.setValue(SAML2Constants.SUCCESS);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SAML2InvalidNameIDPolicyException se) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster statusCode.setValue(SAML2Constants.REQUESTER);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StatusCode subStatusCode = ProtocolFactory.getInstance().
80849398a45dca1fb917716907d6ec99be6222c2Peter Major createStatusCode();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster subStatusCode.setValue(SAML2Constants.INVALID_NAME_ID_POLICY);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster statusCode.setStatusCode(subStatusCode);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster status.setStatusMessage(se.getMessage());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster status.setStatusCode(statusCode);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setStatus(status);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authnReq != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // sp initiated case, need to set InResponseTo attribute
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setInResponseTo(authnReq.getID());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setVersion(SAML2Constants.VERSION_2_0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setIssueInstant(new Date());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setID(SAML2Utils.generateID());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // set the idp entity id as the response issuer
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Issuer issuer = AssertionFactory.getInstance().createIssuer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster issuer.setValue(idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setIssuer(issuer);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major res.setDestination(XMLUtils.escapeSpecialCharacters(acsURL));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return res;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML Assertion</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param request The HTTP request.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param session The user's session object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param authnReq The <code>AuthnRequest</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param recipientEntityID The entity ID of the response recipient.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param idpEntityID The entity ID of the identity provider.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param realm The realm name.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param nameIDFormat The <code>NameIDFormat</code>.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param acsURL The <code>ACS</code> service <code>url</code>.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param affiliationID AffiliationID for IDP initiated SSO.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param matchingAuthnContext the <code>AuthnContext</code> used to find authentication type and scheme.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @return the <code>SAML Assertion</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @throws SAML2Exception if the operation is not successful.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static Assertion getAssertion(
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Object session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnRequest authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String recipientEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpMetaAlias,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String nameIDFormat,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String affiliationID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnContext matchingAuthnContext)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getAssertion: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Assertion assertion = AssertionFactory.getInstance().createAssertion();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String assertionID = SAML2Utils.generateID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setID(assertionID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setVersion(SAML2Constants.VERSION_2_0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setIssueInstant(new Date());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Issuer issuer = AssertionFactory.getInstance().createIssuer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster issuer.setValue(idpEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setIssuer(issuer);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List statementList = new ArrayList();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NewBoolean isNewSessionIndex = new NewBoolean();
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura AuthnStatement authnStatement = null;
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura IDPSession idpSession = null;
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura String sessionIndex = null;
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura String sessionID = sessionProvider.getSessionID(session);
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura synchronized (sessionID) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authnStatement = getAuthnStatement(request, session, isNewSessionIndex, authnReq, idpEntityID, realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major matchingAuthnContext);
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura if (authnStatement == null) {
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura return null;
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura sessionIndex = authnStatement.getSessionIndex();
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura if (isNewSessionIndex.getValue()) {
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura if (SAML2Utils.debug.messageEnabled()) {
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "This is a new IDP session with sessionIndex=" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major sessionIndex + ", and sessionID=" +
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura sessionID);
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura }
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura idpSession = (IDPSession) IDPCache.idpSessionsBySessionID.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major get(sessionProvider.getSessionID(session));
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura if (idpSession == null) {
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura idpSession = new IDPSession(session);
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura }
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura // Set the metaAlias in the IDP session object
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura idpSession.setMetaAlias(idpMetaAlias);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura IDPCache.idpSessionsByIndices.put(sessionIndex, idpSession);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura if ((agent != null) && agent.isRunning() && (saml2Svc != null)) {
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura saml2Svc.setIdpSessionCount(
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura (long)IDPCache.idpSessionsByIndices.size());
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura }
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura } else {
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura idpSession = (IDPSession)IDPCache.idpSessionsByIndices.
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura get(sessionIndex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura }
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura if (isNewSessionIndex.getValue()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura "a new IDP session has been saved in cache, " +
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura "with sessionIndex=" + sessionIndex);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionProvider.addListener(session, sessionListener);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura "Unable to add session listener.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura } else {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (idpSession == null && SAML2FailoverUtils.isSAML2FailoverEnabled()) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper // Read from SAML2 Token Repository
ac73e8326df742bb4f8e11fdd6b551cba1c878d0Kohei Tamura IDPSessionCopy idpSessionCopy = null;
ac73e8326df742bb4f8e11fdd6b551cba1c878d0Kohei Tamura try {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper idpSessionCopy = (IDPSessionCopy) SAML2FailoverUtils.retrieveSAML2Token(sessionIndex);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper } catch (SAML2TokenRepositoryException se) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod +
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper "Unable to obtain IDPSessionCopy from the SAML2 Token Repository for sessionIndex:"
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper + sessionIndex, se);
ac73e8326df742bb4f8e11fdd6b551cba1c878d0Kohei Tamura }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Copy back to IDPSession
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpSessionCopy != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpSession = new IDPSession(idpSessionCopy);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSessionCopy is null");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura SAML2Utils.bundle.getString("IDPSessionIsNULL"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else if ((idpSession == null) &&
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper (!SAML2FailoverUtils.isSAML2FailoverEnabled())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSession is null; SAML2 failover" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "is disabled");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura SAML2Utils.bundle.getString("IDPSessionIsNULL"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura "This is an existing IDP session with sessionIndex="
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura + sessionIndex + ", and sessionID=" +
ce2f140d2972ebe3bbc25ee5dc40860b8663ead0Kohei Tamura sessionProvider.getSessionID(idpSession.getSession()));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster statementList.add(authnStatement);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AttributeStatement attrStatement = getAttributeStatement(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, idpEntityID, recipientEntityID, realm);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (attrStatement != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List attrStatementList = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attrStatementList.add(attrStatement);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major assertion.setAttributeStatements(attrStatementList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the assertion effective time (in seconds)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int effectiveTime = getEffectiveTime(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the NotBefore skew (in seconds)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int notBeforeSkewTime = getNotBeforeSkewTime(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the subject element
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Subject subject = getSubject(session, authnReq, acsURL,
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDFormat, realm, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major recipientEntityID, effectiveTime, affiliationID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // register (spEntityID, nameID) with the sso token
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // for later logout use
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String spEntityID = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authnReq != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spEntityID = authnReq.getIssuer().getValue();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spEntityID = recipientEntityID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major NameIDandSPpair pair = new NameIDandSPpair(subject.getNameID(), spEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major synchronized (IDPCache.idpSessionsByIndices) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major List<NameIDandSPpair> list = idpSession.getNameIDandSPpairs();
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major String id;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (authnReq != null) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major id = authnReq.getIssuer().getValue();
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major } else {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major id = spEntityID;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major }
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major boolean found = false;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major for (NameIDandSPpair nameIDandSPpair : list) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (nameIDandSPpair.getSPEntityID().equals(id)) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major found = true;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (!found) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major list.add(pair);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major assertion.setAuthnStatements(statementList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setSubject(subject);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Conditions conditions = getConditions(recipientEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major notBeforeSkewTime, effectiveTime);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setConditions(conditions);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String discoBootstrapEnabled = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID, SAML2Constants.DISCO_BOOTSTRAPPING_ENABLED);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((discoBootstrapEnabled != null) &&
80849398a45dca1fb917716907d6ec99be6222c2Peter Major discoBootstrapEnabled.equalsIgnoreCase("true")) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List attrStatementList = assertion.getAttributeStatements();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (attrStatementList == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attrStatementList = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setAttributeStatements(attrStatementList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster DiscoveryBootstrap bootstrap = new DiscoveryBootstrap(session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major subject,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major authnStatement.getAuthnContext().getAuthnContextClassRef(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major spEntityID, realm);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attrStatementList.add(bootstrap.getBootstrapStatement());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setAdvice(bootstrap.getCredentials());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (assertionCacheEnabled(realm, idpEntityID)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String userName = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster userName = sessionProvider.getPrincipalName(session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException se) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get principal name from the session.", se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidSSOToken"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String cacheKey = userName.toLowerCase();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major List assertions = (List) IDPCache.assertionCache.get(cacheKey);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (assertions == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster synchronized (IDPCache.assertionCache) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major assertions = (List) IDPCache.assertionCache.get(cacheKey);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (assertions == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertions = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.assertionCache.put(cacheKey, assertions);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster synchronized (assertions) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertions.add(assertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.assertionByIDCache.put(assertionID, assertion);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major try {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2FailoverUtils.saveSAML2Token(assertionID, cacheKey,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major assertion.toXMLString(true, true),
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper conditions.getNotOnOrAfter().getTime() / 1000);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod +
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper "Saving Assertion to SAML2 Token Repository. ID = " + assertionID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper } catch (SAML2TokenRepositoryException se) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod + "Unable to save Assertion to the SAML2 Token Repository", se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper // Save to SAML2 Token Repository
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper long sessionExpireTime = System.currentTimeMillis() / 1000 + (sessionProvider.getTimeLeft(session));
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper SAML2FailoverUtils.saveSAML2TokenWithoutSecondaryKey(sessionIndex, new IDPSessionCopy(idpSession),
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper sessionExpireTime);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.message(classMethod + "SAVE IDPSession!");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException se) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod + "Unable to get left-time from the session.", se);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper } catch (SAML2TokenRepositoryException se) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod + "Unable to save IDPSession to the SAML2 Token Repository", se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return assertion;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * Returns a <code>SAML AuthnStatement</code> object.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param request The HTTP request.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param session The user's session.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param isNewSessionIndex A returned flag from which the caller knows if the session index in the returned
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * <code>AuthnStatement</code> is a new session index.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param authnReq The <code>AuthnRequest</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param idpEntityID The entity ID of the identity provider.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param realm The realm name.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @param matchingAuthnContext The <code>AuthnContext</code> used to find authentication type and scheme.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @return The <code>SAML AuthnStatement</code> object.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major * @throws SAML2Exception If the operation is not successful.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static AuthnStatement getAuthnStatement(
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Object session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major NewBoolean isNewSessionIndex,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnRequest authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnContext matchingAuthnContext)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getAuthnStatement: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnStatement authnStatement =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AssertionFactory.getInstance().createAuthnStatement();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Date authInstant = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // will be used when we add SubjectLocality to the statement
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] values = sessionProvider.getProperty(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, SessionProvider.AUTH_INSTANT);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (values != null && values.length != 0 &&
80849398a45dca1fb917716907d6ec99be6222c2Peter Major values[0] != null && values[0].length() != 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authInstant = DateUtils.stringToDate(values[0]);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "exception retrieving info from the session: ", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authInstant == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authInstant = new Date();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authnStatement.setAuthnInstant(authInstant);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AuthnContext authnContext = matchingAuthnContext;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authnContext == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String authLevel = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] values = sessionProvider.getProperty(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, SessionProvider.AUTH_LEVEL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (values != null && values.length != 0 &&
80849398a45dca1fb917716907d6ec99be6222c2Peter Major values[0] != null && values[0].length() != 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authLevel = values[0];
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "exception retrieving auth level info from the session: ",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPAuthnContextMapper idpAuthnContextMapper =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major getIDPAuthnContextMapper(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authnContext =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAuthnContextMapper.getAuthnContextFromAuthLevel(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major authLevel, realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final Response idpResponse = (Response) request.getAttribute(SAML2Constants.SAML_PROXY_IDP_RESPONSE_KEY);
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major if (idpResponse != null) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major // IdP proxy case: we already received an assertion from the remote IdP and now the IdP proxy is generating
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major // a new SAML response for the SP.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major Set<String> authenticatingAuthorities = new LinkedHashSet<String>();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final List<Assertion> assertions = idpResponse.getAssertion();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major for (Assertion assertion : assertions) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authenticatingAuthorities.addAll(extractAuthenticatingAuthorities(assertion));
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major }
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major // According to SAML profile 4.1.4.2 each assertion within the SAML Response MUST have the same issuer, so
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major // this should suffice. We should have at least one assertion, since the IdP proxy's SP already accepted it.
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authenticatingAuthorities.add(assertions.iterator().next().getIssuer().getValue());
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authnContext.setAuthenticatingAuthority(new ArrayList<String>(authenticatingAuthorities));
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authnStatement.setAuthnContext(authnContext);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String sessionIndex = getSessionIndex(session);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (sessionIndex == null) { // new sessionIndex
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionIndex = SAML2Utils.generateIDWithServerID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] values = {sessionIndex};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sessionProvider.setProperty(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.IDP_SESSION_INDEX,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major values);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "error setting session index into the session: ", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorGettingAuthnStatement"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster isNewSessionIndex.setValue(true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster isNewSessionIndex.setValue(false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "SessionIndex (in AuthnStatement) =" + sessionIndex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (sessionIndex != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Set authContextSet = (HashSet)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPCache.authnContextCache.get(sessionIndex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authContextSet == null || authContextSet.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authContextSet = new HashSet();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authContextSet.add(authnContext);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // cache the AuthContext to use in the case of session upgrade.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPCache.authnContextCache.put(sessionIndex, authContextSet);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authnStatement.setSessionIndex(sessionIndex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return authnStatement;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML AttributeStatement</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static AttributeStatement getAttributeStatement(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Object session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String recipientEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPAttributeMapper idpAttrMapper =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major getIDPAttributeMapper(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List attributes = idpAttrMapper.getAttributes(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, idpEntityID, recipientEntityID, realm);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((attributes == null) || (attributes.isEmpty())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AttributeStatement attrStatement =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AssertionFactory.getInstance().createAttributeStatement();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attrStatement.setAttribute(attributes);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return attrStatement;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns an <code>IDPAttributeMapper</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static IDPAttributeMapper getIDPAttributeMapper(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm, String idpEntityID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getIDPAttributeMapper: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpAttributeMapperName = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPAttributeMapper idpAttributeMapper = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAttributeMapperName = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID, SAML2Constants.IDP_ATTRIBUTE_MAPPER);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpAttributeMapperName == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAttributeMapperName =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_ATTRIBUTE_MAPPER_CLASS;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod + "use " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_ATTRIBUTE_MAPPER_CLASS);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAttributeMapper = (IDPAttributeMapper)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPCache.idpAttributeMapperCache.get(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAttributeMapperName);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpAttributeMapper == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAttributeMapper = (IDPAttributeMapper)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Class.forName(idpAttributeMapperName).newInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.idpAttributeMapperCache.put(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAttributeMapperName, idpAttributeMapper);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got the IDPAttributeMapper from cache");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception ex) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get IDP Attribute Mapper.", ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return idpAttributeMapper;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns an <code>IDPAuthnContextMapper</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings public static IDPAuthnContextMapper getIDPAuthnContextMapper(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm, String idpEntityID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getIDPAuthnContextMapper: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpAuthnContextMapperName = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPAuthnContextMapper idpAuthnContextMapper = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAuthnContextMapperName = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.IDP_AUTHNCONTEXT_MAPPER_CLASS);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpAuthnContextMapperName == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAuthnContextMapperName =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_AUTHNCONTEXT_MAPPER_CLASS;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod + "use " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_AUTHNCONTEXT_MAPPER_CLASS);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAuthnContextMapper = (IDPAuthnContextMapper)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPCache.idpAuthnContextMapperCache.get(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAuthnContextMapperName);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpAuthnContextMapper == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpAuthnContextMapper = (IDPAuthnContextMapper)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Class.forName(idpAuthnContextMapperName).newInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.idpAuthnContextMapperCache.put(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAuthnContextMapperName, idpAuthnContextMapper);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got the IDPAuthnContextMapper from cache");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception ex) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get IDP AuthnContext Mapper.", ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return idpAuthnContextMapper;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns an <code>IDPECPSessionMapper</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings public static IDPECPSessionMapper getIDPECPSessionMapper(String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpECPSessionMapperName = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPECPSessionMapper idpECPSessionMapper = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpECPSessionMapperName = getAttributeValueFromIDPSSOConfig(realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpEntityID, SAML2Constants.IDP_ECP_SESSION_MAPPER_CLASS);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpECPSessionMapperName == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpECPSessionMapperName =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_ECP_SESSION_MAPPER_CLASS;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "IDPSSOUtil.getIDPECPSessionMapper: use " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.DEFAULT_IDP_ECP_SESSION_MAPPER_CLASS);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpECPSessionMapper = (IDPECPSessionMapper)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPCache.idpECPSessionMapperCache.get(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpECPSessionMapperName);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpECPSessionMapper == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpECPSessionMapper = (IDPECPSessionMapper)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Class.forName(idpECPSessionMapperName).newInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.idpECPSessionMapperCache.put(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpECPSessionMapperName, idpECPSessionMapper);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "IDPSSOUtil.getIDPECPSessionMapper: " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got the IDPECPSessionMapper from cache");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception ex) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.getIDPECPSessionMapper: " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get IDPECPSessionMapper.", ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return idpECPSessionMapper;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML Subject</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param session the user's session
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param authnReq the <code>AuthnRequest</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the <code>ACS</code> service <code>url</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param nameIDFormat the <code>NameIDFormat</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm The realm name
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param recipientEntityID the entity id of the response recipient
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param effectiveTime the effective time of the assertion
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param affiliationID affiliationID for IDP initiated SSO
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the <code>SAML Subject</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static Subject getSubject(Object session,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnRequest authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String nameIDFormat,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String recipientEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int effectiveTime,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String affiliationID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getSubject: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Subject subject = AssertionFactory.getInstance().createSubject();
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper boolean ignoreProfile = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String userName = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster userName = sessionProvider.getPrincipalName(session);
3240047b6ae47ab759fac9d4be1a597669394e46Mark de Reeper ignoreProfile = SAML2Utils.isIgnoreProfileSet(session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException se) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "There was a problem with the session.", se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidSSOToken"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean allowCreate = true; // allow create is the default
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String remoteEntityID = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String spNameQualifier = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean isAffiliation = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authnReq != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster remoteEntityID = authnReq.getIssuer().getValue();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NameIDPolicy nameIDPolicy = authnReq.getNameIDPolicy();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (nameIDPolicy != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // this will take care of affiliation
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster allowCreate = nameIDPolicy.isAllowCreate();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spNameQualifier = nameIDPolicy.getSPNameQualifier();
5bd78872486a30b19b4df7895dd0afecb18b169cJonathan Scudder if (spNameQualifier != null && !spNameQualifier.isEmpty()) {
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major AffiliationDescriptorType affiDesc = metaManager.getAffiliationDescriptor(realm, spNameQualifier);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (affiDesc != null) {
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major if (affiDesc.getAffiliateMember().contains(remoteEntityID)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster isAffiliation = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster remoteEntityID = spNameQualifier;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major } else {
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major spNameQualifier = recipientEntityID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // IDP initialted SSO
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (affiliationID != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AffiliationDescriptorType affiDesc = metaManager.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major getAffiliationDescriptor(realm, affiliationID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (affiDesc == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "affiliationNotFound"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (affiDesc.getAffiliateMember().contains(recipientEntityID)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster isAffiliation = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster remoteEntityID = affiliationID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spNameQualifier = affiliationID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "spNotAffiliationMember"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster remoteEntityID = recipientEntityID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spNameQualifier = recipientEntityID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spsso = getSPSSODescriptor(
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas realm, recipientEntityID, classMethod);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (spsso == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {recipientEntityID};
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "metaDataError"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPSSODescriptorElement idpsso =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major metaManager.getIDPSSODescriptor(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpsso == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {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 }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDFormat = SAML2Utils.verifyNameIDFormat(nameIDFormat, spsso, idpsso);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major boolean isTransient = SAML2Constants.NAMEID_TRANSIENT_FORMAT.equals(nameIDFormat);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major boolean isPersistent = SAML2Constants.PERSISTENT.equals(nameIDFormat);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major NameIDInfo nameIDInfo;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NameID nameID = null;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major IDPAccountMapper idpAccountMapper = SAML2Utils.getIDPAccountMapper(realm, idpEntityID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //Use-cases for NameID persistence:
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //* persistent NameID -> The NameID MUST be stored
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //* transient NameID -> The NameID MUST NOT be stored
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //* ignored user profile mode -> The NameID CANNOT be stored
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major //* for any other cases -> The NameID MAY be stored based on customizable logic
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major boolean shouldPersistNameID = isPersistent || (!isTransient && !ignoreProfile
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major && idpAccountMapper.shouldPersistNameIDFormat(realm, idpEntityID, remoteEntityID, nameIDFormat));
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!isTransient) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major String userID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster userID = sessionProvider.getPrincipalName(session);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException se) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major SAML2Utils.debug.error(classMethod + "Unable to get principal name from the session.", se);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (isPersistent || shouldPersistNameID) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDInfo = AccountUtils.getAccountFederation(userID, idpEntityID, remoteEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (nameIDInfo != null) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameID = nameIDInfo.getNameID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (!nameIDFormat.equals(nameID.getFormat())) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major AccountUtils.removeAccountFederation(nameIDInfo, userID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major DoManageNameID.removeIDPFedSession(remoteEntityID, nameID.getValue());
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameID = null;
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (nameID == null) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (!allowCreate && isPersistent) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major throw new SAML2InvalidNameIDPolicyException(SAML2Utils.bundle.getString("cannotCreateNameID"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
f657bb9412e8203540d27ec9cd59297c4d370a0fPeter Major nameID = idpAccountMapper.getNameID(session, idpEntityID, spNameQualifier, realm, nameIDFormat);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major SAML2Utils.debug.message(classMethod + " shouldPersistNameID = " + shouldPersistNameID);
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major if (shouldPersistNameID && allowCreate) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major // write federation info into the persistent datastore
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.isDualRole(idpEntityID, realm)) {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.DUAL_ROLE, false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.IDP_ROLE,
07856bf23b706ef4e3654388d9ca26a720e0ad6aPeter Major isAffiliation);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AccountUtils.setAccountFederation(nameIDInfo, userName);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster subject.setNameID(nameID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (isTransient) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.userIDByTransientNameIDValue.put(nameID.getValue(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major userName);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String inResponseTo = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (authnReq != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster inResponseTo = authnReq.getID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SubjectConfirmation sc = getSubjectConfirmation(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major inResponseTo, acsURL, effectiveTime);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (sc == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get subject confirmation");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("noSubjectConfirmation"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List list = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster list.add(sc);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster subject.setSubjectConfirmation(list);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return subject;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML SubjectConfirmation</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static SubjectConfirmation getSubjectConfirmation(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String inResponseTo, String acsURL, int effectiveTime)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SubjectConfirmation sc = AssertionFactory.getInstance().
80849398a45dca1fb917716907d6ec99be6222c2Peter Major createSubjectConfirmation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sc.setMethod(SAML2Constants.SUBJECT_CONFIRMATION_METHOD_BEARER);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SubjectConfirmationData scd = AssertionFactory.getInstance().
80849398a45dca1fb917716907d6ec99be6222c2Peter Major createSubjectConfirmationData();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster scd.setRecipient(XMLUtils.escapeSpecialCharacters(acsURL));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (inResponseTo != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster scd.setInResponseTo(inResponseTo);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Date date = new Date();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster date.setTime(date.getTime() + effectiveTime * 1000);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster scd.setNotOnOrAfter(date);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sc.setSubjectConfirmationData(scd);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return sc;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML Conditions</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected static Conditions getConditions(String audienceEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int notBeforeSkewTime, int effectiveTime) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getConditions: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Conditions conditions = AssertionFactory.getInstance().
80849398a45dca1fb917716907d6ec99be6222c2Peter Major createConditions();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Date date = new Date();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster date.setTime(date.getTime() - notBeforeSkewTime * 1000);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conditions.setNotBefore(date);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster date = new Date();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster date.setTime(date.getTime() + effectiveTime * 1000);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conditions.setNotOnOrAfter(date);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List list = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AudienceRestriction ar = getAudienceRestriction(audienceEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (ar == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get Audience Restriction");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("noAudienceRestriction"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster list.add(ar);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conditions.setAudienceRestrictions(list);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return conditions;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML AudienceRestriction</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static AudienceRestriction getAudienceRestriction(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String audienceEntityID) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AudienceRestriction ar = AssertionFactory.getInstance().
80849398a45dca1fb917716907d6ec99be6222c2Peter Major createAudienceRestriction();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (audienceEntityID != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List list = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster list.add(audienceEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ar.setAudience(list);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return ar;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the assertion consumer service <code>URL</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getACSurl(String spEntityID,
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major String realm,
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major AuthnRequest authnReq,
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major HttpServletRequest request,
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major StringBuffer rBinding)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major String acsURL = null;
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major String acsBinding;
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major Integer acsIndex = null;
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major if (authnReq != null) {
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major acsURL = authnReq.getAssertionConsumerServiceURL();
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major acsBinding = authnReq.getProtocolBinding();
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major acsIndex = authnReq.getAssertionConsumerServiceIndex();
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major } else {
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major acsBinding = request.getParameter(SAML2Constants.BINDING);
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major }
e90783680c3667210ac9de725dd4f8608d685fa0Peter Major return getACSurl(spEntityID, realm, acsURL, acsBinding, acsIndex, request, rBinding);
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major /**
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * Returns the assertion consumer service <code>URL</code>.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major *
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param spEntityID The entity id of the service provider.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param realm The realm name of the identity provider.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param acsURL AssertionConsumerServiceURL in AuthnRequest.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param binding ProtocolBinding in AuthnRequest.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param index AssertionConsumerServiceIndex in AuthnRequest.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param request The <code>HttpServletRequest</code> object.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @param rBinding The binding used to send back <code>Response</code>.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @return The assertion consumer service <code>URL</code>.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major * @throws SAML2Exception if the operation is not successful.
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major */
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major public static String getACSurl(String spEntityID, String realm, String acsURL, String binding, Integer index,
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major HttpServletRequest request, StringBuffer rBinding) throws SAML2Exception {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major if (binding != null && !binding.trim().isEmpty()
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major && !binding.startsWith(SAML2Constants.BINDING_PREFIX)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // convert short format binding to long format
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major binding = SAML2Constants.BINDING_PREFIX + binding;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsURL == null || acsURL.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer returnedBinding = new StringBuffer();
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major if ((binding != null) && (binding.trim().length() != 0)) {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major acsURL = IDPSSOUtil.getACSurlFromMetaByBinding(spEntityID, realm, binding, returnedBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major int acsIndex;
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major if (index == null) {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major acsURL = getDefaultACSurl(spEntityID, realm, returnedBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major acsIndex = index.intValue();
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major if (acsIndex < 0 || acsIndex > 65535) {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major acsIndex = 0;
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major }
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major acsURL = IDPSSOUtil.getACSurlFromMetaByIndex(spEntityID, realm, acsIndex, returnedBinding);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major binding = returnedBinding.toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (isACSurlValidInMetadataSP(acsURL, spEntityID, realm)) {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major if (binding == null || binding.isEmpty()) {
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major binding = getBindingForAcsUrl(spEntityID, realm, acsURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] args = {acsURL, spEntityID};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception("libSAML2", "invalidAssertionConsumerServiceURL", args);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
e08748a19c208005b9fccd4d4ca8281519eeec3dPeter Major rBinding.append(binding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return acsURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the default assertion consumer service url and binding
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * from the metadata.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getDefaultACSurl(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major StringBuffer returnedBinding) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getDefaultACSurl: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas realm, spEntityID, classMethod);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AssertionConsumerServiceElement acs = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String binding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String firstAcsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String firstBinding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < acsList.size(); i++) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (acs.isIsDefault()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acsURL = acs.getLocation();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major binding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (i == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster firstAcsURL = acs.getLocation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster firstBinding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (acsURL == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acsURL = firstAcsURL;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major binding = firstBinding;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (binding != null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major returnedBinding.append(binding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return acsURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the assertion consumer service url binding from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * the metadata.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getBindingForAcsUrl(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String spEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String realm,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acsURL) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getBindingForAcsUrl: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas realm, spEntityID, classMethod);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AssertionConsumerServiceElement acs = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String binding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < acsList.size(); i++) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String location = acs.getLocation();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (location != null && location.equals(acsURL)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major return acs.getBinding();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the assertion consumer service <code>URL</code> from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * meta data by binding
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getACSurlFromMetaByBinding(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String desiredBinding,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major StringBuffer returnedBinding)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getACSurlFromMetaByBinding: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas realm, spEntityID, classMethod);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String binding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String defaultAcsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String defaultBinding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String firstAcsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String firstBinding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AssertionConsumerServiceElement acs = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < acsList.size(); i++) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster binding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (binding.equals(desiredBinding)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = acs.getLocation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acs.isIsDefault()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster defaultAcsURL = acs.getLocation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster defaultBinding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (i == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster firstAcsURL = acs.getLocation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster firstBinding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsURL == null || acsURL.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = defaultAcsURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsURL == null || acsURL.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = firstAcsURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsURL == null || acsURL.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get valid Assertion " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Consumer Service URL");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster returnedBinding.append(firstBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster returnedBinding.append(defaultBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster returnedBinding.append(binding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return acsURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the assertion consumer service <code>URL</code> from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * meta data by binding
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getACSurlFromMetaByIndex(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int acsIndex,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major StringBuffer returnedBinding)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getACSurlFromMetaByIndex: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas realm, spEntityID, classMethod);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int index;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String binding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String defaultAcsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String defaultBinding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String firstAcsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String firstBinding = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AssertionConsumerServiceElement acs = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < acsList.size(); i++) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster index = acs.getIndex();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster binding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (index == acsIndex) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = acs.getLocation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster binding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acs.isIsDefault()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster defaultAcsURL = acs.getLocation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster defaultBinding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (i == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster firstAcsURL = acs.getLocation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster firstBinding = acs.getBinding();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsURL == null || acsURL.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = defaultAcsURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsURL == null || acsURL.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = firstAcsURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsURL == null || acsURL.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster acsURL = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get valid Assertion " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Consumer Service URL");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster returnedBinding.append(firstBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster returnedBinding.append(defaultBinding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster returnedBinding.append(binding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return acsURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
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.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponseArtifact(HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID, String spEntityID, String realm, String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String relayState, Response res, Object session, Map props)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.sendResponseArtifact: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPSSODescriptorElement idpSSODescriptorElement = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster idpSSODescriptorElement = metaManager.getIDPSSODescriptor(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpSSODescriptorElement == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get IDP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpEntityID};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.IDP_METADATA_ERROR, data, session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("metaDataError"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SAML2MetaException sme) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get IDP SSO Descriptor from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpEntityID};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.IDP_METADATA_ERROR, data, session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("metaDataError"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major ArtifactResolutionServiceElement ars =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (ArtifactResolutionServiceElement)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpSSODescriptorElement.getArtifactResolutionService().get(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (ars == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get ArtifactResolutionServiceElement from meta.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpEntityID};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.IDP_METADATA_ERROR, data, session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("metaDataError"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Artifact art = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster art = ProtocolFactory.getInstance().createArtifact(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major null,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major ars.getIndex(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.generateSourceID(idpEntityID),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.generateMessageHandleWithServerID()
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster );
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SAML2Exception se) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to create artifact: ", se);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpEntityID};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major LogUtil.CANNOT_CREATE_ARTIFACT, data, session, props);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAMLUtils.sendError(request, response,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major response.SC_INTERNAL_SERVER_ERROR, "errorCreateArtifact",
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("errorCreateArtifact"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String artStr = art.getArtifactValue();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPCache.responsesByArtifacts.put(artStr, res);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper try {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper long expireTime = getValidTimeofResponse(realm, idpEntityID, res) / 1000;
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper SAML2FailoverUtils.saveSAML2TokenWithoutSecondaryKey(artStr,
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper res.toXMLString(true, true), expireTime);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper if (SAML2Utils.debug.messageEnabled()) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.message(classMethod + "Saved Response to SAML2 Token Repository using key "
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper + artStr);
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper }
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper } catch (SAML2TokenRepositoryException se) {
7be5aa496ae10e8d30aa6675df55e074cbb5cfedMark de Reeper SAML2Utils.debug.error(classMethod + "Unable to save Response to the SAML2 Token Repository", se);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String messageEncoding = SAML2Utils.getAttributeValueFromSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, spEntityID, SAML2Constants.SP_ROLE,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.RESPONSE_ARTIFACT_MESSAGE_ENCODING);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "messageEncoding = " + messageEncoding);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "artStr = " + artStr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((messageEncoding != null) &&
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (messageEncoding.equals(SAML2Constants.FORM_ENCODING))) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {idpEntityID, realm, acsURL};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.access(Level.INFO, LogUtil.SEND_ARTIFACT, logdata,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest SAML2Utils.postToTarget(request, response, SAML2Constants.SAML_ART,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major artStr, "RelayState", relayState, acsURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String redirectURL = acsURL +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (acsURL.contains("?") ? "&" : "?") + "SAMLart=" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major URLEncDec.encode(artStr);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((relayState != null) && (relayState.trim().length() != 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster redirectURL += "&RelayState=" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major URLEncDec.encode(relayState);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Redirect URL = " + redirectURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {idpEntityID, realm, redirectURL};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.access(Level.INFO, LogUtil.SEND_ARTIFACT, logdata,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, props);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster response.sendRedirect(redirectURL);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (IOException ioe) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to send redirect: ", ioe);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This method sends SAML Response back to ECP.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param request The servlet request.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param response The servlet response.
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * @param out The print writer for writing out presentation.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param idpEntityID the entity id of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param realm the realm name of the identity provider
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param acsURL the assertion consumer service <code>URL</code>
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @param res the <code>SAML Response</code> object
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @throws SAML2Exception if the operation is not successful
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static void sendResponseECP(HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response,
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper PrintWriter out,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID, String realm, String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Response res) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major ECPFactory ecpFactory = ECPFactory.getInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ECPResponse ecpResponse = ecpFactory.createECPResponse();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ecpResponse.setMustUnderstand(Boolean.TRUE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ecpResponse.setActor(SAML2Constants.SOAP_ACTOR_NEXT);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ecpResponse.setAssertionConsumerServiceURL(acsURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String header = ecpResponse.toXMLString(true, true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String body = res.toXMLString(true, true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings SOAPMessage reply = SOAPCommunicator.getInstance().createSOAPMessage(header, body,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] logdata = {idpEntityID, realm, acsURL, ""};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (LogUtil.isAccessLoggable(Level.FINE)) {
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings logdata[3] = SOAPCommunicator.getInstance().soapMessageToString(reply);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.access(Level.INFO, LogUtil.SEND_ECP_RESPONSE, logdata,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major null);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
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 if (reply.saveRequired()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster reply.saveChanges();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster response.setStatus(HttpServletResponse.SC_OK);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.putHeaders(reply.getMimeHeaders(), response);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Write out the message on the response stream
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper ByteArrayOutputStream stream = new ByteArrayOutputStream();
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper reply.writeTo(stream);
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper out.println(stream.toString());
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper out.flush();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception ex) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.sendResponseECP", ex);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String[] data = {idpEntityID, realm, acsURL};
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogUtil.error(Level.INFO, LogUtil.SEND_ECP_RESPONSE_FAILED, data,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major null);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAMLUtils.sendError(request, response,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failedToSendECPResponse", ex.getMessage());
0fdab8904a8fe223f6934b878769fe45e7651c60Andrew Forrest return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns the session index of an <code>IDPSession</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param session the session corresponding to the <code>IDPSession</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the session index string
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getSessionIndex(Object session) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getSessionIndex: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (session == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String[] values = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster values = sessionProvider.getProperty(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major session, SAML2Constants.IDP_SESSION_INDEX);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SessionException e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "error retrieving session index from the session: ", e);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster values = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (values == null || values.length == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String index = values[0];
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (index == null || index.length() == 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major classMethod + "Returning sessionIndex=" + index);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return index;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * Returns the authentication service <code>URL</code> of the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * identity provider
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getAuthenticationServiceURL(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String hostEntityId,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletRequest request) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getAuthenticationServiceURL: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String authUrl = getAttributeValueFromIDPSSOConfig(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster realm, hostEntityId, SAML2Constants.AUTH_URL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((authUrl == null) || (authUrl.trim().length() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // need to get it from the request
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String uri = request.getRequestURI();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String deploymentURI = uri;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int firstSlashIndex = uri.indexOf("/");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int secondSlashIndex = uri.indexOf("/", firstSlashIndex + 1);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (secondSlashIndex != -1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster deploymentURI = uri.substring(0, secondSlashIndex);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer sb = new StringBuffer(100);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster sb.append(request.getScheme()).append("://")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(request.getServerName()).append(":")
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(request.getServerPort())
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append(deploymentURI)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major .append("/UI/Login?realm=").append(realm);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster authUrl = sb.toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + "auth url=:" + authUrl);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return authUrl;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static String getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String hostEntityId,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String attrName) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String classMethod = "IDPSSOUtil.getAttributeValueFromIDPSSOConfig: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String result = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster IDPSSOConfigElement config = metaManager.getIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, hostEntityId);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map attrs = SAML2MetaUtils.getAttributes(config);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List value = (List) attrs.get(attrName);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (value != null && value.size() != 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster result = (String) value.get(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (SAML2MetaException sme) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "get IDPSSOConfig failed:", sme);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster result = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return result;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Redirects to authenticate service
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static void redirectAuthentication(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletRequest request,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major HttpServletResponse response,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AuthnRequest authnReq,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String reqID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception, IOException {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.redirectAuthentication: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the authentication service url
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer newURL = new StringBuffer(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPSSOUtil.getAuthenticationServiceURL(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID, request));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Pass spEntityID to IdP Auth Module
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (spEntityID != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (newURL.indexOf("?") == -1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append("?");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append("&");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append(SAML2Constants.SPENTITYID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append("=");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append(URLEncDec.encode(spEntityID));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // find out the authentication method, e.g. module=LDAP, from
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // authn context mapping
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPAuthnContextMapper idpAuthnContextMapper =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major getIDPAuthnContextMapper(realm, idpEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPAuthnContextInfo info =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpAuthnContextMapper.getIDPAuthnContextInfo(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major authnReq, idpEntityID, realm);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Set authnTypeAndValues = info.getAuthnTypeAndValues();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((authnTypeAndValues != null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (!authnTypeAndValues.isEmpty())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Iterator iter = authnTypeAndValues.iterator();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major StringBuffer authSB = new StringBuffer((String) iter.next());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (iter.hasNext()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major authSB.append("&");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major authSB.append((String) iter.next());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (newURL.indexOf("?") == -1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append("?");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append("&");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append(authSB.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "authString=" + authSB.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (newURL.indexOf("?") == -1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append("?goto=");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append("&goto=");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String gotoURL = request.getRequestURL().toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String gotoQuery = request.getQueryString();
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major //We are appending redirected=true to the goto URL so that we can tell if the user was already redirected
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major //to the login interface for authentication.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (gotoQuery != null) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major gotoURL += "?" + gotoQuery + "&" + REDIRECTED_TRUE;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major gotoURL += "?" + REDIRECTED_TRUE;
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (reqID != null) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major gotoURL += "&ReqID=" + reqID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "gotoURL=" + gotoURL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster newURL.append(URLEncDec.encode(gotoURL));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "New URL for authentication: " + newURL.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
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 response.sendRedirect(newURL.toString());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Signs an <code>Assertion</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static void signAssertion(String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Assertion assertion)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.signAssertion: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster KeyProvider kp = KeyUtil.getKeyProviderInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (kp == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get a key provider instance.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("nullKeyProvider"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpSignCertAlias = SAML2Utils.getSigningCertAlias(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID, SAML2Constants.IDP_ROLE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (idpSignCertAlias == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Unable to get the hosted IDP signing certificate alias.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("missingSigningCertAlias"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper String encryptedKeyPass =
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper PrivateKey key;
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper key = kp.getPrivateKey(idpSignCertAlias);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper } else {
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper key = kp.getPrivateKey(idpSignCertAlias, encryptedKeyPass);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper }
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper assertion.sign(key, kp.getX509Certificate(idpSignCertAlias));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
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.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster static void signAndEncryptResponseComponents(String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Response res,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major boolean signAssertion)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.signAndEncryptResponseComponents: ";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean toEncryptAssertion = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean toEncryptNameID = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean toEncryptAttribute = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (res == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List assertions = res.getAssertion();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((assertions == null) || (assertions.size() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Assertion assertion = (Assertion) assertions.get(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the encryption related flags from the SP Entity Config
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String wantAssertionEncrypted =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.getAttributeValueFromSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, spEntityID, SAML2Constants.SP_ROLE,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.WANT_ASSERTION_ENCRYPTED);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster toEncryptAssertion = (wantAssertionEncrypted != null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (wantAssertionEncrypted.equals(SAML2Constants.TRUE));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (!toEncryptAssertion) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String wantNameIDEncrypted =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.getAttributeValueFromSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, spEntityID, SAML2Constants.SP_ROLE,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.WANT_NAMEID_ENCRYPTED);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster toEncryptNameID = (wantNameIDEncrypted != null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (wantNameIDEncrypted.equals(SAML2Constants.TRUE));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String wantAttributeEncrypted =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.getAttributeValueFromSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, spEntityID, SAML2Constants.SP_ROLE,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.WANT_ATTRIBUTE_ENCRYPTED);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster toEncryptAttribute = (wantAttributeEncrypted != null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (wantAttributeEncrypted.equals(SAML2Constants.TRUE));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((!toEncryptAssertion) && (!toEncryptNameID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (!toEncryptAttribute)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // all encryption flags are off, no encryption needed
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signAssertion) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signAssertion(realm, idpEntityID, assertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List assertionList = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertionList.add(assertion);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major res.setAssertion(assertionList);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas realm, spEntityID, classMethod);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas // get the encryption information
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster EncInfo encInfo = KeyUtil.getEncInfo(spSSODescriptorElement,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major spEntityID, SAML2Constants.SP_ROLE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (encInfo == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failed to get service provider encryption key info.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("UnableToFindEncryptKeyInfo"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (toEncryptAssertion) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // sign assertion first, then encrypt the assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signAssertion) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signAssertion(realm, idpEntityID, assertion);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // we only encrypt the Assertion
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster EncryptedAssertion encryptedAssertion = assertion.encrypt(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getWrappingKey(), encInfo.getDataEncAlgorithm(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getDataEncStrength(), spEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (encryptedAssertion == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failed to encrypt the assertion.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("FailedToEncryptAssertion"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List assertionList = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertionList.add(encryptedAssertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setEncryptedAssertion(assertionList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setAssertion(new ArrayList()); // reset assertion list
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + "Assertion encrypted.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
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 if (toEncryptNameID) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // we need to encrypt the NameID
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Subject subject = assertion.getSubject();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (subject == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NameID nameID = subject.getNameID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (nameID == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster EncryptedID encryptedNameID = nameID.encrypt(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getWrappingKey(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getDataEncAlgorithm(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getDataEncStrength(), spEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (encryptedNameID == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failed to encrypt the NameID.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "FailedToEncryptNameID"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster subject.setEncryptedID(encryptedNameID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster subject.setNameID(null); // reset NameID
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setSubject(subject);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + "NameID encrypted.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (toEncryptAttribute) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // we need to encrypt the Attribute
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List attributeStatements = assertion.getAttributeStatements();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((attributeStatements != null)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major && (attributeStatements.size() > 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int asSize = attributeStatements.size();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // to hold all the AttributeStatements
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List stmts = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < asSize; i++) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major AttributeStatement attributeStatement =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (AttributeStatement) attributeStatements.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List attributes = attributeStatement.getAttribute();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((attributes == null) || (attributes.size() == 0)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster continue;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int aSize = attributes.size();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // holds all the encrypted Attributes in this statement
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List eaList = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int j = 0; j < aSize; j++) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Attribute attribute = (Attribute) attributes.get(j);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster EncryptedAttribute encryptedAttribute =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major attribute.encrypt(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getWrappingKey(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getDataEncAlgorithm(),
80849398a45dca1fb917716907d6ec99be6222c2Peter Major encInfo.getDataEncStrength(), spEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (encryptedAttribute == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "failed to encrypt the Attribute.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "FailedToEncryptAttribute"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster eaList.add(encryptedAttribute);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attributeStatement.setEncryptedAttribute(eaList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster attributeStatement.setAttribute(new ArrayList());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster stmts.add(attributeStatement);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertion.setAttributeStatements(stmts);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Attribute encrypted.");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (signAssertion) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster signAssertion(realm, idpEntityID, assertion);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List assertionList = new ArrayList();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster assertionList.add(assertion);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster res.setAssertion(assertionList);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major private static String getWriterURL(String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String classMethod = "IDPSSOUtil.getWriterURL: ";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String writerURL = null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major try {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // get cot list of the idp
80849398a45dca1fb917716907d6ec99be6222c2Peter Major IDPSSOConfigElement idpEntityCfg =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major metaManager.getIDPSSOConfig(realm, idpEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Map idpConfigAttrsMap = null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (idpEntityCfg != null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpConfigAttrsMap = SAML2MetaUtils.getAttributes(idpEntityCfg);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((idpConfigAttrsMap == null) || (idpConfigAttrsMap.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major return null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major List idpCOTList =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (List) idpConfigAttrsMap.get(SAML2Constants.COT_LIST);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((idpCOTList == null) || (idpCOTList.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major return null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // get cot list of the sp
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SPSSOConfigElement spEntityCfg =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major metaManager.getSPSSOConfig(realm, spEntityID);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Map spConfigAttrsMap = null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (spEntityCfg != null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major spConfigAttrsMap = SAML2MetaUtils.getAttributes(spEntityCfg);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((spConfigAttrsMap == null) || (spConfigAttrsMap.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major return null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major List spCOTList = (List) spConfigAttrsMap.get(SAML2Constants.COT_LIST);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((spCOTList == null) || (spCOTList.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major return null;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // retain in the idpCOTList the intersection of two lists
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpCOTList.retainAll(spCOTList);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major for (int i = 0; i < idpCOTList.size(); i++) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String cotName = (String) idpCOTList.get(i);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major CircleOfTrustDescriptor cotDescriptor =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major cotManager.getCircleOfTrust(realm, cotName);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major writerURL = cotDescriptor.getSAML2WriterServiceURL();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((writerURL != null) && (writerURL.trim().length() != 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major break;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major } catch (COTException ce) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod + "Error retreiving of "
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "circle of trust", ce);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major } catch (SAML2Exception se) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Not able to getting writer URL : ", se);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major } catch (Exception e) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Not able to getting writer URL : ", e);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major return writerURL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major /**
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 *
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * @return the effective time value in seconds.
80849398a45dca1fb917716907d6ec99be6222c2Peter Major */
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 realm, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.ASSERTION_EFFECTIVE_TIME_ATTRIBUTE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (effectiveTimeStr != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster effectiveTime = Integer.parseInt(effectiveTimeStr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSSOUtil.getEffectiveTime: " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got effective time from config:" + effectiveTime);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (NumberFormatException nfe) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSSOUtil.getEffectiveTime: " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "Failed to get assertion effective time from " +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "IDP SSO config: ", nfe);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster effectiveTime = SAML2Constants.ASSERTION_EFFECTIVE_TIME;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return effectiveTime;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
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 *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return the NotBefore skew value in seconds.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster protected static int getNotBeforeSkewTime(String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.getNotBeforeSkewTime:";
80849398a45dca1fb917716907d6ec99be6222c2Peter Major int notBeforeSkewTime =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.NOTBEFORE_ASSERTION_SKEW_DEFAULT;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get the assertion effective time (in seconds)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String skewTimeStr = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.ASSERTION_NOTBEFORE_SKEW_ATTRIBUTE);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (skewTimeStr != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster notBeforeSkewTime = Integer.parseInt(skewTimeStr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major "got NotBefore skew time from config:"
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + notBeforeSkewTime);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (NumberFormatException nfe) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(classMethod + "IDP SSO config: ", nfe);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major notBeforeSkewTime =
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.NOTBEFORE_ASSERTION_SKEW_DEFAULT;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + "NotBefore Skew time :" +
80849398a45dca1fb917716907d6ec99be6222c2Peter Major notBeforeSkewTime);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return notBeforeSkewTime;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static boolean assertionCacheEnabled(String realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpEntityID) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String enabled = SAML2Utils.getAttributeValueFromSSOConfig(realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpEntityID, SAML2Constants.IDP_ROLE,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.ASSERTION_CACHE_ENABLED);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return "true".equalsIgnoreCase(enabled) ? true : false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public static byte[] stringToByteArray(String input) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster char chars[] = input.toCharArray();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster byte bytes[] = new byte[chars.length];
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < chars.length; i++) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster bytes[i] = (byte) chars[i];
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return bytes;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major public static long getValidTimeofResponse(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String realm, String idpEntityID, Response response)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // in seconds
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int timeskew = SAML2Constants.ASSERTION_TIME_SKEW_DEFAULT;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String timeskewStr = getAttributeValueFromIDPSSOConfig(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Constants.ASSERTION_TIME_SKEW);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (timeskewStr != null && timeskewStr.trim().length() > 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster timeskew = Integer.parseInt(timeskewStr);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (timeskew < 0) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster timeskew = SAML2Constants.ASSERTION_TIME_SKEW_DEFAULT;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message("timeskew = " + timeskew);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major List assertions = response.getAssertion();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if ((assertions == null) || (assertions.size() == 0)) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major // failed case
80849398a45dca1fb917716907d6ec99be6222c2Peter Major return (System.currentTimeMillis()
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + getEffectiveTime(realm, idpEntityID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + timeskew * 1000);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Assertion assertion = (Assertion) assertions.get(0);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Conditions cond = assertion.getConditions();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (cond == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception("nullConditions");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Date notOnOrAfter = cond.getNotOnOrAfter();
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
80849398a45dca1fb917716907d6ec99be6222c2Peter Major long ret = notOnOrAfter.getTime() + timeskew * 1000;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (notOnOrAfter == null ||
80849398a45dca1fb917716907d6ec99be6222c2Peter Major (ret < System.currentTimeMillis())) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (SAML2Utils.debug.messageEnabled()) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.message("Time in Assertion "
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + " is invalid.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("invalidTimeOnResponse"));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major return ret;
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
80849398a45dca1fb917716907d6ec99be6222c2Peter Major * Signs SAMLv2 Response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
80849398a45dca1fb917716907d6ec99be6222c2Peter Major private static void signResponse(String realm, String idpEntityID,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major Response response) throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil:signResponse";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster KeyProvider kp = KeyUtil.getKeyProviderInstance();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (kp == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod
80849398a45dca1fb917716907d6ec99be6222c2Peter Major + "Unable to get a key provider instance.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("nullKeyProvider"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String idpSignCertAlias = SAML2Utils.getSigningCertAlias(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major realm, idpEntityID, SAML2Constants.IDP_ROLE);
80849398a45dca1fb917716907d6ec99be6222c2Peter Major if (idpSignCertAlias == null) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.debug.error(classMethod +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Unable to get the hosted IDP signing certificate alias.");
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throw new SAML2Exception(
80849398a45dca1fb917716907d6ec99be6222c2Peter Major SAML2Utils.bundle.getString("missingSigningCertAlias"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper String encryptedKeyPass =
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper PrivateKey key;
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper key = kp.getPrivateKey(idpSignCertAlias);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper } else {
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper key = kp.getPrivateKey(idpSignCertAlias, encryptedKeyPass);
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper }
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper
0cd8368ca65c58915ee90bc73d84e65f3da9e120Mark de Reeper response.sign(key, kp.getX509Certificate(idpSignCertAlias));
80849398a45dca1fb917716907d6ec99be6222c2Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Returns a <code>SAML2IdentityProviderAdapter</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
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
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings public static SAML2IdentityProviderAdapter getIDPAdapterClass(String realm, String idpEntityID)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
7da3f239ac3deab008336f663f21e82d5d01aeadJonathan Scudder return SAML2Utils.getIDPAdapterClass(realm, idpEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Validates if the Assertion Consumer Service URL acsURL exists in the
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * metadata of the Service Provider spEntityID
80849398a45dca1fb917716907d6ec99be6222c2Peter Major *
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 */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private static boolean isACSurlValidInMetadataSP(String acsURL,
80849398a45dca1fb917716907d6ec99be6222c2Peter Major String spEntityID, String realm)
80849398a45dca1fb917716907d6ec99be6222c2Peter Major throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean isValidACSurl = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String classMethod = "IDPSSOUtil.isACSurlValidInMetadataSP: ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptorElement = getSPSSODescriptor(
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas realm, spEntityID, classMethod);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List acsList = spSSODescriptorElement.getAssertionConsumerService();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster AssertionConsumerServiceElement acs = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster for (int i = 0; i < acsList.size(); i++) {
80849398a45dca1fb917716907d6ec99be6222c2Peter Major acs = (AssertionConsumerServiceElement) acsList.get(i);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String acsInMeta = acs.getLocation();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (acsInMeta.equalsIgnoreCase(acsURL)) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster isValidACSurl = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(classMethod + " acsURL=" + acsURL +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "Found in the metadata");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster break;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
80849398a45dca1fb917716907d6ec99be6222c2Peter Major
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return isValidACSurl;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas /**
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * Returns the the value of the wantAssertionsSigned property
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param spEntityID ID of the SP entity to be retrieved.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param realm The realm under which the entity resides.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @return boolean value of the wantAssertionsSigned property.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @throws SAML2MetaException if unable to retrieve the service
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * provider's SSO descriptor.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas */
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas private static boolean wantAssertionsSigned(String realm, String spEntityID) throws SAML2Exception {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas String method = "IPDSSOUtil:wantAssertionsSigned : ";
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas if (SAML2Utils.debug.messageEnabled()) {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SAML2Utils.debug.message(method + ": realm - " + realm + "/: spEntityID - " + spEntityID);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptor = getSPSSODescriptor(spEntityID, realm, method);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas return spSSODescriptor.isWantAssertionsSigned();
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas /**
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * Returns the service provider's SSO descriptor in an entity under the realm.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param realm The realm under which the entity resides.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param spEntityID ID of the SP entity to be retrieved.
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @param classMethod the calling class method
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @return <code>SPSSODescriptorElement</code> for the entity
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas * @throws SAML2Exception if entity is not found
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas */
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas private static SPSSODescriptorElement getSPSSODescriptor(String realm,
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas String spEntityID, String classMethod)
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas throws SAML2Exception {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SPSSODescriptorElement spSSODescriptor = null;
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas if (metaManager == null) {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SAML2Utils.debug.error(classMethod + "Unable to get meta manager.");
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas throw new SAML2Exception(SAML2Utils.bundle.getString("errorMetaManager"));
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas try {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas spSSODescriptor = metaManager.getSPSSODescriptor(realm, spEntityID);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas if (spSSODescriptor == null) {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SAML2Utils.debug.error(classMethod
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas + "Unable to get SP SSO Descriptor from metadata, descriptor is null.");
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas String[] data = { spEntityID };
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas } catch (SAML2MetaException sme) {
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas SAML2Utils.debug.error(classMethod + "Unable to get SP SSO Descriptor from metadata, descriptor is null.");
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas String[] data = { spEntityID };
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas return spSSODescriptor;
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas }
c6826ecffee2d21d0127af063ffaa4d0c7b153baJon Jonthomas
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major /**
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * Check that the authenticated session belongs to the same realm where the IDP is defined.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major *
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * @param realm The realm where the IdP is defined.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * @param session The Session object of the authenticated user.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major * @return true If the session was initiated in the same realm as the session's realm.
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major */
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings public static boolean isValidSessionInRealm(String realm, Object session) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String classMethod = "IDPSSOUtil.isValidSessionInRealm: ";
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major boolean isValidSessionInRealm = false;
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major try {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major // A user can only be authenticated in one realm
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major String sessionRealm = SAML2Utils.getSingleValuedSessionProperty(session, SAML2Constants.ORGANIZATION);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (sessionRealm != null && !sessionRealm.isEmpty()) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (realm.equalsIgnoreCase(sessionRealm)) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major isValidSessionInRealm = true;
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major } else {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major if (SAML2Utils.debug.warningEnabled()) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.warning(classMethod + "Invalid realm for the session:" + sessionRealm
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major + ", while the realm of the IdP is:" + realm);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major } catch (SessionException ex) {
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major SAML2Utils.debug.error(classMethod + "Could not retrieve the session information", ex);
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major return isValidSessionInRealm;
e2a4ad8aa03f07545518b54a7a0b4853b4eb7e88Peter Major }
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major private static List<String> extractAuthenticatingAuthorities(Assertion assertion) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final List<String> authenticatingAuthorities = new ArrayList<String>();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final List<AuthnStatement> authnStatements = assertion.getAuthnStatements();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major if (authnStatements != null) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major for (AuthnStatement authnStatement : authnStatements) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major final List<String> authorities = authnStatement.getAuthnContext().getAuthenticatingAuthority();
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major if (authorities != null) {
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major authenticatingAuthorities.addAll(authorities);
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major }
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major }
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major }
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major return authenticatingAuthorities;
c2ef82503e46505b74eb802c0dcf41c303d18779Peter Major }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}