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