a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Copyright (c) 2009 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: DefaultFedletAdapter.java,v 1.2 2009/06/17 03:09:13 exu Exp $
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster *
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpackage com.sun.identity.saml2.plugins;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.common.HttpURLConnectionManager;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.assertion.NameID;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Constants;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Exception;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.common.SAML2Utils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.jaxb.entityconfig.BaseConfigType;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.meta.SAML2MetaUtils;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.LogoutRequest;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.saml2.protocol.LogoutResponse;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport com.sun.identity.shared.encode.URLEncDec;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.servlet.http.HttpServletRequest;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport javax.servlet.http.HttpServletResponse;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.io.OutputStream;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.net.HttpURLConnection;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.net.URL;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Iterator;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.Map;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterimport java.util.List;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * The <code>DefaultFedletAdapter</code> class provides default implementation
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * for <code>FedletAdapter</code>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterpublic class DefaultFedletAdapter extends FedletAdapter {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private String logoutUrl = null;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Initializes the fedlet adapter, this method will only be executed
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * once after creation of the adapter instance.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param initParams initial set of parameters configured in the fedlet
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * for this adapter. One of the parameters named
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>HOSTED_ENTITY_ID</code> refers to the ID of this
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * fedlet entity.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void initialize(Map initParams) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Invokes after Fedlet receives SLO request from IDP. It does the work
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * of logout the user.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param request servlet request
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param response servlet response
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param hostedEntityID entity ID for the fedlet
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID entity id for the IDP to which the request is
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * received from.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param siList List of SessionIndex whose session to be logged out
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param nameIDValue nameID value whose session to be logged out
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param binding Single Logout binding used,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * one of following values:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.SOAP</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.HTTP_POST</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.HTTP_REDIRECT</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @return <code>true</code> if user is logged out successfully;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>false</code> otherwise.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @exception SAML2Exception if user want to fail the process.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public boolean doFedletSLO (
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpServletRequest request,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpServletResponse response,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogoutRequest logoutReq,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String hostedEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List siList,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String nameIDValue,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String binding)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean status = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String method = "DefaultFedletAdapter:doFedletSLO:";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (logoutUrl == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster BaseConfigType spConfig = SAML2Utils.getSAML2MetaManager()
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster .getSPSSOConfig("/", hostedEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List appLogoutURL = (List) SAML2MetaUtils.getAttributes(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spConfig).get(SAML2Constants.APP_LOGOUT_URL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((appLogoutURL != null) && !appLogoutURL.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster logoutUrl = (String) appLogoutURL.get(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (logoutUrl == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String deployuri = request.getRequestURI();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int slashLoc = deployuri.indexOf("/", 1);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (slashLoc != -1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster deployuri = deployuri.substring(0, slashLoc);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (deployuri != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String url = request.getRequestURL().toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int loc = url.indexOf(deployuri + "/");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (loc != -1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster logoutUrl = url.substring(0, loc + deployuri.length()) +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "/logout";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (logoutUrl == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return status;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster URL url = new URL(logoutUrl);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpURLConnection conn =
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpURLConnectionManager.getConnection(url);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setDoOutput(true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestMethod("POST");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setFollowRedirects(false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setInstanceFollowRedirects(false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // replay cookies
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String strCookies = SAML2Utils.getCookiesString(request);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (strCookies != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(method + "Sending cookies : " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster strCookies);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("Cookie", strCookies);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("Content-Type",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "application/x-www-form-urlencoded");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("IDP", URLEncDec.encode(idpEntityID));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("SP", URLEncDec.encode(hostedEntityID));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "NameIDValue", URLEncDec.encode(nameIDValue));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (siList != null && !siList.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Iterator iter = siList.iterator();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster StringBuffer siValue = new StringBuffer();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster siValue.append((String)iter.next());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster while (iter.hasNext()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster siValue.append(",").append((String)iter.next());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "SessionIndex", URLEncDec.encode(siValue.toString()));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("Binding", binding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster OutputStream outputStream = conn.getOutputStream();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Write the request to the HTTP server.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster outputStream.write("".getBytes());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster outputStream.flush();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster outputStream.close();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Check response code
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(method + "Response code OK");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster status = true;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(method + "Response code NOT OK: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + conn.getResponseCode());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster status = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster status = false;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return status;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Invokes after Fedlet receives SLO response from IDP and the SLO status
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * is success.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param request servlet request
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param response servlet response
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param logoutReq SAML2 <code>LogoutRequest</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param logoutRes SAML2 <code>LogoutResponse</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param hostedEntityID entity ID for the fedlet
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID entity id for the IDP to which the logout response
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * is received from.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param binding Single Logout binding used,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * one of following values:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.SOAP</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.HTTP_POST</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.HTTP_REDIRECT</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @exception SAML2Exception if user want to fail the process.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void onFedletSLOSuccess(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpServletRequest request,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpServletResponse response,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogoutRequest logoutReq,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogoutResponse logoutRes,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String hostedEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String binding)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster onFedletSLOSuccessOrFailure(request, response, logoutReq,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster logoutRes, hostedEntityID, idpEntityID, binding, true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /**
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * Invokes after Fedlet receives SLO response from IDP and the SLO status
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * is not success.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param request servlet request
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param response servlet response
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param logoutReq SAML2 <code>LogoutRequest</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param logoutRes SAML2 <code>LogoutResponse</code> object
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param hostedEntityID entity ID for the fedlet
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param idpEntityID entity id for the IDP to which the logout response
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * is received from.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @param binding Single Logout binding used,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * one of following values:
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.SOAP</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.HTTP_POST</code>,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * <code>SAML2Constants.HTTP_REDIRECT</code>
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * @exception SAML2Exception if user want to fail the process.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster public void onFedletSLOFailure(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpServletRequest request,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpServletResponse response,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogoutRequest logoutReq,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogoutResponse logoutRes,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String hostedEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String binding)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster onFedletSLOSuccessOrFailure(request, response, logoutReq,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster logoutRes, hostedEntityID, idpEntityID, binding, false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster private void onFedletSLOSuccessOrFailure(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpServletRequest request,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpServletResponse response,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogoutRequest logoutReq,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster LogoutResponse logoutRes,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String hostedEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String idpEntityID,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String binding,
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster boolean isSuccess)
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster throws SAML2Exception {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String method = "DefaultFedletAdapter:onFedletSLOSuccessOrFailure:";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster try {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (logoutUrl == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster BaseConfigType spConfig = SAML2Utils.getSAML2MetaManager()
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster .getSPSSOConfig("/", hostedEntityID);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List appLogoutURL = (List) SAML2MetaUtils.getAttributes(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster spConfig).get(SAML2Constants.APP_LOGOUT_URL);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((appLogoutURL != null) && !appLogoutURL.isEmpty()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster logoutUrl = (String) appLogoutURL.get(0);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (logoutUrl == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String deployuri = request.getRequestURI();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int slashLoc = deployuri.indexOf("/", 1);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (slashLoc != -1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster deployuri = deployuri.substring(0, slashLoc);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (deployuri != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String url = request.getRequestURL().toString();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster int loc = url.indexOf(deployuri + "/");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (loc != -1) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster logoutUrl = url.substring(0, loc + deployuri.length()) +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "/logout";
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (logoutUrl == null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster URL url = new URL(logoutUrl);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpURLConnection conn =
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster HttpURLConnectionManager.getConnection(url);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setDoOutput(true);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestMethod("POST");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setFollowRedirects(false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setInstanceFollowRedirects(false);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // replay cookies
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster String strCookies = SAML2Utils.getCookiesString(request);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (strCookies != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(method + "Sending cookies : " +
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster strCookies);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("Cookie", strCookies);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("Content-Type",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "application/x-www-form-urlencoded");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("IDP", URLEncDec.encode(idpEntityID));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("SP", URLEncDec.encode(hostedEntityID));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (logoutReq != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster NameID nameID = logoutReq.getNameID();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (nameID != null) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty(
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster "NameIDValue", URLEncDec.encode(nameID.getValue()));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster List siList = logoutReq.getSessionIndex();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if ((siList != null) && (!siList.isEmpty())) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("SessionIndex",
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster URLEncDec.encode((String)siList.get(0)));
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("Binding", binding);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (isSuccess) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("SLOStatus", "Success");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster conn.setRequestProperty("SLOStatus", "Failure");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster OutputStream outputStream = conn.getOutputStream();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Write the request to the HTTP server.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster outputStream.write("".getBytes());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster outputStream.flush();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster outputStream.close();
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster // Check response code
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster if (SAML2Utils.debug.messageEnabled()) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.message(method + "Response code OK");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } else {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster SAML2Utils.debug.error(method + "Response code NOT OK: "
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster + conn.getResponseCode());
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster } catch (Exception e) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster return;
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster }
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster}