Search in sources :

Example 16 with LogoutRequest

use of com.sun.identity.saml2.protocol.LogoutRequest in project OpenAM by OpenRock.

the class SPSingleLogout method processLogoutRequest.

/**
     * Gets and processes the Single <code>LogoutRequest</code> from IDP.
     *
     * @param request the HttpServletRequest.
     * @param response the HttpServletResponse.
     * @param out the print writer for writing out presentation
     * @param samlRequest <code>LogoutRequest</code> in the
     *          XML string format.
     * @param relayState the target URL on successful
     * <code>LogoutRequest</code>.
     * @throws SAML2Exception if error processing
     *          <code>LogoutRequest</code>.
     * @throws SessionException if error processing
     *          <code>LogoutRequest</code>.
     */
public static void processLogoutRequest(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String samlRequest, String relayState) throws SAML2Exception, SessionException {
    String method = "processLogoutRequest : ";
    if (debug.messageEnabled()) {
        debug.message(method + "samlRequest : " + samlRequest);
        debug.message(method + "relayState : " + relayState);
    }
    String rmethod = request.getMethod();
    String binding = SAML2Constants.HTTP_REDIRECT;
    if (rmethod.equals("POST")) {
        binding = SAML2Constants.HTTP_POST;
    }
    String metaAlias = SAML2MetaUtils.getMetaAliasByUri(request.getRequestURI());
    if ((SPCache.isFedlet) && ((metaAlias == null) || (metaAlias.length() == 0))) {
        List spMetaAliases = sm.getAllHostedServiceProviderMetaAliases("/");
        if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) {
            // get first one
            metaAlias = (String) spMetaAliases.get(0);
        }
        if ((metaAlias == null) || (metaAlias.length() == 0)) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullSPEntityID"));
        }
    }
    String realm = SAML2Utils.getRealm(SAML2MetaUtils.getRealmByMetaAlias(metaAlias));
    String spEntityID = sm.getEntityByMetaAlias(metaAlias);
    if (!SAML2Utils.isSPProfileBindingSupported(realm, spEntityID, SAML2Constants.SLO_SERVICE, binding)) {
        throw new SAML2Exception(SAML2Utils.bundle.getString("unsupportedBinding"));
    }
    LogoutRequest logoutReq = null;
    if (rmethod.equals("POST")) {
        logoutReq = LogoutUtil.getLogoutRequestFromPost(samlRequest, response);
    } else if (rmethod.equals("GET")) {
        String decodedStr = SAML2Utils.decodeFromRedirect(samlRequest);
        if (decodedStr == null) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullDecodedStrFromSamlRequest"));
        }
        logoutReq = ProtocolFactory.getInstance().createLogoutRequest(decodedStr);
    }
    if (logoutReq == null) {
        if (debug.messageEnabled()) {
            debug.message("SPSingleLogout:processLogoutRequest: logoutReq " + "is null");
        }
        return;
    }
    String location = null;
    String idpEntityID = logoutReq.getIssuer().getValue();
    // invoke SPAdapter preSingleLogoutProcess : IDP initiated HTTP
    //String userId = preSingleLogoutProcess(spEntityID, realm, request, 
    //    response, null, logoutReq, null, SAML2Constants.HTTP_REDIRECT); 
    boolean needToVerify = SAML2Utils.getWantLogoutRequestSigned(realm, spEntityID, SAML2Constants.SP_ROLE);
    if (debug.messageEnabled()) {
        debug.message(method + "metaAlias : " + metaAlias);
        debug.message(method + "realm : " + realm);
        debug.message(method + "idpEntityID : " + idpEntityID);
        debug.message(method + "spEntityID : " + spEntityID);
    }
    if (needToVerify == true) {
        boolean valid = false;
        if (rmethod.equals("POST")) {
            valid = LogoutUtil.verifySLORequest(logoutReq, realm, idpEntityID, spEntityID, SAML2Constants.SP_ROLE);
        } else {
            String queryString = request.getQueryString();
            valid = SAML2Utils.verifyQueryString(queryString, realm, SAML2Constants.SP_ROLE, idpEntityID);
        }
        if (!valid) {
            debug.error("SPSingleLogout.processLogoutRequest: " + "Invalid signature in SLO Request.");
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSignInRequest"));
        }
        SPSSODescriptorElement spsso = sm.getSPSSODescriptor(realm, spEntityID);
        String loc = getSLOResponseLocationOrLocation(spsso, binding);
        if (!SAML2Utils.verifyDestination(logoutReq.getDestination(), loc)) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidDestination"));
        }
    }
    // get IDPSSODescriptor
    IDPSSODescriptorElement idpsso = sm.getIDPSSODescriptor(realm, idpEntityID);
    if (idpsso == null) {
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
    List slosList = idpsso.getSingleLogoutService();
    if (slosList == null) {
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.SLO_NOT_FOUND, data, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("sloServiceListNotfound"));
    }
    location = LogoutUtil.getSLOResponseServiceLocation(slosList, binding);
    if (location == null || location.length() == 0) {
        location = LogoutUtil.getSLOServiceLocation(slosList, binding);
        if (location == null || location.length() == 0) {
            debug.error("Unable to find the IDP's single logout " + "response service with the HTTP-Redirect binding");
            throw new SAML2Exception(SAML2Utils.bundle.getString("sloResponseServiceLocationNotfound"));
        } else {
            if (debug.messageEnabled()) {
                debug.message("SP's single logout response service location = " + location);
            }
        }
    } else {
        if (debug.messageEnabled()) {
            debug.message("IDP's single logout response service location = " + location);
        }
    }
    List partners = IDPProxyUtil.getSPSessionPartners(request);
    //IDP Proxy Case
    if (partners != null && !partners.isEmpty()) {
        LogoutResponse logoutRespon = processLogoutRequest(logoutReq, spEntityID, realm, request, response, false, false, binding, true);
        logoutRespon.setDestination(XMLUtils.escapeSpecialCharacters(location));
        IDPProxyUtil.sendIDPInitProxyLogoutRequest(request, response, out, logoutRespon, location, spEntityID, idpEntityID, binding, realm);
    } else {
        LogoutResponse logoutRes = processLogoutRequest(logoutReq, spEntityID, realm, request, response, true, binding, true);
        logoutRes.setDestination(XMLUtils.escapeSpecialCharacters(location));
        LogoutUtil.sendSLOResponse(response, request, logoutRes, location, relayState, realm, spEntityID, SAML2Constants.SP_ROLE, idpEntityID, binding);
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) LogoutResponse(com.sun.identity.saml2.protocol.LogoutResponse) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) List(java.util.List) ArrayList(java.util.ArrayList) LogoutRequest(com.sun.identity.saml2.protocol.LogoutRequest) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)

