Search in sources :

Example 1 with SingleLogoutManager

use of com.sun.identity.multiprotocol.SingleLogoutManager in project OpenAM by OpenRock.

the class WSFederationUtils method processMultiProtocolLogout.

/**
     * Processes Single Logout cross multiple federation protocols
     * @param request HttpServletRequest object.
     * @param response HttpServletResponse object
     */
public static void processMultiProtocolLogout(HttpServletRequest request, HttpServletResponse response, Object userSession) {
    debug.message("WSFederationUtils.processMPSingleLogout");
    try {
        String wreply = (String) request.getAttribute(WSFederationConstants.LOGOUT_WREPLY);
        String realm = (String) request.getAttribute(WSFederationConstants.REALM_PARAM);
        String idpEntityId = (String) request.getAttribute(WSFederationConstants.ENTITYID_PARAM);
        Set sessSet = new HashSet();
        sessSet.add(userSession);
        String sessUser = SessionManager.getProvider().getPrincipalName(userSession);
        // assume WS-Federation logout always succeed as there is not
        // logout status from the specification
        SingleLogoutManager manager = SingleLogoutManager.getInstance();
        // TODO : find out spEntityID/logout request if any
        int status = manager.doIDPSingleLogout(sessSet, sessUser, request, response, false, true, SingleLogoutManager.WS_FED, realm, idpEntityId, null, wreply, null, null, SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS);
        if (status != SingleLogoutManager.LOGOUT_REDIRECTED_STATUS) {
            response.sendRedirect(wreply);
        }
    } catch (SessionException ex) {
        // ignore;
        debug.message("WSFederationUtils.processMultiProtocolLogout", ex);
    } catch (IOException ex) {
        // ignore;
        debug.message("WSFederationUtils.processMultiProtocolLogout", ex);
    } catch (Exception ex) {
        // ignore;
        debug.message("WSFederationUtils.processMultiProtocolLogout", ex);
    }
}
Also used : SingleLogoutManager(com.sun.identity.multiprotocol.SingleLogoutManager) HashSet(java.util.HashSet) Set(java.util.Set) SessionException(com.sun.identity.plugin.session.SessionException) IOException(java.io.IOException) SessionException(com.sun.identity.plugin.session.SessionException) DataStoreProviderException(com.sun.identity.plugin.datastore.DataStoreProviderException) IOException(java.io.IOException) WSFederationMetaException(com.sun.identity.wsfederation.meta.WSFederationMetaException) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) HashSet(java.util.HashSet)

Example 2 with SingleLogoutManager

use of com.sun.identity.multiprotocol.SingleLogoutManager in project OpenAM by OpenRock.

the class IDPSingleLogout method sendLastResponse.

