Search in sources :

Example 6 with LogoutResponse

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

the class IDPSingleLogout method isNameNotFound.

static boolean isNameNotFound(LogoutResponse logoutRes) {
    Status status = logoutRes.getStatus();
    String statusMessage = status.getStatusMessage();
    return (status.getStatusCode().getValue().equals(SAML2Constants.RESPONDER) && statusMessage != null && statusMessage.equals(SAML2Utils.bundle.getString("invalid_name_identifier")));
}
Also used : Status(com.sun.identity.saml2.protocol.Status)

Example 7 with LogoutResponse

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

the class IDPSingleLogout method sendAlreadyLogedOutResp.

/**
     * Generates a new Logout Response with Success Status saying that the user has already logged out.
     *
     * @param response The Servlet response.
     * @param logoutReq The SAML 2.0 Logout Request.
     * @param relayState The original relay state that came with the request.
     * @param realm The realm where the hosted entity has been defined.
     * @param idpEntityID The entity id of the hosted IdP.
     * @param spEntityID The entity id of the remote SP.
     * @param binding The binding that the IdP should reply with to the SP.
     *
     * @throws SAML2Exception If there was a problem while constructing/sending the Logout Response.
     */
private static void sendAlreadyLogedOutResp(HttpServletResponse response, HttpServletRequest request, LogoutRequest logoutReq, String relayState, String realm, String idpEntityID, String spEntityID, String binding) throws SAML2Exception {
    String classMethod = "IDPSingleLogout.sendAlreadyLogedOutResp";
    debug.message(classMethod + "No session in the IdP. " + "We are already logged out. Generating success logout");
    LogoutResponse logRes = LogoutUtil.generateResponse(ALREADY_LOGGEDOUT, logoutReq.getID(), SAML2Utils.createIssuer(idpEntityID), realm, SAML2Constants.IDP_ROLE, logoutReq.getIssuer().getSPProvidedID());
    SingleLogoutServiceElement endpoint = getLogoutResponseEndpoint(realm, spEntityID, binding);
    binding = endpoint.getBinding();
    String location = getResponseLocation(endpoint);
    debug.message(classMethod + "Location found: " + location + " for binding " + binding);
    logRes.setDestination(XMLUtils.escapeSpecialCharacters(location));
    LogoutUtil.sendSLOResponse(response, request, logRes, location, relayState, realm, idpEntityID, SAML2Constants.IDP_ROLE, spEntityID, binding);
}
Also used : LogoutResponse(com.sun.identity.saml2.protocol.LogoutResponse) SingleLogoutServiceElement(com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement)

Example 8 with LogoutResponse

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

the class LogoutUtil method doSLOBySOAP.

/**
     * Performs SOAP logout, this method will send LogoutResuest to IDP using
     * SOAP binding, and process LogoutResponse.
     * @param requestID Request id.
     * @param sloRequest  a string representation of LogoutRequest.
     * @param sloURL SOAP logout URL on IDP side.
     * @param realm  a string representation of LogoutRequest.
     * @param hostEntity  host entity is sending the request.
     * @param hostRole SOAP logout URL on IDP side.
     * @throws SAML2Exception if logout failed. 
     * @throws SessionException if logout failed. 
     */