Example 17 with LogoutRequest

use of com.sun.identity.saml2.protocol.LogoutRequest in project OpenAM by OpenRock.

the class LogoutRequestImpl method toXMLString.

/**
     * Returns the <code>LogoutRequest</code> in an XML document String format
     * based on the <code>LogoutRequest</code> schema described above.
     *
     * @param includeNSPrefix Determines whether or not the namespace qualifier
     *        is prepended to the Element when converted
     * @param declareNS Determines whether or not the namespace is declared
     *        within the Element.
     * @return A XML String representing the <code>LogoutRequest</code>.
     * @throws SAML2Exception if some error occurs during conversion to
     *         <code>String</code>.
     */
public String toXMLString(boolean includeNSPrefix, boolean declareNS) throws SAML2Exception {
    if (isSigned && signedXMLString != null) {
        return signedXMLString;
    }
    validateData();
    StringBuffer xmlString = new StringBuffer(1000);
    xmlString.append(SAML2Constants.START_TAG);
    if (includeNSPrefix) {
        xmlString.append(SAML2Constants.PROTOCOL_PREFIX);
    }
    xmlString.append(SAML2Constants.LOGOUT_REQUEST).append(SAML2Constants.SPACE);
    if (declareNS) {
        xmlString.append(SAML2Constants.PROTOCOL_DECLARE_STR).append(SAML2Constants.SPACE);
    }
    xmlString.append(SAML2Constants.ID).append(SAML2Constants.EQUAL).append(SAML2Constants.QUOTE).append(requestId).append(SAML2Constants.QUOTE).append(SAML2Constants.SPACE).append(SAML2Constants.VERSION).append(SAML2Constants.EQUAL).append(SAML2Constants.QUOTE).append(version).append(SAML2Constants.QUOTE).append(SAML2Constants.SPACE).append(SAML2Constants.ISSUE_INSTANT).append(SAML2Constants.EQUAL).append(SAML2Constants.QUOTE).append(DateUtils.toUTCDateFormat(issueInstant)).append(SAML2Constants.QUOTE);
    if ((destinationURI != null) && (destinationURI.length() > 0)) {
        xmlString.append(SAML2Constants.SPACE).append(SAML2Constants.DESTINATION).append(SAML2Constants.EQUAL).append(SAML2Constants.QUOTE).append(destinationURI).append(SAML2Constants.QUOTE);
    }
    if ((consent != null) && (consent.length() > 0)) {
        xmlString.append(SAML2Constants.SPACE).append(SAML2Constants.CONSENT).append(SAML2Constants.EQUAL).append(SAML2Constants.QUOTE).append(consent).append(SAML2Constants.QUOTE);
    }
    if (notOnOrAfter != null) {
        xmlString.append(SAML2Constants.SPACE).append(SAML2Constants.NOTONORAFTER).append(SAML2Constants.EQUAL).append(SAML2Constants.QUOTE).append(DateUtils.toUTCDateFormat(notOnOrAfter)).append(SAML2Constants.QUOTE);
    }
    if ((reason != null) && (reason.length() > 0)) {
        xmlString.append(SAML2Constants.SPACE).append(SAML2Constants.REASON).append(SAML2Constants.EQUAL).append(SAML2Constants.QUOTE).append(reason).append(SAML2Constants.QUOTE);
    }
    xmlString.append(SAML2Constants.END_TAG);
    if (nameID != null) {
        String issuerString = nameID.toXMLString(includeNSPrefix, declareNS);
        xmlString.append(issuerString);
    }
    if ((signatureString != null) && (signatureString.length() > 0)) {
        xmlString.append(signatureString);
    }
    if (extensions != null) {
        xmlString.append(extensions.toXMLString(includeNSPrefix, declareNS));
    }
    if (baseId != null) {
        xmlString.append(baseId.toXMLString(includeNSPrefix, declareNS));
    }
    if (nameId != null) {
        xmlString.append(nameId.toXMLString(includeNSPrefix, declareNS));
    }
    if (encryptedId != null) {
        xmlString.append(encryptedId.toXMLString(includeNSPrefix, declareNS));
    }
    if (sessionIndexList != null && !sessionIndexList.isEmpty()) {
        Iterator sessionIterator = sessionIndexList.iterator();
        while (sessionIterator.hasNext()) {
            ProtocolFactory protoFactory = ProtocolFactory.getInstance();
            String sessionString = (String) sessionIterator.next();
            SessionIndex sIndex = protoFactory.createSessionIndex(sessionString);
            xmlString.append(sIndex.toXMLString(includeNSPrefix, declareNS));
        }
    }
    xmlString.append(SAML2Constants.SAML2_END_TAG).append(SAML2Constants.LOGOUT_REQUEST).append(SAML2Constants.END_TAG);
    return xmlString.toString();
}
Also used : ProtocolFactory(com.sun.identity.saml2.protocol.ProtocolFactory) SessionIndex(com.sun.identity.saml2.protocol.SessionIndex) Iterator(java.util.Iterator)