private static boolean sendLastResponse(IDPSession idpSession, LogoutResponse logoutRes, HttpServletRequest request, HttpServletResponse response, String idpSessionIndex, Object session, String realm, String idpEntityID, String relayState) throws SAML2Exception, SessionException, SAML2MetaException {
    String binding;
    //resetting the binding to the original value so the response is sent back with the correct binding
    binding = idpSession.getOriginatingLogoutRequestBinding();
    String originatingRequestID = idpSession.getOriginatingLogoutRequestID();
    String originatingLogoutSPEntityID = idpSession.getOriginatingLogoutSPEntityID();
    if (originatingRequestID == null) {
        // this is IDP initiated SLO
        if (idpSession.getLogoutAll()) {
            String userID = sessionProvider.getPrincipalName(idpSession.getSession());
            destroyAllTokenForUser(userID, request, response);
        } else {
            IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
            if (agent != null && agent.isRunning() && saml2Svc != null) {
                saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
            }
            try {
                if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                    SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
                }
            } catch (SAML2TokenRepositoryException se) {
                debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
            }
            IDPCache.authnContextCache.remove(idpSessionIndex);
            if (!MultiProtocolUtils.isMultipleProtocolSession(idpSession.getSession(), SingleLogoutManager.SAML2)) {
                sessionProvider.invalidateSession(idpSession.getSession(), request, response);
            } else {
                MultiProtocolUtils.removeFederationProtocol(idpSession.getSession(), SingleLogoutManager.SAML2);
                // call Multi-Federation protocol SingleLogoutManager
                SingleLogoutManager sloManager = SingleLogoutManager.getInstance();
                Set<Object> set = new HashSet<Object>(1);
                set.add(session);
                SessionProvider provider = SessionManager.getProvider();
                String uid = provider.getPrincipalName(session);
                debug.message("IDPSingleLogout.sendLastResponse: MP/Http");
                int retStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
                try {
                    retStatus = sloManager.doIDPSingleLogout(set, uid, request, response, false, true, SingleLogoutManager.SAML2, realm, idpEntityID, originatingLogoutSPEntityID, relayState, null, null, getLogoutStatus(logoutRes));
                } catch (SAML2Exception ex) {
                    throw ex;
                } catch (Exception ex) {
                    debug.error("IDPSIngleLogout.sendLastResponse: MP/IDP initiated HTTP", ex);
                    throw new SAML2Exception(ex.getMessage());
                }
                if (retStatus == SingleLogoutManager.LOGOUT_REDIRECTED_STATUS) {
                    return true;
                }
            }
        }
        debug.message("IDP initiated SLO Success");
        return false;
    }
    List<SingleLogoutServiceElement> slosList = getSPSLOServiceEndpoints(realm, originatingLogoutSPEntityID);
    String location = LogoutUtil.getSLOResponseServiceLocation(slosList, binding);
    if (location == null || location.isEmpty()) {
        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);
        }
    }
    Status status = destroyTokenAndGenerateStatus(idpSessionIndex, idpSession.getSession(), request, response, true);
    //here we are providing null for remote entity, because it's an unused variable in the method...
    logoutRes = LogoutUtil.generateResponse(status, originatingRequestID, SAML2Utils.createIssuer(idpEntityID), realm, SAML2Constants.IDP_ROLE, null);
    if (logoutRes != null) {
        logoutRes.setDestination(XMLUtils.escapeSpecialCharacters(location));
        IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
        if (agent != null && agent.isRunning() && saml2Svc != null) {
            saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
        }
        try {
            if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
            }
        } catch (SAML2TokenRepositoryException se) {
            debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
        }
        IDPCache.authnContextCache.remove(idpSessionIndex);
        // call multi-federation protocol processing
        // this is the SP initiated HTTP binding case
        boolean isMultiProtocolSession = false;
        int retStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
        try {
            SessionProvider provider = SessionManager.getProvider();
            session = idpSession.getSession();
            if (session != null && provider.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 = provider.getPrincipalName(session);
                debug.message("IDPSingleLogout.sendLastResponse: MP/Http");
                retStatus = sloManager.doIDPSingleLogout(set, uid, request, response, false, true, SingleLogoutManager.SAML2, realm, idpEntityID, originatingLogoutSPEntityID, relayState, null, logoutRes.toXMLString(), getLogoutStatus(logoutRes));
            }
        } catch (SessionException e) {
            // ignore as session might not be valid
            debug.message("IDPSingleLogout.sendLastResponse: session", e);
        } catch (Exception e) {
            debug.message("IDPSingleLogout.sendLastResponse: MP2", e);
            retStatus = SingleLogoutManager.LOGOUT_FAILED_STATUS;
        }
        if (!isMultiProtocolSession || (retStatus != SingleLogoutManager.LOGOUT_REDIRECTED_STATUS)) {
            logoutRes = updateLogoutResponse(logoutRes, retStatus);
            LogoutUtil.sendSLOResponse(response, request, logoutRes, location, relayState, realm, idpEntityID, SAML2Constants.IDP_ROLE, originatingLogoutSPEntityID, binding);
            return true;
        } else {
            return false;
        }
    }
    IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
    if (agent != null && agent.isRunning() && saml2Svc != null) {
        saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
    }
    try {
        if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
            SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
        }
    } catch (SAML2TokenRepositoryException se) {
        debug.error("IDPSingleLogout.sendLastResponse: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
    }
    IDPCache.authnContextCache.remove(idpSessionIndex);
    return false;
}
Also used : Status(com.sun.identity.saml2.protocol.Status) HashSet(java.util.HashSet) Set(java.util.Set) 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) SingleLogoutManager(com.sun.identity.multiprotocol.SingleLogoutManager) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SingleLogoutServiceElement(com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) HashSet(java.util.HashSet) SessionProvider(com.sun.identity.plugin.session.SessionProvider)

Example 3 with SingleLogoutManager

use of com.sun.identity.multiprotocol.SingleLogoutManager 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

SingleLogoutManager (com.sun.identity.multiprotocol.SingleLogoutManager)3 SessionException (com.sun.identity.plugin.session.SessionException)3 SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)3 IOException (java.io.IOException)3 HashSet (java.util.HashSet)3 Set (java.util.Set)3 SingleLogoutServiceElement (com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement)2 SAML2MetaException (com.sun.identity.saml2.meta.SAML2MetaException)2 SAML2TokenRepositoryException (org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)2 DataStoreProviderException (com.sun.identity.plugin.datastore.DataStoreProviderException)1 SessionProvider (com.sun.identity.plugin.session.SessionProvider)1 IDPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)1 LogoutRequest (com.sun.identity.saml2.protocol.LogoutRequest)1 LogoutResponse (com.sun.identity.saml2.protocol.LogoutResponse)1 Status (com.sun.identity.saml2.protocol.Status)1 WSFederationMetaException (com.sun.identity.wsfederation.meta.WSFederationMetaException)1 List (java.util.List)1