Search in sources :

Example 51 with SAML2MetaException

use of com.sun.identity.saml2.meta.SAML2MetaException in project OpenAM by OpenRock.

the class IDPSingleLogout method initiateLogoutRequest.

/**
     * Parses the request parameters and initiates the Logout
     * Request to be sent to the SP.
     *
     * @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.
     * @throws SAML2Exception if error initiating request to SP.
     */
public static void initiateLogoutRequest(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String binding, Map paramsMap) throws SAML2Exception {
    if (debug.messageEnabled()) {
        debug.message("in initiateLogoutRequest");
        debug.message("binding : " + binding);
        debug.message("logoutAll : " + (String) paramsMap.get(SAML2Constants.LOGOUT_ALL));
        debug.message("paramsMap : " + paramsMap);
    }
    boolean logoutall = false;
    String logoutAllValue = (String) paramsMap.get(SAML2Constants.LOGOUT_ALL);
    if ((logoutAllValue != null) && logoutAllValue.equalsIgnoreCase("true")) {
        logoutall = true;
    }
    String metaAlias = (String) paramsMap.get(SAML2Constants.IDP_META_ALIAS);
    try {
        Object session = sessionProvider.getSession(request);
        String sessUser = sessionProvider.getPrincipalName(session);
        if (session == null) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullSSOToken"));
        }
        if (metaAlias == null) {
            String[] values = sessionProvider.getProperty(session, SAML2Constants.IDP_META_ALIAS);
            if (values != null && values.length != 0) {
                metaAlias = values[0];
            }
        }
        if (metaAlias == null) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullIDPMetaAlias"));
        }
        paramsMap.put(SAML2Constants.METAALIAS, metaAlias);
        String realm = SAML2Utils.getRealm(SAML2MetaUtils.getRealmByMetaAlias(metaAlias));
        String idpEntityID = sm.getEntityByMetaAlias(metaAlias);
        if (idpEntityID == null) {
            debug.error("Identity Provider ID is missing");
            String[] data = { idpEntityID };
            LogUtil.error(Level.INFO, LogUtil.INVALID_IDP, data, null);
            throw new SAML2Exception(SAML2Utils.bundle.getString("nullIDPEntityID"));
        }
        // clean up session index
        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;
        }
        // then send the request to the original server
        if (!SAML2FailoverUtils.isSAML2FailoverEnabled() && isMisroutedRequest(request, response, out, session)) {
            return;
        } else {
            if (debug.messageEnabled()) {
                debug.message("IDPSingleLogout.initiateLogoutRequest: " + "SAML2 Failover will be attempted. Be sure SFO is " + "properly configured or the attempt will fail");
            }
        }
        IDPSession idpSession = IDPCache.idpSessionsByIndices.get(idpSessionIndex);
        if (idpSession == null) {
            if (debug.messageEnabled()) {
                debug.message("IDPSLO.initiateLogoutRequest: " + "IDP Session with session index " + idpSessionIndex + " already removed.");
            }
            try {
                if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                    SAML2FailoverUtils.deleteSAML2Token(idpSessionIndex);
                }
            } catch (SAML2TokenRepositoryException se) {
                debug.error("IDPSingleLogout.initiateLogoutReq: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
            }
            IDPCache.authnContextCache.remove(idpSessionIndex);
            MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
            return;
        }
        if (debug.messageEnabled()) {
            debug.message("idpSessionIndex=" + idpSessionIndex);
        }
        List<NameIDandSPpair> list = idpSession.getNameIDandSPpairs();
        int n = list.size();
        if (debug.messageEnabled()) {
            debug.message("IDPSingleLogout.initiateLogoutReq:" + " NameIDandSPpairs=" + list + ", size=" + n);
        }
        if (n == 0) {
            if (debug.messageEnabled()) {
                debug.message("No SP session participant(s)");
            }
            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.initiateLogoutReq: Error while deleting token from " + "SAML2 Token Repository for idpSessionIndex:" + idpSessionIndex, se);
            }
            IDPCache.authnContextCache.remove(idpSessionIndex);
            MultiProtocolUtils.invalidateSession(session, request, response, SingleLogoutManager.SAML2);
            return;
        }
        String relayState = (String) paramsMap.get(SAML2Constants.RELAY_STATE);
        // Validate the RelayState URL.
        SAML2Utils.validateRelayStateURL(realm, idpEntityID, relayState, SAML2Constants.IDP_ROLE);
        int soapFailCount = 0;
        idpSession.setOriginatingLogoutRequestBinding(binding);
        for (int i = 0; i < n; i++) {
            NameIDandSPpair pair = list.remove(0);
            removeTransientNameIDFromCache(pair.getNameID());
            String spEntityID = pair.getSPEntityID();
            if (debug.messageEnabled()) {
                debug.message("IDPSingleLogout.initLogoutReq: processing spEntityID " + spEntityID);
            }
            List extensionsList = LogoutUtil.getExtensionsList(paramsMap);
            List<SingleLogoutServiceElement> slosList = getSPSLOServiceEndpoints(realm, spEntityID);
            // get IDP entity config in case of SOAP, for basic auth info
            SPSSOConfigElement spConfig = sm.getSPSSOConfig(realm, spEntityID);
            if (logoutall == true) {
                idpSessionIndex = null;
            }
            SingleLogoutServiceElement logoutEndpoint = LogoutUtil.getMostAppropriateSLOServiceLocation(slosList, idpSession.getOriginatingLogoutRequestBinding());
            if (logoutEndpoint == null) {
                continue;
            }
            StringBuffer requestID = null;
            try {
                requestID = LogoutUtil.doLogout(metaAlias, spEntityID, extensionsList, logoutEndpoint, relayState, idpSessionIndex, pair.getNameID(), request, response, paramsMap, spConfig);
            } catch (SAML2Exception ex) {
                if (logoutEndpoint.getBinding().equals(SAML2Constants.SOAP)) {
                    debug.error("IDPSingleLogout.initiateLogoutRequest:", ex);
                    soapFailCount++;
                    continue;
                } else {
                    throw ex;
                }
            }
            String requestIDStr = requestID.toString();
            String bindingUsed = logoutEndpoint.getBinding();
            if (debug.messageEnabled()) {
                debug.message("\nIDPSLO.requestIDStr = " + requestIDStr + "\nbinding = " + bindingUsed);
            }
            if (!requestIDStr.isEmpty() && (bindingUsed.equals(SAML2Constants.HTTP_REDIRECT) || bindingUsed.equals(SAML2Constants.HTTP_POST))) {
                idpSession.setPendingLogoutRequestID(requestIDStr);
                idpSession.setLogoutAll(logoutall);
                Map logoutMap = (Map) paramsMap.get("LogoutMap");
                if (logoutMap != null && !logoutMap.isEmpty()) {
                    IDPCache.logoutResponseCache.put(requestIDStr, (Map) paramsMap.get("LogoutMap"));
                }
                return;
            }
        }
        //requested binding, or SOAP was used for the logout (or the mixture of this two).
        if (logoutall == true) {
            String userID = sessionProvider.getPrincipalName(idpSession.getSession());
            destroyAllTokenForUser(userID, request, response);
        } else {
            MultiProtocolUtils.invalidateSession(idpSession.getSession(), request, response, SingleLogoutManager.SAML2);
            IDPCache.idpSessionsByIndices.remove(idpSessionIndex);
            if (agent != null && agent.isRunning() && saml2Svc != null) {
                saml2Svc.setIdpSessionCount((long) IDPCache.idpSessionsByIndices.size());
            }
            IDPCache.authnContextCache.remove(idpSessionIndex);
        }
        //handling the case when the auth was initiated with HTTP-Redirect, but only SOAP or no SLO endpoint was
        //available, and also the case when the whole logout process was using SOAP binding from the beginning
        int logoutStatus = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
        boolean isMultiProtocol = MultiProtocolUtils.isMultipleProtocolSession(request, SingleLogoutManager.SAML2);
        //TODO: would be nice to actually return the correct message in idpSingleLogoutInit.jsp
        if (soapFailCount == n) {
            if (isMultiProtocol) {
                logoutStatus = SingleLogoutManager.LOGOUT_FAILED_STATUS;
            }
        } else if (soapFailCount > 0) {
            if (isMultiProtocol) {
                logoutStatus = SingleLogoutManager.LOGOUT_PARTIAL_STATUS;
            }
        }
        // processing multi-federation protocol session
        if (isMultiProtocol) {
            Set set = new HashSet();
            set.add(session);
            boolean isSOAPInitiated = binding.equals(SAML2Constants.SOAP) ? true : false;
            int retStat = SingleLogoutManager.LOGOUT_SUCCEEDED_STATUS;
            try {
                debug.message("IDPSingleLogout.initLogReq: MP");
                retStat = SingleLogoutManager.getInstance().doIDPSingleLogout(set, sessUser, request, response, isSOAPInitiated, true, SingleLogoutManager.SAML2, realm, idpEntityID, null, relayState, null, null, logoutStatus);
            } catch (Exception ex) {
                debug.warning("IDPSingleLogout.initiateLoogutReq: MP", ex);
                throw new SAML2Exception(ex.getMessage());
            }
            if (debug.messageEnabled()) {
                debug.message("IDPSingleLogout.initLogoutRequest: " + "SLOManager return status = " + retStat);
            }
            switch(retStat) {
                case SingleLogoutManager.LOGOUT_FAILED_STATUS:
                    throw new SAML2Exception(SAML2Utils.bundle.getString("sloFailed"));
                case SingleLogoutManager.LOGOUT_PARTIAL_STATUS:
                    throw new SAML2Exception(SAML2Utils.bundle.getString("partialLogout"));
                default:
                    break;
            }
        }
    } catch (SAML2MetaException sme) {
        debug.error("Error retreiving metadata", sme);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    } catch (SessionException ssoe) {
        debug.error("SessionException: ", ssoe);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) SPSSOConfigElement(com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement) 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) 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) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) HashSet(java.util.HashSet)