Example 18 with LogoutRequest

use of com.sun.identity.saml2.protocol.LogoutRequest in project OpenAM by OpenRock.

the class SPSingleLogout method initiateLogoutRequest.

/**
     * Parses the request parameters and initiates the Logout
     * Request to be sent to the IDP.
     *
     * @param request the HttpServletRequest.
     * @param response the HttpServletResponse.
     * @param out The print writer for writing out presentation.
     * @param binding binding used for this request.
     * @param paramsMap Map of all other parameters.
     *       Following parameters names with their respective
     *       String values are allowed in this paramsMap.
     *       "RelayState" - the target URL on successful Single Logout
     *       "Destination" - A URI Reference indicating the address to
     *                       which the request has been sent.
     *       "Consent" - Specifies a URI a SAML defined identifier
     *                   known as Consent Identifiers.
     *       "Extension" - Specifies a list of Extensions as list of
     *                   String objects.
     * @param origLogoutRequest original LogoutRequest
     * @param msg SOAPMessage 
     * @param newSession Session object for IDP Proxy
     * @param audit the auditor for logging SAML2 Events - may be null
     * @throws SAML2Exception if error initiating request to IDP.
     */
public static void initiateLogoutRequest(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String binding, Map paramsMap, LogoutRequest origLogoutRequest, SOAPMessage msg, Object newSession, SAML2EventLogger audit) throws SAML2Exception {
    if (debug.messageEnabled()) {
        debug.message("SPSingleLogout:initiateLogoutRequest");
        debug.message("binding : " + binding);
        debug.message("paramsMap : " + paramsMap);
    }
    String metaAlias = (String) paramsMap.get(SAML2Constants.SP_METAALIAS);
    try {
        Object session = null;
        if (newSession != null) {
            session = newSession;
        } else {
            session = sessionProvider.getSession(request);
        }
        if (null != audit) {
            audit.setSSOTokenId(session);
        }
        if (!SPCache.isFedlet) {
            if (session == null) {
                throw new SAML2Exception(SAML2Utils.bundle.getString("nullSSOToken"));
            }
        }
        if (metaAlias == null) {
            if (!SPCache.isFedlet) {
                String[] values = sessionProvider.getProperty(session, SAML2Constants.SP_METAALIAS);
                if (values != null && values.length > 0) {
                    metaAlias = values[0];
                }
            } else {
                List spMetaAliases = sm.getAllHostedServiceProviderMetaAliases("/");
                if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) {
                    // get first one
                    metaAlias = (String) spMetaAliases.get(0);
                }
            }
        }
        if (metaAlias == null) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullSPMetaAlias"));
        }
        paramsMap.put(SAML2Constants.METAALIAS, metaAlias);
        String realm = SAML2Utils.getRealm(SAML2MetaUtils.getRealmByMetaAlias(metaAlias));
        debug.message("realm : " + realm);
        String spEntityID = sm.getEntityByMetaAlias(metaAlias);
        if (spEntityID == null) {
            debug.error("Service Provider ID is missing");
            String[] data = { spEntityID };
            LogUtil.error(Level.INFO, LogUtil.INVALID_SP, data, null);
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullSPEntityID"));
        }
        debug.message("spEntityID : " + spEntityID);
        // clean up session index
        String tokenID = sessionProvider.getSessionID(session);
        String infoKeyString = null;
        if (SPCache.isFedlet) {
            infoKeyString = SAML2Utils.getParameter(paramsMap, SAML2Constants.INFO_KEY);
        } else {
            try {
                String[] values = sessionProvider.getProperty(session, AccountUtils.getNameIDInfoKeyAttribute());
                if (values != null && values.length > 0) {
                    infoKeyString = values[0];
                }
            } catch (SessionException se) {
                debug.error("Unable to get infoKeyString from " + "session.", se);
                throw new SAML2Exception(SAML2Utils.bundle.getString("errorInfoKeyString"));
            }
        }
        if (debug.messageEnabled()) {
            debug.message("tokenID : " + tokenID);
            debug.message("infoKeyString : " + infoKeyString);
        }
        // get SPSSODescriptor
        SPSSODescriptorElement spsso = sm.getSPSSODescriptor(realm, spEntityID);
        if (spsso == null) {
            String[] data = { spEntityID };
            LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
            throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
        }
        List extensionsList = LogoutUtil.getExtensionsList(paramsMap);
        String relayState = SAML2Utils.getParameter(paramsMap, SAML2Constants.RELAY_STATE);
        if (relayState == null || relayState.equals("")) {
            relayState = SAML2Utils.getAttributeValueFromSSOConfig(realm, spEntityID, SAML2Constants.SP_ROLE, SAML2Constants.DEFAULT_RELAY_STATE);
        }
        // Validate the RelayState URL.
        SAML2Utils.validateRelayStateURL(realm, spEntityID, relayState, SAML2Constants.SP_ROLE);
        if (infoKeyString == null) {
            // termination case, do local logout only and send to
            // relay state if any
            debug.warning("SPSingleLogout.initiateLogoutRequest : Unable to get infoKeyString from session.");
            sessionProvider.invalidateSession(session, request, response);
            if ((relayState != null) && !relayState.equals("")) {
                try {
                    response.sendRedirect(relayState);
                } catch (IOException e) {
                    debug.error("SPSingleLogout.initiateLogoutRequest: " + "Error in send redirect to " + relayState, e);
                }
            } else {
                RequestDispatcher dispatcher = request.getRequestDispatcher("saml2/jsp/default.jsp?message=spSloSuccess");
                try {
                    dispatcher.forward(request, response);
                } catch (IOException e) {
                    debug.error("SPSingleLogout.initiateLogoutRequest: " + "Error in forwarding to default.jsp", e);
                } catch (ServletException e) {
                    debug.error("SPSingleLogout.initiateLogoutRequest: " + "Error in forwarding to default.jsp", e);
                }
            }
            return;
        }
        StringTokenizer st = new StringTokenizer(infoKeyString, SAML2Constants.SECOND_DELIM);
        String requestID = null;
        while (st.hasMoreTokens()) {
            String tmpInfoKeyString = st.nextToken();
            NameIDInfoKey nameIdInfoKey = NameIDInfoKey.parse(tmpInfoKeyString);
            //logout request to the other SP instance, invalidating the session for both SPs.
            if (nameIdInfoKey.getHostEntityID().equals(spEntityID)) {
                requestID = prepareForLogout(realm, tokenID, metaAlias, extensionsList, binding, relayState, request, response, paramsMap, tmpInfoKeyString, origLogoutRequest, msg);
            }
        }
        // IDP Proxy 
        SOAPMessage soapMsg = (SOAPMessage) IDPCache.SOAPMessageByLogoutRequestID.get(requestID);
        if (soapMsg != null) {
            IDPProxyUtil.sendProxyLogoutResponseBySOAP(soapMsg, response, out);
        }
        // when SAML Response reached the SP side.
        if (binding.equals(SAML2Constants.SOAP) || (requestID == null)) {
            sessionProvider.invalidateSession(session, request, response);
        }
    } catch (SAML2MetaException sme) {
        debug.error("Error retreiving metadata", sme);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    } catch (SessionException ssoe) {
        debug.error("Session exception: ", ssoe);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
}
Also used : SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) SessionException(com.sun.identity.plugin.session.SessionException) IOException(java.io.IOException) SOAPMessage(javax.xml.soap.SOAPMessage) RequestDispatcher(javax.servlet.RequestDispatcher) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) ServletException(javax.servlet.ServletException) StringTokenizer(java.util.StringTokenizer) List(java.util.List) ArrayList(java.util.ArrayList) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) NameIDInfoKey(com.sun.identity.saml2.common.NameIDInfoKey)

