Search in sources :

Example 96 with Response

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

the class AttributeQueryUtil method verifyResponse.

private static void verifyResponse(Response response, AttributeQuery attrQuery, String attrAuthorityEntityID, AttributeAuthorityDescriptorElement aad) throws SAML2Exception {
    String attrQueryID = attrQuery.getID();
    if ((attrQueryID != null) && (!attrQueryID.equals(response.getInResponseTo()))) {
        throw new SAML2Exception(SAML2Utils.bundle.getString("invalidInResponseToAttrQuery"));
    }
    Issuer respIssuer = response.getIssuer();
    if (respIssuer == null) {
        return;
    }
    if (!attrAuthorityEntityID.equals(respIssuer.getValue())) {
        throw new SAML2Exception(SAML2Utils.bundle.getString("responseIssuerMismatch"));
    }
    if (!response.isSigned()) {
        throw new SAML2Exception(SAML2Utils.bundle.getString("responseNotSigned"));
    }
    Set<X509Certificate> signingCerts = KeyUtil.getVerificationCerts(aad, attrAuthorityEntityID, SAML2Constants.ATTR_AUTH_ROLE);
    if (!signingCerts.isEmpty()) {
        boolean valid = response.isSignatureValid(signingCerts);
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message("AttributeQueryUtil.verifyResponse: " + "Signature validity is : " + valid);
        }
        if (!valid) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSignatureOnResponse"));
        }
    } else {
        throw new SAML2Exception(SAML2Utils.bundle.getString("missingSigningCertAlias"));
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) Issuer(com.sun.identity.saml2.assertion.Issuer) X509Certificate(java.security.cert.X509Certificate)

Example 97 with Response

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

the class SPACSUtils method getResponseFromSOAP.

/**
     * Obtains <code>SAML Response</code> from <code>SOAPBody</code>.
     * Used by Artifact profile.
     */