Example 52 with SAML2MetaException

use of com.sun.identity.saml2.meta.SAML2MetaException in project OpenAM by OpenRock.

the class IDPArtifactResolution method doArtifactResolution.

/**
     * This method processes the artifact resolution request coming 
     * from a service provider. It processes the artifact
     * resolution request sent by the service provider and 
     * sends back a proper SOAPMessage that contains an Assertion.
     *
     * @param request the <code>HttpServletRequest</code> object
     * @param response the <code>HttpServletResponse</code> object
     */
public static void doArtifactResolution(HttpServletRequest request, HttpServletResponse response) {
    String classMethod = "IDPArtifactResolution.doArtifactResolution: ";
    try {
        String idpMetaAlias = request.getParameter(SAML2MetaManager.NAME_META_ALIAS_IN_URI);
        if ((idpMetaAlias == null) || (idpMetaAlias.trim().length() == 0)) {
            idpMetaAlias = SAML2MetaUtils.getMetaAliasByUri(request.getRequestURI());
        }
        if ((idpMetaAlias == null) || (idpMetaAlias.trim().length() == 0)) {
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(classMethod + "unable to get IDP meta alias from request.");
            }
            String[] data = { idpMetaAlias };
            LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, null);
            SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "nullIDPMetaAlias", SAML2Utils.bundle.getString("nullIDPMetaAlias"));
            return;
        }
        // retrieve IDP entity id from meta alias
        String idpEntityID = null;
        String realm = null;
        try {
            idpEntityID = IDPSSOUtil.metaManager.getEntityByMetaAlias(idpMetaAlias);
            if ((idpEntityID == null) || (idpEntityID.trim().length() == 0)) {
                SAMLUtils.debug.error(classMethod + "Unable to get IDP Entity ID from meta.");
                String[] data = { idpEntityID };
                LogUtil.error(Level.INFO, LogUtil.INVALID_IDP, data, null);
                SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "nullIDPEntityID", SAML2Utils.bundle.getString("nullIDPEntityID"));
                return;
            }
            realm = SAML2MetaUtils.getRealmByMetaAlias(idpMetaAlias);
        } catch (SAML2MetaException sme) {
            SAML2Utils.debug.error(classMethod + "Unable to get IDP Entity ID from meta.");
            String[] data = { idpMetaAlias };
            LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, null);
            SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "metaDataError", SAML2Utils.bundle.getString("metaDataError"));
            return;
        }
        if (!SAML2Utils.isIDPProfileBindingSupported(realm, idpEntityID, SAML2Constants.ARTIFACT_RESOLUTION_SERVICE, SAML2Constants.SOAP)) {
            SAML2Utils.debug.error(classMethod + "Artifact Resolution Service binding: Redirect is not " + "supported for " + idpEntityID);
            String[] data = { idpEntityID, SAML2Constants.SOAP };
            LogUtil.error(Level.INFO, LogUtil.BINDING_NOT_SUPPORTED, data, null);
            SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "unsupportedBinding", SAML2Utils.bundle.getString("unsupportedBinding"));
            return;
        }
        try {
            // Get all the headers from the HTTP request
            MimeHeaders headers = getHeaders(request);
            // Get the body of the HTTP request
            InputStream is = request.getInputStream();
            SOAPMessage msg = messageFactory.createMessage(headers, is);
            SOAPMessage reply = null;
            reply = onMessage(msg, request, response, realm, idpEntityID);
            if (reply != null) {
                /* Need to call saveChanges because we're
                     * going to use the MimeHeaders to set HTTP
                     * response information. These MimeHeaders
                     * are generated as part of the save. */
                if (reply.saveRequired()) {
                    reply.saveChanges();
                }
                response.setStatus(HttpServletResponse.SC_OK);
                putHeaders(reply.getMimeHeaders(), response);
                // Write out the message on the response stream
                OutputStream outputStream = response.getOutputStream();
                reply.writeTo(outputStream);
                outputStream.flush();
            } else {
                response.setStatus(HttpServletResponse.SC_NO_CONTENT);
            }
        } catch (SOAPException ex) {
            SAML2Utils.debug.error(classMethod + "SOAP error", ex);
            String[] data = { idpEntityID };
            LogUtil.error(Level.INFO, LogUtil.INVALID_SOAP_MESSAGE, data, null);
            SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "invalidSOAPMessage", SAML2Utils.bundle.getString("invalidSOAPMessage") + " " + ex.getMessage());
            return;
        } catch (SAML2Exception se) {
            SAML2Utils.debug.error(classMethod + "SAML2 error", se);
            SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "unableToCreateArtifactResponse", SAML2Utils.bundle.getString("unableToCreateArtifactResponse") + " " + se.getMessage());
            return;
        }
    } catch (IOException ioe) {
        SAML2Utils.debug.error(classMethod + "I/O rrror", ioe);
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) MimeHeaders(javax.xml.soap.MimeHeaders) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) SOAPException(javax.xml.soap.SOAPException) IOException(java.io.IOException) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) SOAPMessage(javax.xml.soap.SOAPMessage)