Example 19 with LogoutRequest

use of com.sun.identity.saml2.protocol.LogoutRequest in project OpenAM by OpenRock.

the class LogoutUtil method verifySLORequest.

/**
     * Verify the signature in LogoutRequest.
     *
     * @param sloRequest SLO request will be verified.
     * @param realm realm of host entity.
     * @param remoteEntity entity ID of remote host entity.
     * @param hostEntity entity ID of host entity.
     * @param hostEntityRole role of host entity.
     * @return returns true if signature is valid.
     * @throws SAML2Exception if error in verifying the signature.
     * @throws SessionException if error in verifying the signature.
     */
public static boolean verifySLORequest(LogoutRequest sloRequest, String realm, String remoteEntity, String hostEntity, String hostEntityRole) throws SAML2Exception, SessionException {
    String method = "verifySLORequest : ";
    boolean needVerifySignature = SAML2Utils.getWantLogoutRequestSigned(realm, hostEntity, hostEntityRole);
    if (needVerifySignature == false) {
        if (debug.messageEnabled()) {
            debug.message(method + "SLORequest doesn't need to be verified.");
        }
        return true;
    }
    if (debug.messageEnabled()) {
        debug.message(method + "realm is : " + realm);
        debug.message(method + "remoteEntity is : " + remoteEntity);
        debug.message(method + "Host Entity role is : " + hostEntityRole);
    }
    boolean valid = false;
    Set<X509Certificate> signingCerts;
    if (hostEntityRole.equalsIgnoreCase(SAML2Constants.IDP_ROLE)) {
        SPSSODescriptorElement spSSODesc = metaManager.getSPSSODescriptor(realm, remoteEntity);
        signingCerts = KeyUtil.getVerificationCerts(spSSODesc, remoteEntity, SAML2Constants.SP_ROLE);
    } else {
        IDPSSODescriptorElement idpSSODesc = metaManager.getIDPSSODescriptor(realm, remoteEntity);
        signingCerts = KeyUtil.getVerificationCerts(idpSSODesc, remoteEntity, SAML2Constants.IDP_ROLE);
    }
    if (!signingCerts.isEmpty()) {
        valid = sloRequest.isSignatureValid(signingCerts);
        if (debug.messageEnabled()) {
            debug.message(method + "Signature is : " + valid);
        }
    } else {
        debug.error("Incorrect configuration for Signing Certificate.");
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
    return valid;
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) X509Certificate(java.security.cert.X509Certificate) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)