private static void doSLOBySOAP(String requestID, LogoutRequest sloRequest, String sloURL, String realm, String hostEntity, String hostRole, HttpServletRequest request, HttpServletResponse response) throws SAML2Exception, SessionException {
    String sloRequestXMLString = sloRequest.toXMLString(true, true);
    if (debug.messageEnabled()) {
        debug.message("LogoutUtil.doSLOBySOAP : SLORequestXML: " + sloRequestXMLString + "\nSOAPURL : " + sloURL);
    }
    SOAPMessage resMsg = null;
    try {
        resMsg = SOAPCommunicator.getInstance().sendSOAPMessage(sloRequestXMLString, sloURL, true);
    } catch (SOAPException se) {
        debug.error("Unable to send SOAPMessage to IDP ", se);
        throw new SAML2Exception(se.getMessage());
    }
    // get the LogoutResponse element from SOAP message
    Element respElem = SOAPCommunicator.getInstance().getSamlpElement(resMsg, "LogoutResponse");
    LogoutResponse sloResponse = ProtocolFactory.getInstance().createLogoutResponse(respElem);
    String userId = null;
    // invoke SPAdapter for preSingleLogoutProcess : SP initiated SOAP
    if ((hostRole != null) && hostRole.equals(SAML2Constants.SP_ROLE)) {
        userId = SPSingleLogout.preSingleLogoutProcess(hostEntity, realm, request, response, null, sloRequest, sloResponse, SAML2Constants.SOAP);
    }
    if (sloResponse == null) {
        debug.error("LogoutUtil.doSLOBySoap : null response");
        throw new SAML2Exception(SAML2Utils.bundle.getString("nullLogoutResponse"));
    }
    if (debug.messageEnabled()) {
        debug.message("LogoutUtil.doSLOBySOAP : " + "LogoutResponse without SOAP envelope:\n" + sloResponse.toXMLString());
    }
    Issuer resIssuer = sloResponse.getIssuer();
    String requestId = sloResponse.getInResponseTo();
    SAML2Utils.verifyResponseIssuer(realm, hostEntity, resIssuer, requestId);
    String remoteEntityID = sloResponse.getIssuer().getValue();
    verifySLOResponse(sloResponse, realm, remoteEntityID, hostEntity, hostRole);
    boolean success = checkSLOResponse(sloResponse, requestID);
    if (debug.messageEnabled()) {
        debug.message("Request success : " + success);
    }
    if (success == false) {
        if (SPCache.isFedlet) {
            FedletAdapter fedletAdapter = SAML2Utils.getFedletAdapterClass(hostEntity, realm);
            if (fedletAdapter != null) {
                fedletAdapter.onFedletSLOFailure(request, response, sloRequest, sloResponse, hostEntity, remoteEntityID, SAML2Constants.SOAP);
            }
        }
        throw new SAML2Exception(SAML2Utils.bundle.getString("sloFailed"));
    } else {
        // invoke SPAdapter for postSLOSuccess : SP inited SOAP 
        if ((hostRole != null) && hostRole.equals(SAML2Constants.SP_ROLE)) {
            if (SPCache.isFedlet) {
                FedletAdapter fedletAdapter = SAML2Utils.getFedletAdapterClass(hostEntity, realm);
                if (fedletAdapter != null) {
                    fedletAdapter.onFedletSLOSuccess(request, response, sloRequest, sloResponse, hostEntity, remoteEntityID, SAML2Constants.SOAP);
                }
            } else {
                SPSingleLogout.postSingleLogoutSuccess(hostEntity, realm, request, response, userId, sloRequest, sloResponse, SAML2Constants.SOAP);
            }
        }
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) FedletAdapter(com.sun.identity.saml2.plugins.FedletAdapter) LogoutResponse(com.sun.identity.saml2.protocol.LogoutResponse) Issuer(com.sun.identity.saml2.assertion.Issuer) SOAPException(javax.xml.soap.SOAPException) SingleLogoutServiceElement(com.sun.identity.saml2.jaxb.metadata.SingleLogoutServiceElement) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) Element(org.w3c.dom.Element) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement) SOAPMessage(javax.xml.soap.SOAPMessage)

Example 9 with LogoutResponse

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

the class LogoutUtil method verifySLOResponse.

/**
     * Verify the signature in LogoutResponse.
     *
     * @param sloResponse SLO response 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 verifySLOResponse(LogoutResponse sloResponse, String realm, String remoteEntity, String hostEntity, String hostEntityRole) throws SAML2Exception, SessionException {
    String method = "verifySLOResponse : ";
    boolean needVerifySignature = SAML2Utils.getWantLogoutResponseSigned(realm, hostEntity, hostEntityRole);
    if (needVerifySignature == false) {
        if (debug.messageEnabled()) {
            debug.message(method + "SLOResponse doesn't need to be verified.");
        }
        return true;
    }
    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()) {
        boolean valid = sloResponse.isSignatureValid(signingCerts);
        if (debug.messageEnabled()) {
            debug.message(method + "Signature is : " + valid);
        }
        return valid;
    } else {
        debug.error("Incorrect configuration for Signing Certificate.");
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
}
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 10 with LogoutResponse

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

the class SPSingleLogout method processLogoutResponse.

/**
     * Gets and processes the Single <code>LogoutResponse</code> from IDP,
     * destroys the local session, checks response's issuer
     * and inResponseTo.
     *
     * @param request the HttpServletRequest.
     * @param response the HttpServletResponse.
     * @param samlResponse <code>LogoutResponse</code> in the
     *          XML string format.
     * @param relayState the target URL on successful
     * <code>LogoutResponse</code>.
     * @throws SAML2Exception if error processing
     *          <code>LogoutResponse</code>.
     * @throws SessionException if error processing
     *          <code>LogoutResponse</code>.
     */