Example 53 with SAML2MetaException

use of com.sun.identity.saml2.meta.SAML2MetaException in project OpenAM by OpenRock.

the class IDPArtifactResolution method onMessage.

/**
     * This method generates a <code>SOAPMessage</code> containing the
     * <code>ArtifactResponse</code> that is corresponding to the
     * <code>ArtifactResolve</code> contained in the 
     * <code>SOAPMessage</code> passed in.
     *
     * @param message <code>SOAPMessage</code> contains a
     *             <code>ArtifactResolve</code> 
     * @param request the <code>HttpServletRequest</code> object
     * @param realm the realm to where the identity provider belongs
     * @param idpEntityID the entity id of the identity provider 
     * 
     * @return <code>SOAPMessage</code> contains the 
     *             <code>ArtifactResponse</code>
     * @exception SAML2Exception if the operation is not successful
     */
public static SOAPMessage onMessage(SOAPMessage message, HttpServletRequest request, HttpServletResponse response, String realm, String idpEntityID) throws SAML2Exception {
    String classMethod = "IDPArtifactResolution.onMessage: ";
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "Entering onMessage().");
    }
    Element reqElem = SOAPCommunicator.getInstance().getSamlpElement(message, "ArtifactResolve");
    ArtifactResolve artResolve = ProtocolFactory.getInstance().createArtifactResolve(reqElem);
    if (artResolve == null) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "no valid ArtifactResolve node found in SOAP body.");
        }
        return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "noArtifactResolve", null);
    }
    String spEntityID = artResolve.getIssuer().getValue();
    if (!SAML2Utils.isSourceSiteValid(artResolve.getIssuer(), realm, idpEntityID)) {
        SAML2Utils.debug.error(classMethod + spEntityID + " is not trusted issuer.");
        String[] data = { idpEntityID, realm, artResolve.getID() };
        LogUtil.error(Level.INFO, LogUtil.INVALID_ISSUER_REQUEST, data, null);
        return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "invalidIssuerInRequest", null);
    }
    SPSSODescriptorElement spSSODescriptor = null;
    try {
        spSSODescriptor = IDPSSOUtil.metaManager.getSPSSODescriptor(realm, spEntityID);
    } catch (SAML2MetaException sme) {
        SAML2Utils.debug.error(classMethod, sme);
        spSSODescriptor = null;
    }
    if (spSSODescriptor == null) {
        SAML2Utils.debug.error(classMethod + "Unable to get SP SSO Descriptor from meta.");
        return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "metaDataError", null);
    }
    OrderedSet acsSet = SPSSOFederate.getACSUrl(spSSODescriptor, SAML2Constants.HTTP_ARTIFACT);
    String acsURL = (String) acsSet.get(0);
    //String protocolBinding = (String) acsSet.get(1);
    String isArtifactResolveSigned = SAML2Utils.getAttributeValueFromSSOConfig(realm, idpEntityID, SAML2Constants.IDP_ROLE, SAML2Constants.WANT_ARTIFACT_RESOLVE_SIGNED);
    if ((isArtifactResolveSigned != null) && (isArtifactResolveSigned.equals(SAML2Constants.TRUE))) {
        if (!artResolve.isSigned()) {
            SAML2Utils.debug.error(classMethod + "The artifact resolve is not signed " + "when it is expected to be signed.");
            return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "ArtifactResolveNotSigned", null);
        }
        Set<X509Certificate> verificationCerts = KeyUtil.getVerificationCerts(spSSODescriptor, spEntityID, SAML2Constants.SP_ROLE);
        if (!artResolve.isSignatureValid(verificationCerts)) {
            SAML2Utils.debug.error(classMethod + "artifact resolve verification failed.");
            return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "invalidArtifact", null);
        }
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "artifact resolve signature verification is successful.");
        }
    }
    Artifact art = artResolve.getArtifact();
    if (art == null) {
        SAML2Utils.debug.error(classMethod + "Unable to get an artifact from ArtifactResolve.");
        return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "invalidArtifactSignature", null);
    }
    String artStr = art.getArtifactValue();
    Response res = (Response) IDPCache.responsesByArtifacts.remove(artStr);
    String remoteArtURL = null;
    boolean saml2FailoverEnabled = SAML2FailoverUtils.isSAML2FailoverEnabled();
    if (res == null) {
        // in LB case, artifact may reside on the other server.
        String targetServerID = SAML2Utils.extractServerId(art.getMessageHandle());
        if (targetServerID == null) {
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(classMethod + "target serverID is null");
            }
            return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "InvalidArtifactId", null);
        }
        String localServerID = SAML2Utils.getLocalServerID();
        boolean localTarget = localServerID.equals(targetServerID);
        if (!localTarget) {
            if (!SystemConfigurationUtil.isValidServerId(targetServerID)) {
                if (SAML2Utils.debug.messageEnabled()) {
                    SAML2Utils.debug.message(classMethod + "target serverID is not valid: " + targetServerID);
                }
                return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "InvalidArtifactId", null);
            }
            try {
                String remoteServiceURL = SystemConfigurationUtil.getServerFromID(targetServerID);
                remoteArtURL = remoteServiceURL + SAML2Utils.removeDeployUri(request.getRequestURI());
                SOAPConnection con = SOAPCommunicator.getInstance().openSOAPConnection();
                SOAPMessage resMsg = con.call(message, remoteArtURL);
                return resMsg;
            } catch (Exception ex) {
                if (SAML2Utils.debug.messageEnabled()) {
                    SAML2Utils.debug.message(classMethod + "unable to forward request to remote server. " + "remote url = " + remoteArtURL, ex);
                }
                if (!saml2FailoverEnabled) {
                    return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "RemoteArtifactResolutionFailed", null);
                }
            // when the target server is running but the remote call was
            // failed to this server (due to a network error)
            // and the saml2failover is enabled, we can still find the
            // artifact in the SAML2 repository.
            // However the cached entry in the target server will not be
            // deleted this way.
            }
        }
        if (saml2FailoverEnabled) {
            // Check the SAML2 Token Repository
            try {
                if (SAML2Utils.debug.messageEnabled()) {
                    SAML2Utils.debug.message("Artifact=" + artStr);
                }
                String tmp = (String) SAML2FailoverUtils.retrieveSAML2Token(artStr);
                res = ProtocolFactory.getInstance().createResponse(tmp);
            } catch (SAML2Exception e) {
                SAML2Utils.debug.error(classMethod + " SAML2 ERROR!!!", e);
                return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "UnableToFindResponseInRepo", null);
            } catch (SAML2TokenRepositoryException se) {
                SAML2Utils.debug.error(classMethod + " There was a problem reading the response " + "from the SAML2 Token Repository using artStr:" + artStr, se);
                return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, "UnableToFindResponseInRepo", null);
            }
        }
    }
    if (res == null) {
        return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.CLIENT_FAULT, saml2FailoverEnabled ? "UnableToFindResponseInRepo" : "UnableToFindResponse", null);
    }
    // Remove Response from SAML2 Token Repository
    try {
        if (saml2FailoverEnabled) {
            SAML2FailoverUtils.deleteSAML2Token(artStr);
        }
    } catch (SAML2TokenRepositoryException e) {
        SAML2Utils.debug.error(classMethod + " Error deleting the response from the SAML2 Token Repository using artStr:" + artStr, e);
    }
    Map props = new HashMap();
    String nameIDString = SAML2Utils.getNameIDStringFromResponse(res);
    if (nameIDString != null) {
        props.put(LogUtil.NAME_ID, nameIDString);
    }
    // check if need to sign the assertion
    boolean signAssertion = spSSODescriptor.isWantAssertionsSigned();
    if (signAssertion) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "signing the assertion.");
        }
    }
    // encrypt the assertion or its NameID and/or Attribute based
    // on SP config setting and sign the assertion.
    IDPSSOUtil.signAndEncryptResponseComponents(realm, spEntityID, idpEntityID, res, signAssertion);
    ArtifactResponse artResponse = ProtocolFactory.getInstance().createArtifactResponse();
    Status status = ProtocolFactory.getInstance().createStatus();
    StatusCode statusCode = ProtocolFactory.getInstance().createStatusCode();
    statusCode.setValue(SAML2Constants.SUCCESS);
    status.setStatusCode(statusCode);
    // set the idp entity id as the response issuer
    Issuer issuer = AssertionFactory.getInstance().createIssuer();
    issuer.setValue(idpEntityID);
    artResponse.setStatus(status);
    artResponse.setID(SAML2Utils.generateID());
    artResponse.setInResponseTo(artResolve.getID());
    artResponse.setVersion(SAML2Constants.VERSION_2_0);
    artResponse.setIssueInstant(new Date());
    artResponse.setAny(res.toXMLString(true, true));
    artResponse.setIssuer(issuer);
    artResponse.setDestination(XMLUtils.escapeSpecialCharacters(acsURL));
    String wantArtifactResponseSigned = SAML2Utils.getAttributeValueFromSSOConfig(realm, spEntityID, SAML2Constants.SP_ROLE, SAML2Constants.WANT_ARTIFACT_RESPONSE_SIGNED);
    if ((wantArtifactResponseSigned != null) && (wantArtifactResponseSigned.equals(SAML2Constants.TRUE))) {
        KeyProvider kp = KeyUtil.getKeyProviderInstance();
        if (kp == null) {
            SAML2Utils.debug.error(classMethod + "Unable to get a key provider instance.");
            return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "nullKeyProvider", null);
        }
        String idpSignCertAlias = SAML2Utils.getSigningCertAlias(realm, idpEntityID, SAML2Constants.IDP_ROLE);
        if (idpSignCertAlias == null) {
            SAML2Utils.debug.error(classMethod + "Unable to get the hosted IDP signing certificate alias.");
            return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "missingSigningCertAlias", null);
        }
        String encryptedKeyPass = SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
        PrivateKey key;
        if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
            key = kp.getPrivateKey(idpSignCertAlias);
        } else {
            key = kp.getPrivateKey(idpSignCertAlias, encryptedKeyPass);
        }
        artResponse.sign(key, kp.getX509Certificate(idpSignCertAlias));
    }
    String str = artResponse.toXMLString(true, true);
    String[] logdata = { idpEntityID, artStr, str };
    LogUtil.access(Level.INFO, LogUtil.ARTIFACT_RESPONSE, logdata, null, props);
    if (str != null) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "ArtifactResponse message:\n" + str);
        }
    } else {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "Unable to print ArtifactResponse message.");
        }
    }
    SOAPMessage msg = null;
    try {
        msg = SOAPCommunicator.getInstance().createSOAPMessage(str, false);
    } catch (SOAPException se) {
        SAML2Utils.debug.error(classMethod + "Unable to create a SOAPMessage and add a document ", se);
        return SOAPCommunicator.getInstance().createSOAPFault(SAML2Constants.SERVER_FAULT, "unableToCreateSOAPMessage", null);
    }
    return msg;
}
Also used : KeyProvider(com.sun.identity.saml.xmlsig.KeyProvider) PrivateKey(java.security.PrivateKey) HashMap(java.util.HashMap) Issuer(com.sun.identity.saml2.assertion.Issuer) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) Element(org.w3c.dom.Element) SOAPConnection(javax.xml.soap.SOAPConnection) SOAPMessage(javax.xml.soap.SOAPMessage) StatusCode(com.sun.identity.saml2.protocol.StatusCode) ArtifactResolve(com.sun.identity.saml2.protocol.ArtifactResolve) SOAPException(javax.xml.soap.SOAPException) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) Status(com.sun.identity.saml2.protocol.Status) OrderedSet(com.sun.identity.shared.datastruct.OrderedSet) X509Certificate(java.security.cert.X509Certificate) Artifact(com.sun.identity.saml2.protocol.Artifact) SOAPException(javax.xml.soap.SOAPException) 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) Date(java.util.Date) Response(com.sun.identity.saml2.protocol.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) ArtifactResponse(com.sun.identity.saml2.protocol.ArtifactResponse) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) ArtifactResponse(com.sun.identity.saml2.protocol.ArtifactResponse) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) HashMap(java.util.HashMap) Map(java.util.Map)