private static Response getResponseFromSOAP(SOAPMessage resMsg, ArtifactResolve resolve, HttpServletRequest request, HttpServletResponse response, String idpEntityID, IDPSSODescriptorElement idp, String orgName, String hostEntityId, SAML2MetaManager sm) throws SAML2Exception, IOException {
    String method = "SPACSUtils.getResponseFromSOAP:";
    Element resElem = null;
    try {
        resElem = SOAPCommunicator.getInstance().getSamlpElement(resMsg, "ArtifactResponse");
    } catch (SAML2Exception se) {
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.SOAP_ERROR, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "soapError", se.getMessage());
        throw se;
    }
    ArtifactResponse artiResp = null;
    try {
        artiResp = ProtocolFactory.getInstance().createArtifactResponse(resElem);
    } catch (SAML2Exception se) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(method + "Couldn't create " + "ArtifactResponse:", se);
        }
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.CANNOT_INSTANTIATE_ARTIFACT_RESPONSE, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "failedToCreateArtifactResponse", se.getMessage());
        throw se;
    }
    if (artiResp == null) {
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.MISSING_ARTIFACT_RESPONSE, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "missingArtifactResponse", SAML2Utils.bundle.getString("missingArtifactResponse"));
        throw new SAML2Exception(SAML2Utils.bundle.getString("missingArtifactResponse"));
    } else {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(method + "Received ArtifactResponse:" + artiResp.toXMLString(true, true));
        }
    }
    // verify ArtifactResponse
    String wantArtiRespSigned = getAttributeValueFromSPSSOConfig(orgName, hostEntityId, sm, SAML2Constants.WANT_ARTIFACT_RESPONSE_SIGNED);
    if (wantArtiRespSigned != null && wantArtiRespSigned.equals("true")) {
        Set<X509Certificate> verificationCerts = KeyUtil.getVerificationCerts(idp, idpEntityID, SAML2Constants.IDP_ROLE);
        if (!artiResp.isSigned() || !artiResp.isSignatureValid(verificationCerts)) {
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(method + "ArtifactResponse's signature is invalid.");
            }
            String[] data = { idpEntityID };
            LogUtil.error(Level.INFO, LogUtil.ARTIFACT_RESPONSE_INVALID_SIGNATURE, data, null);
            SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "invalidSignature", SAML2Utils.bundle.getString("invalidSignature"));
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSignature"));
        }
    }
    String inResponseTo = artiResp.getInResponseTo();
    if (inResponseTo == null || !inResponseTo.equals(resolve.getID())) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(method + "ArtifactResponse's InResponseTo is invalid.");
        }
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.ARTIFACT_RESPONSE_INVALID_INRESPONSETO, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "invalidInResponseTo", SAML2Utils.bundle.getString("invalidInResponseTo"));
        throw new SAML2Exception(SAML2Utils.bundle.getString("invalidInResponseTo"));
    }
    Issuer idpIssuer = artiResp.getIssuer();
    if (idpIssuer == null || !idpIssuer.getValue().equals(idpEntityID)) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(method + "ArtifactResponse's Issuer is invalid.");
        }
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.ARTIFACT_RESPONSE_INVALID_ISSUER, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "invalidIssuer", SAML2Utils.bundle.getString("invalidIssuer"));
        throw new SAML2Exception(SAML2Utils.bundle.getString("invalidIssuer"));
    }
    // check time?
    Status status = artiResp.getStatus();
    if (status == null || !status.getStatusCode().getValue().equals(SAML2Constants.SUCCESS)) {
        String statusCode = (status == null) ? "" : status.getStatusCode().getValue();
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(method + "ArtifactResponse's status code is not success." + statusCode);
        }
        String[] data = { idpEntityID, "" };
        if (LogUtil.isErrorLoggable(Level.FINE)) {
            data[1] = statusCode;
        }
        LogUtil.error(Level.INFO, LogUtil.ARTIFACT_RESPONSE_INVALID_STATUS_CODE, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "invalidStatusCode", SAML2Utils.bundle.getString("invalidStatusCode"));
        throw new SAML2Exception(SAML2Utils.bundle.getString("invalidStatusCode"));
    }
    try {
        return ProtocolFactory.getInstance().createResponse(artiResp.getAny());
    } catch (SAML2Exception se) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(method + "couldn't instantiate Response:", se);
        }
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.CANNOT_INSTANTIATE_RESPONSE_ARTIFACT, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "failedToCreateResponse", se.getMessage());
        throw se;
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) Status(com.sun.identity.saml2.protocol.Status) Issuer(com.sun.identity.saml2.assertion.Issuer) ArtifactResponse(com.sun.identity.saml2.protocol.ArtifactResponse) SPSSOConfigElement(com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) IDPSSOConfigElement(com.sun.identity.saml2.jaxb.entityconfig.IDPSSOConfigElement) ArtifactResolutionServiceElement(com.sun.identity.saml2.jaxb.metadata.ArtifactResolutionServiceElement) Element(org.w3c.dom.Element) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement) X509Certificate(java.security.cert.X509Certificate)

Example 98 with Response

use of com.sun.identity.saml2.protocol.Response 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 99 with Response

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

the class IDPSingleLogout method processLogoutResponse.