Example 20 with LogoutRequest

use of com.sun.identity.saml2.protocol.LogoutRequest in project OpenAM by OpenRock.

the class IDPSingleLogout method processLogoutRequest.

/**
     * Gets and processes the Single <code>LogoutRequest</code> from SP.
     *
     * @param request the HttpServletRequest.
     * @param response the HttpServletResponse.
     * @param out the print writer for writing out presentation
     * @param samlRequest <code>LogoutRequest</code> in the
     *          XML string format.
     * @param relayState the target URL on successful
     * <code>LogoutRequest</code>.
     * @throws SAML2Exception if error processing
     *          <code>LogoutRequest</code>.
     * @throws SessionException if error processing
     *          <code>LogoutRequest</code>.
     */
public static void processLogoutRequest(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String samlRequest, String relayState) throws SAML2Exception, SessionException {
    String classMethod = "IDPSingleLogout.processLogoutRequest : ";
    if (debug.messageEnabled()) {
        debug.message(classMethod + "IDPSingleLogout:processLogoutRequest");
        debug.message(classMethod + "samlRequest : " + samlRequest);
        debug.message(classMethod + "relayState : " + relayState);
    }
    String rmethod = request.getMethod();
    String binding = SAML2Constants.HTTP_REDIRECT;
    if (rmethod.equals("POST")) {
        binding = SAML2Constants.HTTP_POST;
    }
    String metaAlias = SAML2MetaUtils.getMetaAliasByUri(request.getRequestURI());
    String realm = SAML2Utils.getRealm(SAML2MetaUtils.getRealmByMetaAlias(metaAlias));
    String idpEntityID = sm.getEntityByMetaAlias(metaAlias);
    if (!SAML2Utils.isIDPProfileBindingSupported(realm, idpEntityID, SAML2Constants.SLO_SERVICE, binding)) {
        debug.error(classMethod + "SLO service binding " + binding + " is not supported for " + idpEntityID);
        throw new SAML2Exception(SAML2Utils.bundle.getString("unsupportedBinding"));
    }
    LogoutRequest logoutReq = null;
    if (rmethod.equals("POST")) {
        logoutReq = LogoutUtil.getLogoutRequestFromPost(samlRequest, response);
    } else if (rmethod.equals("GET")) {
        String decodedStr = SAML2Utils.decodeFromRedirect(samlRequest);
        if (decodedStr == null) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullDecodedStrFromSamlRequest"));
        }
        logoutReq = ProtocolFactory.getInstance().createLogoutRequest(decodedStr);
    }
    if (logoutReq == null) {
        if (debug.messageEnabled()) {
            debug.message("IDPSingleLogout:processLogoutRequest: logoutReq " + "is null");
        }
        return;
    }
    String spEntityID = logoutReq.getIssuer().getValue();
    boolean needToVerify = SAML2Utils.getWantLogoutRequestSigned(realm, idpEntityID, SAML2Constants.IDP_ROLE);
    if (debug.messageEnabled()) {
        debug.message(classMethod + "metaAlias : " + metaAlias);
        debug.message(classMethod + "realm : " + realm);
        debug.message(classMethod + "idpEntityID : " + idpEntityID);
        debug.message(classMethod + "spEntityID : " + spEntityID);
    }
    if (needToVerify) {
        boolean valid = false;
        if (binding.equals(SAML2Constants.HTTP_REDIRECT)) {
            String queryString = request.getQueryString();
            valid = SAML2Utils.verifyQueryString(queryString, realm, SAML2Constants.IDP_ROLE, spEntityID);
        } else {
            valid = LogoutUtil.verifySLORequest(logoutReq, realm, spEntityID, idpEntityID, SAML2Constants.IDP_ROLE);
        }
        if (!valid) {
            debug.error("Invalid signature in SLO Request.");
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSignInRequest"));
        }
        IDPSSODescriptorElement idpsso = sm.getIDPSSODescriptor(realm, idpEntityID);
        String loc = null;
        if (idpsso != null) {
            List sloList = idpsso.getSingleLogoutService();
            if ((sloList != null) && (!sloList.isEmpty())) {
                loc = LogoutUtil.getSLOResponseServiceLocation(sloList, binding);
                if ((loc == null) || (loc.length() == 0)) {
                    loc = LogoutUtil.getSLOServiceLocation(sloList, binding);
                }
            }
        }
        if (!SAML2Utils.verifyDestination(logoutReq.getDestination(), loc)) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidDestination"));
        }
    }
    // Get the local session, if it does not exist send a succesful
    // Logout Response with a status message of "Already Logout"
    Object session = null;
    try {
        session = sessionProvider.getSession(request);
    } catch (SessionException ssoe) {
        sendAlreadyLogedOutResp(response, request, logoutReq, relayState, realm, idpEntityID, spEntityID, binding);
        return;
    }
    // then send the request to the original server
    if (session != null && !SAML2FailoverUtils.isSAML2FailoverEnabled() && isMisroutedRequest(request, response, out, session)) {
        return;
    } else {
        if (debug.messageEnabled()) {
            debug.message(classMethod + "SAML2 Failover will be attempted. Be sure SFO is " + "properly configured or the attempt will fail");
        }
    }
    LogoutResponse logoutRes = processLogoutRequest(logoutReq, request, response, binding, relayState, idpEntityID, realm, true);
    if (logoutRes == null) {
        // through HTTP_Redirect, nothing to do here
        return;
    }
    // this is the case where there is no more SP session
    // participant
    SingleLogoutServiceElement endpoint = getLogoutResponseEndpoint(realm, spEntityID, binding);
    binding = endpoint.getBinding();
    String location = getResponseLocation(endpoint);
    logoutRes.setDestination(XMLUtils.escapeSpecialCharacters(location));
    // call multi-federation protocol processing
    // this is SP initiated HTTP based single logout
    boolean isMultiProtocolSession = false;
    int retStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
    try {
        if ((session != null) && (sessionProvider.isValid(session)) && MultiProtocolUtils.isMultipleProtocolSession(session, SingleLogoutManager.SAML2)) {
            isMultiProtocolSession = true;
            // call Multi-Federation protocol SingleLogoutManager
            SingleLogoutManager sloManager = SingleLogoutManager.getInstance();
            Set set = new HashSet();
            set.add(session);
            String uid = sessionProvider.getPrincipalName(session);
            debug.message("IDPSingleLogout.processLogReq: MP/SPinit/Http");
            retStatus = sloManager.doIDPSingleLogout(set, uid, request, response, false, false, SingleLogoutManager.SAML2, realm, idpEntityID, spEntityID, relayState, logoutReq.toString(), logoutRes.toXMLString(), getLogoutStatus(logoutRes));
        }
    } catch (SessionException e) {
        // ignore as session might not be valid
        debug.message("IDPSingleLogout.processLogoutRequest: session", e);
    } catch (Exception e) {
        debug.message("IDPSingleLogout.processLogoutRequest: MP2", e);
        retStatus = SingleLogoutManager.LOGOUT_FAILED_STATUS;
    }
    if (!isMultiProtocolSession || (retStatus != SingleLogoutManager.LOGOUT_REDIRECTED_STATUS)) {
        logoutRes = updateLogoutResponse(logoutRes, retStatus);
        List partners = IDPProxyUtil.getSessionPartners(request);
        if (partners != null && !partners.isEmpty()) {
            IDPProxyUtil.sendProxyLogoutRequest(request, response, out, logoutReq, partners, binding, relayState);
        } else {
            LogoutUtil.sendSLOResponse(response, request, logoutRes, location, relayState, realm, idpEntityID, SAML2Constants.IDP_ROLE, spEntityID, binding);
        }
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) LogoutResponse(com.sun.identity.saml2.protocol.LogoutResponse) SessionException(com.sun.identity.plugin.session.SessionException) SessionException(com.sun.identity.plugin.session.SessionException) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) IOException(java.io.IOException) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SingleLogoutManager(com.sun.identity.multiprotocol.SingleLogoutManager) SingleLogoutServiceElement(com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement) LogoutRequest(com.sun.identity.saml2.protocol.LogoutRequest) List(java.util.List) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement) HashSet(java.util.HashSet)

Aggregations

SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)23 LogoutRequest (com.sun.identity.saml2.protocol.LogoutRequest)13 List (java.util.List)12 SessionException (com.sun.identity.plugin.session.SessionException)9 IDPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)9 LogoutResponse (com.sun.identity.saml2.protocol.LogoutResponse)9 SPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement)8 SOAPException (javax.xml.soap.SOAPException)8 SAML2MetaException (com.sun.identity.saml2.meta.SAML2MetaException)7 IOException (java.io.IOException)7 ArrayList (java.util.ArrayList)7 SOAPMessage (javax.xml.soap.SOAPMessage)6 Element (org.w3c.dom.Element)6 Issuer (com.sun.identity.saml2.assertion.Issuer)5 SingleLogoutServiceElement (com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement)5 Iterator (java.util.Iterator)5 SAML2TokenRepositoryException (org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)5 BaseConfigType (com.sun.identity.saml2.jaxb.entityconfig.BaseConfigType)4 HashMap (java.util.HashMap)4 NameID (com.sun.identity.saml2.assertion.NameID)3