public static Map<String, String> processLogoutResponse(HttpServletRequest request, HttpServletResponse response, String samlResponse, String relayState) throws SAML2Exception, SessionException {
    String method = "SPSingleLogout:processLogoutResponse : ";
    if (debug.messageEnabled()) {
        debug.message(method + "samlResponse : " + samlResponse);
        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"));
    }
    // Validate the RelayState URL.
    SAML2Utils.validateRelayStateURL(realm, spEntityID, relayState, SAML2Constants.SP_ROLE);
    LogoutResponse logoutRes = null;
    if (rmethod.equals("POST")) {
        logoutRes = LogoutUtil.getLogoutResponseFromPost(samlResponse, response);
    } else if (rmethod.equals("GET")) {
        String decodedStr = SAML2Utils.decodeFromRedirect(samlResponse);
        if (decodedStr == null) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullDecodedStrFromSamlResponse"));
        }
        logoutRes = ProtocolFactory.getInstance().createLogoutResponse(decodedStr);
    }
    if (logoutRes == null) {
        if (debug.messageEnabled()) {
            debug.message("SSingleLogout:processLogoutResponse: logoutRes " + "is null");
        }
        return null;
    }
    String idpEntityID = logoutRes.getIssuer().getValue();
    Issuer resIssuer = logoutRes.getIssuer();
    String inResponseTo = logoutRes.getInResponseTo();
    LogoutRequest logoutReq = (LogoutRequest) SPCache.logoutRequestIDHash.remove(inResponseTo);
    if (logoutReq == null) {
        logoutReq = (LogoutRequest) SAML2Store.getTokenFromStore(inResponseTo);
    }
    if (logoutReq == null && SAML2FailoverUtils.isSAML2FailoverEnabled()) {
        //check the samlFailover cache instead
        try {
            logoutReq = (LogoutRequest) SAML2FailoverUtils.retrieveSAML2Token(inResponseTo);
        } catch (SAML2TokenRepositoryException e) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("LogoutRequestIDandInResponseToDoNotMatch"));
        }
    }
    // invoke SPAdapter preSingleLogoutProcess
    String userId = null;
    if (!SPCache.isFedlet) {
        userId = preSingleLogoutProcess(spEntityID, realm, request, response, null, logoutReq, logoutRes, binding);
    }
    SAML2Utils.verifyResponseIssuer(realm, spEntityID, resIssuer, inResponseTo);
    boolean needToVerify = SAML2Utils.getWantLogoutResponseSigned(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);
    }
    Map<String, String> infoMap = new HashMap<String, String>();
    infoMap.put("entityid", spEntityID);
    infoMap.put(SAML2Constants.REALM, realm);
    if (needToVerify) {
        boolean valid = false;
        if (rmethod.equals("GET")) {
            String queryString = request.getQueryString();
            valid = SAML2Utils.verifyQueryString(queryString, realm, SAML2Constants.SP_ROLE, idpEntityID);
        } else {
            valid = LogoutUtil.verifySLOResponse(logoutRes, realm, idpEntityID, spEntityID, SAML2Constants.SP_ROLE);
        }
        if (!valid) {
            debug.error("SPSingleLogout.processLogoutResponse: " + "Invalid signature in SLO Response.");
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSignInResponse"));
        }
        SPSSODescriptorElement spsso = sm.getSPSSODescriptor(realm, spEntityID);
        String loc = getSLOResponseLocationOrLocation(spsso, binding);
        if (!SAML2Utils.verifyDestination(logoutRes.getDestination(), loc)) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidDestination"));
        }
    }
    if (inResponseTo == null || inResponseTo.length() == 0) {
        if (debug.messageEnabled()) {
            debug.message("LogoutResponse inResponseTo is null");
        }
        throw new SAML2Exception(SAML2Utils.bundle.getString("nullInResponseToFromSamlResponse"));
    }
    if (logoutReq != null) {
        if (debug.messageEnabled()) {
            debug.message("LogoutResponse inResponseTo matches " + "LogoutRequest ID.");
        }
    } else {
        if (debug.messageEnabled()) {
            debug.message("LogoutResponse inResponseTo does not match " + "LogoutRequest ID.");
        }
        throw new SAML2Exception(SAML2Utils.bundle.getString("LogoutRequestIDandInResponseToDoNotMatch"));
    }
    infoMap.put("inResponseTo", inResponseTo);
    infoMap.put(SAML2Constants.RELAY_STATE, relayState);
    // destroy session
    try {
        Object session = sessionProvider.getSession(request);
        if ((session != null) && sessionProvider.isValid(session)) {
            sessionProvider.invalidateSession(session, request, response);
        }
    } catch (SessionException se) {
        debug.message("SPSingleLogout.processLogoutResponse() : Unable to invalidate session: " + se.getMessage());
    }
    if (!SPCache.isFedlet) {
        if (isSuccess(logoutRes)) {
            // invoke SPAdapter postSingleLogoutSucces
            postSingleLogoutSuccess(spEntityID, realm, request, response, userId, logoutReq, logoutRes, binding);
        } else {
            throw new SAML2Exception(SAML2Utils.BUNDLE_NAME, "sloFailed", null);
        }
    } else {
        // obtain fedlet adapter
        FedletAdapter fedletAdapter = SAML2Utils.getFedletAdapterClass(spEntityID, realm);
        if (fedletAdapter != null) {
            if (isSuccess(logoutRes)) {
                fedletAdapter.onFedletSLOSuccess(request, response, logoutReq, logoutRes, spEntityID, idpEntityID, binding);
            } else {
                fedletAdapter.onFedletSLOFailure(request, response, logoutReq, logoutRes, spEntityID, idpEntityID, binding);
                throw new SAML2Exception(SAML2Utils.BUNDLE_NAME, "sloFailed", null);
            }
        }
    }
    return infoMap;
}
Also used : LogoutResponse(com.sun.identity.saml2.protocol.LogoutResponse) Issuer(com.sun.identity.saml2.assertion.Issuer) HashMap(java.util.HashMap) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) SessionException(com.sun.identity.plugin.session.SessionException) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) FedletAdapter(com.sun.identity.saml2.plugins.FedletAdapter) List(java.util.List) ArrayList(java.util.ArrayList) LogoutRequest(com.sun.identity.saml2.protocol.LogoutRequest) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)

Aggregations

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