static boolean processLogoutResponse(HttpServletRequest request, HttpServletResponse response, LogoutResponse logoutRes, String relayState, String metaAlias, String idpEntityID, String spEntityID, String realm, String binding) throws SAML2Exception, SessionException {
    // use the cache to figure out which session index is in question
    // and then use the cache to see if any more SPs to send logout request
    // if yes, send one
    // if no, do local logout and send response back to original requesting
    // SP (this SP name should be remembered in cache)
    Object session = sessionProvider.getSession(request);
    String tokenID = sessionProvider.getSessionID(session);
    String idpSessionIndex = IDPSSOUtil.getSessionIndex(session);
    if (idpSessionIndex == null) {
        if (debug.messageEnabled()) {
            debug.message("No SP session participant(s)");
        }
        MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
        return false;
    }
    IDPSession idpSession = IDPCache.idpSessionsByIndices.get(idpSessionIndex);
    if (idpSession == null) {
        if (debug.messageEnabled()) {
            debug.message("IDPSLO.processLogoutResponse : " + "IDP Session with session index " + idpSessionIndex + " already removed.");
        }
        try {
            if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
            }
        } catch (SAML2TokenRepositoryException se) {
            debug.error("IDPSingleLogout.processLogoutRequest: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
        }
        IDPCache.authnContextCache.remove(idpSessionIndex);
        MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
        return false;
    }
    if (debug.messageEnabled()) {
        debug.message("idpSessionIndex=" + idpSessionIndex);
    }
    List<NameIDandSPpair> list = idpSession.getNameIDandSPpairs();
    debug.message("idpSession.getNameIDandSPpairs()=" + list);
    if (list.isEmpty()) {
        return sendLastResponse(idpSession, logoutRes, request, response, idpSessionIndex, session, realm, idpEntityID, relayState);
    } else {
        // send Next Requests
        Iterator<NameIDandSPpair> it = list.iterator();
        while (it.hasNext()) {
            NameIDandSPpair pair = it.next();
            it.remove();
            spEntityID = pair.getSPEntityID();
            removeTransientNameIDFromCache(pair.getNameID());
            Map paramsMap = new HashMap(request.getParameterMap());
            paramsMap.put(SAML2Constants.ROLE, SAML2Constants.IDP_ROLE);
            List<SingleLogoutServiceElement> slosList = getSPSLOServiceEndpoints(realm, spEntityID);
            List extensionsList = LogoutUtil.getExtensionsList(request.getParameterMap());
            SPSSOConfigElement spConfig = sm.getSPSSOConfig(realm, spEntityID);
            //When processing a logout response we must ensure that we try to use the original logout request
            //binding to make sure asynchronous bindings have precedence over synchronous bindings.
            SingleLogoutServiceElement logoutEndpoint = LogoutUtil.getMostAppropriateSLOServiceLocation(slosList, idpSession.getOriginatingLogoutRequestBinding());
            if (logoutEndpoint == null) {
                continue;
            }
            StringBuffer requestID = LogoutUtil.doLogout(metaAlias, spEntityID, extensionsList, logoutEndpoint, relayState, idpSessionIndex, pair.getNameID(), request, response, paramsMap, spConfig);
            String bindingUsed = logoutEndpoint.getBinding();
            if (bindingUsed.equals(SAML2Constants.HTTP_REDIRECT) || bindingUsed.equals(SAML2Constants.HTTP_POST)) {
                String requestIDStr = requestID.toString();
                if (debug.messageEnabled()) {
                    debug.message("IDPSingleLogout.processLogoutRequest: requestIDStr = " + requestIDStr + "\nbinding = " + bindingUsed);
                }
                if (requestIDStr != null && requestIDStr.length() != 0) {
                    idpSession.setPendingLogoutRequestID(requestIDStr);
                }
                return true;
            }
        }
        //response.
        return sendLastResponse(idpSession, logoutRes, request, response, idpSessionIndex, session, realm, idpEntityID, relayState);
    }
}
Also used : HashMap(java.util.HashMap) SPSSOConfigElement(com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement) SingleLogoutServiceElement(com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map)

Example 100 with Response

use of com.sun.identity.saml2.protocol.Response 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)119 List (java.util.List)53 SAML2MetaException (com.sun.identity.saml2.meta.SAML2MetaException)45 ArrayList (java.util.ArrayList)41 IOException (java.io.IOException)40 SessionException (com.sun.identity.plugin.session.SessionException)35 Response (com.sun.identity.saml2.protocol.Response)31 SOAPException (javax.xml.soap.SOAPException)31 Issuer (com.sun.identity.saml2.assertion.Issuer)28 HttpServletResponse (javax.servlet.http.HttpServletResponse)28 SAML2TokenRepositoryException (org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)25 Map (java.util.Map)24 Assertion (com.sun.identity.saml2.assertion.Assertion)23 SPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement)23 SOAPMessage (javax.xml.soap.SOAPMessage)22 IDPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)20 Date (java.util.Date)20 HashMap (java.util.HashMap)20 Element (org.w3c.dom.Element)20 X509Certificate (java.security.cert.X509Certificate)16