spSingleLogoutPOST.jsp revision 2075f399f27e30aaf713035e00b82e75bbb58f4c
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Copyright (c) 2008 Sun Microsystems Inc. All Rights Reserved
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync The contents of this file are subject to the terms
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync of the Common Development and Distribution License
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync (the License). You may not use this file except in
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync compliance with the License.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync You can obtain a copy of the License at
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync https://opensso.dev.java.net/public/CDDLv1.0.html or
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync See the License for the specific language governing
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync permission and limitations under the License.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync When distributing Covered Code, include this CDDL
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Header Notice in each file and include the License file
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync If applicable, add the following below the CDDL Header,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync with the fields enclosed by brackets [] replaced by
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync your own identifying information:
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "Portions Copyrighted [year] [name of copyright owner]"
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync $Id: spSingleLogoutPOST.jsp,v 1.8 2009/06/24 23:05:31 mrudulahg Exp $
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Portions Copyrighted 2013-2014 ForgeRock AS
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.sae.api.SecureAttrs" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml.common.SAMLUtils" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.common.SAML2Utils" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.common.SAML2Constants" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.common.SAML2Exception" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.meta.SAML2MetaUtils" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.meta.SAML2MetaManager" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.profile.CacheObject" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.profile.SPCache" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.profile.SPSingleLogout" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.profile.IDPCache" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.protocol.LogoutRequest" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="com.sun.identity.saml2.profile.IDPProxyUtil" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="java.util.HashMap" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="java.util.List" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="java.util.Map" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="java.util.Properties" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="org.owasp.esapi.ESAPI" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync<%@ page import="java.io.PrintWriter" %>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync - receives the LogoutRequest and sends the LogoutResponse to
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Identity Provider from the Service Provider.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync - receives the LogoutResponse from the Identity Provider.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Required parameters to this jsp are :
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync - RelayState - the target URL on successful Single Logout
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync - SAMLRequest - the LogoutRequest
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync - SAMLResponse - the LogoutResponse
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Check the SAML2 Documentation for supported parameters.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync // Retrieves the LogoutRequest or LogoutResponse
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync //Retrieves :
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync //- RelayState - the target URL on successful Single Logout
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync //- SAMLRequest - the LogoutRequest
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync //- SAMLResponse - the LogoutResponse
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String relayState = request.getParameter(SAML2Constants.RELAY_STATE);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (relayState != null) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync CacheObject tmpRs=
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync (CacheObject) SPCache.relayStateHash.remove(relayState);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if ((tmpRs != null)) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync relayState = (String) tmpRs.getObject();
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (!ESAPI.validator().isValidInput("HTTP Query String: " + relayState, relayState, "HTTPQueryString", 2000, true)) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync relayState = null;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String samlResponse = request.getParameter(SAML2Constants.SAML_RESPONSE);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (samlResponse != null) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Gets and processes the Single <code>LogoutResponse</code> from IDP,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * destroys the local session, checks response's issuer
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * and inResponseTo.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @param request the HttpServletRequest.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @param response the HttpServletResponse.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @param samlResponse <code>LogoutResponse</code> in the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * XML string format.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @param relayState the target URL on successful
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * <code>LogoutResponse</code>.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @throws SAML2Exception if error processing
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * <code>LogoutResponse</code>.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Map infoMap =
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SPSingleLogout.processLogoutResponse(request,response,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync samlResponse, relayState);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String inRes = (String) infoMap.get("inResponseTo");
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync LogoutRequest origLogoutRequest = (LogoutRequest)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (origLogoutRequest != null && !origLogoutRequest.equals("")) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync IDPProxyUtil.sendProxyLogoutResponse(response, request,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync } catch (SAML2Exception sse) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2Utils.debug.error("Error processing LogoutResponse :", sse);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAMLUtils.sendError(request, response, response.SC_BAD_REQUEST,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "LogoutResponseProcessingError",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2Utils.bundle.getString("LogoutResponseProcessingError") +
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync } catch (Exception e) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2Utils.debug.error("Error processing LogoutResponse ",e);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAMLUtils.sendError(request, response, response.SC_BAD_REQUEST,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "LogoutResponseProcessingError",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2Utils.bundle.getString("LogoutResponseProcessingError") +
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync boolean isRelayStateURLValid = false;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync isRelayStateURLValid = relayState != null && !relayState.isEmpty()
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync && SAML2Utils.isRelayStateURLValid(request, relayState, SAML2Constants.SP_ROLE)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync && ESAPI.validator().isValidInput("RelayState", relayState, "URL", 2000, true);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2MetaManager manager = new SAML2MetaManager();
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String metaAlias = null;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync List<String> spMetaAliases = manager.getAllHostedServiceProviderMetaAliases("/");
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (spMetaAliases != null && !spMetaAliases.isEmpty()) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync // get first one
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync metaAlias = spMetaAliases.get(0);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync isRelayStateURLValid = relayState != null && !relayState.isEmpty()
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync && SAML2Utils.isRelayStateURLValid(metaAlias, relayState, SAML2Constants.SP_ROLE)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync && ESAPI.validator().isValidInput("RelayState", relayState, "URL", 2000, true);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (isRelayStateURLValid) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync } catch (java.io.IOException ioe) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "Exception when redirecting to " +
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync relayState, ioe);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync <jsp:forward page="/saml2/jsp/default.jsp?message=spSloSuccess" />
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String samlRequest = request.getParameter(SAML2Constants.SAML_REQUEST);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (samlRequest != null) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync // Logout SP app via SAE first. App is obligated to redirect back
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync // to complete this SLO request.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (processSAELogout(request, response)) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Gets and processes the Single <code>LogoutRequest</code> from
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @param request the HttpServletRequest.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @param response the HttpServletResponse.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @param samlRequest <code>LogoutRequest</code> in the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * XML string format.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @param relayState the target URL on successful
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * <code>LogoutRequest</code>.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * @throws SAML2Exception if error processing
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * <code>LogoutRequest</code>.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SPSingleLogout.processLogoutRequest(request,response, new PrintWriter(out, true),
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync samlRequest,relayState);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync } catch (SAML2Exception sse) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2Utils.debug.error("Error processing LogoutRequest :", sse);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAMLUtils.sendError(request, response, response.SC_BAD_REQUEST,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "LogoutRequestProcessingError",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2Utils.bundle.getString("LogoutRequestProcessingError")
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync } catch (Exception e) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2Utils.debug.error("Error processing LogoutRequest ",e);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAMLUtils.sendError(request, response, response.SC_BAD_REQUEST,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "LogoutRequestProcessingError",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2Utils.bundle.getString("LogoutRequestProcessingError")
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncboolean processSAELogout(
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync HttpServletRequest request, HttpServletResponse response)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String saeData = request.getParameter(SecureAttrs.SAE_PARAM_APPRETURN);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (saeData != null) { // App returned back.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync return false;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String metaAlias =
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2MetaUtils.getMetaAliasByUri(request.getRequestURI()) ;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String realm = SAML2MetaUtils.getRealmByMetaAlias(metaAlias);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SAML2MetaManager mm = SAML2Utils.getSAML2MetaManager();
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String entityId = mm.getEntityByMetaAlias(metaAlias);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync SPSSOConfigElement spConfig = mm.getSPSSOConfig(realm, entityId);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync String appSLOUrlStr = null;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (spConfig != null) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync appSLOUrlStr = SAML2Utils.getAttributeValueFromSPSSOConfig(
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync if (appSLOUrlStr == null) {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "spSLOPOST:SAE:appSLOUrl not configured.");
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync return false;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "spSLOPOST:SAE:processing App SLO"+ appSLOUrlStr);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync StringBuffer appSLOUrl = new StringBuffer(appSLOUrlStr);
realm, entityId, SAML2Constants.SP_ROLE, appSLOUrlStr);
String encAlg = (String)hp.get(
String encStrength = (String)hp.get(
if (SecureAttrs.SAE_CRYPTO_TYPE_SYM.equals(cryptoType)) {
if (secret == null || secret.length() == 0) {
"spSLOPOST:SAE:processing App SLO:getSAEAttrs no secret/key");
String returnURL = request.getRequestURL()+
"?"+request.getQueryString()+"&"+
SecureAttrs.SAE_PARAM_APPRETURN+"=true";
SecureAttrs sa = SecureAttrs.getInstance(saInstanceName);
SecureAttrs.SAE_CONFIG_ENCRYPTION_KEY_STRENGTH,encStrength); }
SecureAttrs.init(saInstanceName, cryptoType, prop);
sa = SecureAttrs.getInstance(saInstanceName);
String encodedString = sa.getEncodedString(map, secret, encSecret);
if (appSLOUrl.indexOf("?") > 0) {
if (SAML2Utils.debug.messageEnabled()) {
SAML2Utils.debug.message("spSLOPOST:SAE:about to redirect"+
"spSLOPOST:SAE:SecureAttrs.getEncodedStr failed");