a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The contents of this file are subject to the terms
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * of the Common Development and Distribution License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * (the License). You may not use this file except in
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * compliance with the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * You can obtain a copy of the License at
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * See the License for the specific language governing
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * permission and limitations under the License.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * When distributing Covered Code, include this CDDL
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Header Notice in each file and include the License file
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * If applicable, add the following below the CDDL Header,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * with the fields enclosed by brackets [] replaced by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * your own identifying information:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * $Id: IDPSingleLogoutServiceSOAP.java,v 1.10 2009/10/14 23:59:44 exu Exp $
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper * Portions Copyrighted 2015 ForgeRock AS.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Constants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Exception;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Utils;
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbingsimport com.sun.identity.saml2.common.SOAPCommunicator;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.meta.SAML2MetaUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.profile.LogoutUtil;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.profile.IDPProxyUtil;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.profile.IDPSession;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.profile.IDPSingleLogout;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.LogoutRequest;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.LogoutResponse;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.ProtocolFactory;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * This class <code>IDPSingleLogoutServiceSOAP</code> receives and processes
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * single logout request using SOAP binding on IDP side.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpublic class IDPSingleLogoutServiceSOAP extends HttpServlet {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // handle DOS attack
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Get IDP entity ID
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpMetaAlias = SAML2MetaUtils.getMetaAliasByUri(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpEntityID = SAML2Utils.getSAML2MetaManager().
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String realm = SAML2MetaUtils.getRealmByMetaAlias(idpMetaAlias);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster realm, idpEntityID, SAML2Constants.SLO_SERVICE,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throw new SAML2Exception(SAML2Utils.bundle.getString(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "unsupportedBinding"));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSLOSOAP.doPost : uri =" +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster req.getRequestURI() +", idpMetaAlias=" + idpMetaAlias
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings SOAPMessage msg = SOAPCommunicator.getInstance().getSOAPMessage(req);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Map aMap = IDPProxyUtil.getSessionPartners(msg);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List partners = (List) aMap.get(SAML2Constants.PARTNERS);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster reply = onMessage(msg, req, resp, idpEntityID, realm);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // IDP Proxy case
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (partners != null && (!partners.isEmpty())) {
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings Element reqElem = SOAPCommunicator.getInstance().getSamlpElement(msg,
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings "LogoutRequest");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ProtocolFactory.getInstance().createLogoutRequest(
c36b3d48cd721148c2ed02c273ecf4f38e1add70Mark de Reeper IDPProxyUtil.sendProxyLogoutRequestSOAP(req, resp, resp.getWriter(),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Need to call saveChanges because we're
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // going to use the MimeHeaders to set HTTP
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // response information. These MimeHeaders
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // are generated as part of the save.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.putHeaders(reply.getMimeHeaders(), resp);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Write out the message on the response stream
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP", ex);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP", soap);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Process the incoming SOAP message containing the LogoutRequest and
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * generates outgoing SOAP message containing the LogoutResponse on IDP
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param message incoming SOAP message.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param request HTTP servlet request.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param response HTTP servlet response.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID Entity ID of the hosted IDP.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param realm realm of this hosted IDP.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return SOAP message containing the outgoing LogoutResponse.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message("IDPSingleLogoutServiceSOAP.onMessage: init");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // get LogoutRequest element from SOAP message
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings Element reqElem = SOAPCommunicator.getInstance().getSamlpElement(message,
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings "LogoutRequest");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster ProtocolFactory.getInstance().createLogoutRequest(reqElem);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // delay the signature until this server finds the session
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "unable to get LogoutRequest from message", se);
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // TODO decrypt LogoutRequest if any
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // TODO, handle signature verification
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "LogoutRequest is null");
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // process LogoutRequestElement
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster loRes = IDPSingleLogout.processLogoutRequest(logoutReq, request,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster response, SAML2Constants.SOAP, null, idpEntityID, realm, false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogoutUtil.signSLOResponse(loRes, realm, idpEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Constants.IDP_ROLE, logoutReq.getIssuer().getValue());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage;", e);
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "LogoutResponse is null");
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT,
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings msg = SOAPCommunicator.getInstance().createSOAPMessage(loRes.toXMLString(true, true),
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " +
449854c2a07b50ea64d9d6a8b03d18d4afeeee43Ken Stubbings return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error("IDPSingleLogoutServiceSOAP.onMessage: " +