Example 54 with SAML2MetaException

use of com.sun.identity.saml2.meta.SAML2MetaException in project OpenAM by OpenRock.

the class DoManageNameID method processHttpRequest.

/**
     * Parses the request parameters and process the ManageNameID
     * Request from the remote entity.
     *
     * @param request the HttpServletRequest.
     * @param response the HttpServletResponse.
     * @param paramsMap Map of all other parameters.
     * @throws SAML2Exception if error occurred while processing the request.
     * @throws SessionException if error processing the request from remote entity.
     * @throws ServletException if request length is invalid.
     */
public static void processHttpRequest(HttpServletRequest request, HttpServletResponse response, Map paramsMap) throws SAML2Exception, SessionException, ServletException {
    String method = "processHttpRequest: ";
    String metaAlias = null;
    String remoteEntityID = null;
    String queryString = null;
    // handle DOS attack
    SAMLUtils.checkHTTPContentLength(request);
    String requestURL = request.getRequestURI();
    metaAlias = SAML2MetaUtils.getMetaAliasByUri(requestURL);
    if (metaAlias == null) {
        logError("MetaAliasNotFound", LogUtil.MISSING_META_ALIAS, metaAlias);
        throw new SAML2Exception(SAML2Utils.bundle.getString("MetaAliasNotFound"));
    }
    String realm = SAML2MetaUtils.getRealmByMetaAlias(metaAlias);
    String hostEntity = metaManager.getEntityByMetaAlias(metaAlias);
    String hostRole = SAML2Utils.getHostEntityRole(paramsMap);
    boolean isSupported = false;
    if (SAML2Constants.IDP_ROLE.equals(hostRole)) {
        isSupported = SAML2Utils.isIDPProfileBindingSupported(realm, hostEntity, SAML2Constants.MNI_SERVICE, SAML2Constants.HTTP_REDIRECT);
    } else {
        isSupported = SAML2Utils.isSPProfileBindingSupported(realm, hostEntity, SAML2Constants.MNI_SERVICE, SAML2Constants.HTTP_REDIRECT);
    }
    if (!isSupported) {
        debug.error(method + "MNI binding: Redirect is not supported for " + hostEntity);
        String[] data = { hostEntity, SAML2Constants.HTTP_REDIRECT };
        LogUtil.error(Level.INFO, LogUtil.BINDING_NOT_SUPPORTED, data, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("unsupportedBinding"));
    }
    // Retrieve ManageNameIDRequest 
    ManageNameIDRequest mniRequest = getMNIRequest(request);
    remoteEntityID = mniRequest.getIssuer().getValue();
    if (remoteEntityID == null) {
        logError("nullRemoteEntityID", LogUtil.MISSING_ENTITY, remoteEntityID);
        throw new SAML2Exception(SAML2Utils.bundle.getString("nullRemoteEntityID"));
    }
    boolean needToVerify = SAML2Utils.getWantMNIRequestSigned(realm, hostEntity, hostRole);
    if (needToVerify) {
        queryString = request.getQueryString();
        boolean valid = SAML2Utils.verifyQueryString(queryString, realm, hostRole, remoteEntityID);
        if (!valid) {
            logError("invalidSignInRequest", LogUtil.MNI_REQUEST_INVALID_SIGNATURE, null);
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSignInRequest"));
        }
    }
    String relayState = request.getParameter(SAML2Constants.RELAY_STATE);
    if (debug.messageEnabled()) {
        debug.message(method + "Meta Alias is : " + metaAlias);
        debug.message(method + "Remote EntityID is : " + remoteEntityID);
        debug.message(method + "Host Entity role is : " + hostRole);
        debug.message(method + "Relay state is : " + relayState);
    }
    try {
        ManageNameIDServiceElement mniService = getMNIServiceElement(realm, remoteEntityID, hostRole, SAML2Constants.HTTP_REDIRECT);
        String mniURL = mniService.getResponseLocation();
        if (mniURL == null) {
            mniURL = mniService.getLocation();
        }
        ManageNameIDResponse mniResponse = processManageNameIDRequest(mniRequest, metaAlias, remoteEntityID, paramsMap, mniURL, SAML2Constants.HTTP_REDIRECT, request, response);
        sendMNIResponse(response, mniResponse, mniURL, relayState, realm, hostEntity, hostRole, remoteEntityID);
    } catch (SAML2MetaException e) {
        logError("metaDataError", LogUtil.METADATA_ERROR, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) ManageNameIDServiceElement(com.sun.identity.saml2.jaxb.metadata.ManageNameIDServiceElement) ManageNameIDRequest(com.sun.identity.saml2.protocol.ManageNameIDRequest) ManageNameIDResponse(com.sun.identity.saml2.protocol.ManageNameIDResponse) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException)

Example 55 with SAML2MetaException

use of com.sun.identity.saml2.meta.SAML2MetaException in project OpenAM by OpenRock.

the class IDPSSOUtil method sendResponseArtifact.

/**
     * This method opens a URL connection to the target specified and
     * sends artifact response to it using the
     * <code>HttpServletResponse</code> object.
     *
     * @param response    the <code>HttpServletResponse</code> object
     * @param idpEntityID the entity id of the identity provider
     * @param realm       the realm name of the identity provider
     * @param acsURL      the assertion consumer service <code>URL</code>
     * @param relayState  the value of the <code>RelayState</code>
     * @param res         the <code>SAML Response</code> object
     * @param session     user session
     * @param props       property map including nameIDString for logging
     * @throws SAML2Exception if the operation is not successful
     */
public static void sendResponseArtifact(HttpServletRequest request, HttpServletResponse response, String idpEntityID, String spEntityID, String realm, String acsURL, String relayState, Response res, Object session, Map props) throws SAML2Exception {
    String classMethod = "IDPSSOUtil.sendResponseArtifact: ";
    IDPSSODescriptorElement idpSSODescriptorElement = null;
    try {
        idpSSODescriptorElement = metaManager.getIDPSSODescriptor(realm, idpEntityID);
        if (idpSSODescriptorElement == null) {
            SAML2Utils.debug.error(classMethod + "Unable to get IDP SSO Descriptor from meta.");
            String[] data = { idpEntityID };
            LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, session, props);
            throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
        }
    } catch (SAML2MetaException sme) {
        SAML2Utils.debug.error(classMethod + "Unable to get IDP SSO Descriptor from meta.");
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, session, props);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
    ArtifactResolutionServiceElement ars = (ArtifactResolutionServiceElement) idpSSODescriptorElement.getArtifactResolutionService().get(0);
    if (ars == null) {
        SAML2Utils.debug.error(classMethod + "Unable to get ArtifactResolutionServiceElement from meta.");
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, session, props);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
    Artifact art = null;
    try {
        art = ProtocolFactory.getInstance().createArtifact(null, ars.getIndex(), SAML2Utils.generateSourceID(idpEntityID), SAML2Utils.generateMessageHandleWithServerID());
    } catch (SAML2Exception se) {
        SAML2Utils.debug.error(classMethod + "Unable to create artifact: ", se);
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.CANNOT_CREATE_ARTIFACT, data, session, props);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "errorCreateArtifact", SAML2Utils.bundle.getString("errorCreateArtifact"));
        return;
    }
    String artStr = art.getArtifactValue();
    try {
        IDPCache.responsesByArtifacts.put(artStr, res);
        if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
            try {
                long expireTime = getValidTimeofResponse(realm, idpEntityID, res) / 1000;
                SAML2FailoverUtils.saveSAML2TokenWithoutSecondaryKey(artStr, res.toXMLString(true, true), expireTime);
                if (SAML2Utils.debug.messageEnabled()) {
                    SAML2Utils.debug.message(classMethod + "Saved Response to SAML2 Token Repository using key " + artStr);
                }
            } catch (SAML2TokenRepositoryException se) {
                SAML2Utils.debug.error(classMethod + "Unable to save Response to the SAML2 Token Repository", se);
            }
        }
        String messageEncoding = SAML2Utils.getAttributeValueFromSSOConfig(realm, spEntityID, SAML2Constants.SP_ROLE, SAML2Constants.RESPONSE_ARTIFACT_MESSAGE_ENCODING);
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "messageEncoding = " + messageEncoding);
            SAML2Utils.debug.message(classMethod + "artStr = " + artStr);
        }
        if ((messageEncoding != null) && (messageEncoding.equals(SAML2Constants.FORM_ENCODING))) {
            String[] logdata = { idpEntityID, realm, acsURL };
            LogUtil.access(Level.INFO, LogUtil.SEND_ARTIFACT, logdata, session, props);
            SAML2Utils.postToTarget(request, response, SAML2Constants.SAML_ART, artStr, "RelayState", relayState, acsURL);
        } else {
            String redirectURL = acsURL + (acsURL.contains("?") ? "&" : "?") + "SAMLart=" + URLEncDec.encode(artStr);
            if ((relayState != null) && (relayState.trim().length() != 0)) {
                redirectURL += "&RelayState=" + URLEncDec.encode(relayState);
            }
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(classMethod + "Redirect URL = " + redirectURL);
            }
            String[] logdata = { idpEntityID, realm, redirectURL };
            LogUtil.access(Level.INFO, LogUtil.SEND_ARTIFACT, logdata, session, props);
            response.sendRedirect(redirectURL);
        }
    } catch (IOException ioe) {
        SAML2Utils.debug.error(classMethod + "Unable to send redirect: ", ioe);
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) IOException(java.io.IOException) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) ArtifactResolutionServiceElement(com.sun.identity.saml2.jaxb.metadata.ArtifactResolutionServiceElement) Artifact(com.sun.identity.saml2.protocol.Artifact) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)

Aggregations

SAML2MetaException (com.sun.identity.saml2.meta.SAML2MetaException)138 List (java.util.List)106 SAML2MetaManager (com.sun.identity.saml2.meta.SAML2MetaManager)90 ArrayList (java.util.ArrayList)80 Iterator (java.util.Iterator)55 Map (java.util.Map)50 AMConsoleException (com.sun.identity.console.base.model.AMConsoleException)47 SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)44 EntityConfigElement (com.sun.identity.saml2.jaxb.entityconfig.EntityConfigElement)43 HashMap (java.util.HashMap)41 SPSSOConfigElement (com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement)30 BaseConfigType (com.sun.identity.saml2.jaxb.entityconfig.BaseConfigType)29 EntityDescriptorElement (com.sun.identity.saml2.jaxb.metadata.EntityDescriptorElement)28 JAXBException (javax.xml.bind.JAXBException)28 SPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement)26 IDPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)24 IDPSSOConfigElement (com.sun.identity.saml2.jaxb.entityconfig.IDPSSOConfigElement)23 Set (java.util.Set)20 IOException (java.io.IOException)15 HashSet (java.util.HashSet)15