Search in sources :

Example 21 with SAML2Exception

use of com.sun.identity.saml2.common.SAML2Exception in project OpenAM by OpenRock.

the class SPACSUtils method getResponse.

/**
     * Retrieves <code>SAML</code> <code>Response</code> from http request.
     * It handles three cases:
     * <pre>
     * 1. using http method get using request parameter "resID".
     *    This is the case after local login is done.
     * 2. using http method get using request parameter "SAMLart".
     *    This is the case for artifact profile.
     * 3. using http method post. This is the case for post profile.
     * </pre>
     * 
     * @param request http servlet request
     * @param response http servlet response
     * @param orgName realm or organization name the service provider resides in
     * @param hostEntityId Entity ID of the hosted service provider
     * @param metaManager <code>SAML2MetaManager</code> instance.
     * @return <code>ResponseInfo</code> instance.
     * @throws SAML2Exception,IOException if it fails in the process.
     */
public static ResponseInfo getResponse(HttpServletRequest request, HttpServletResponse response, String orgName, String hostEntityId, SAML2MetaManager metaManager) throws SAML2Exception, IOException {
    ResponseInfo respInfo = null;
    String method = request.getMethod();
    if (method.equals("GET")) {
        if (!SAML2Utils.isSPProfileBindingSupported(orgName, hostEntityId, SAML2Constants.ACS_SERVICE, SAML2Constants.HTTP_ARTIFACT)) {
            SAMLUtils.sendError(request, response, response.SC_BAD_REQUEST, "unsupportedBinding", SAML2Utils.bundle.getString("unsupportedBinding"));
            throw new SAML2Exception(SAML2Utils.bundle.getString("unsupportedBinding"));
        }
        respInfo = getResponseFromGet(request, response, orgName, hostEntityId, metaManager);
    } else if (method.equals("POST")) {
        String pathInfo = request.getPathInfo();
        if ((pathInfo != null) && (pathInfo.startsWith("/ECP"))) {
            if (!SAML2Utils.isSPProfileBindingSupported(orgName, hostEntityId, SAML2Constants.ACS_SERVICE, SAML2Constants.PAOS)) {
                SAMLUtils.sendError(request, response, response.SC_BAD_REQUEST, "unsupportedBinding", SAML2Utils.bundle.getString("unsupportedBinding"));
                throw new SAML2Exception(SAML2Utils.bundle.getString("unsupportedBinding"));
            }
            respInfo = getResponseFromPostECP(request, response, orgName, hostEntityId, metaManager);
        } else {
            if (!SAML2Utils.isSPProfileBindingSupported(orgName, hostEntityId, SAML2Constants.ACS_SERVICE, SAML2Constants.HTTP_POST)) {
                SAMLUtils.sendError(request, response, response.SC_BAD_REQUEST, "unsupportedBinding", SAML2Utils.bundle.getString("unsupportedBinding"));
                throw new SAML2Exception(SAML2Utils.bundle.getString("unsupportedBinding"));
            }
            respInfo = getResponseFromPost(request, response, orgName, hostEntityId, metaManager);
        }
    } else {
        // not supported
        SAMLUtils.sendError(request, response, response.SC_METHOD_NOT_ALLOWED, "notSupportedHTTPMethod", SAML2Utils.bundle.getString("notSupportedHTTPMethod"));
        throw new SAML2Exception(SAML2Utils.bundle.getString("notSupportedHTTPMethod"));
    }
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message("SPACSUtils.getResponse: got response=" + respInfo.getResponse().toXMLString(true, true));
    }
    return respInfo;
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception)

Example 22 with SAML2Exception

use of com.sun.identity.saml2.common.SAML2Exception in project OpenAM by OpenRock.

the class SPACSUtils method processResponseForFedlet.

/**
     * Processes response from Identity Provider to Fedlet (SP).
     * This will do all required protocol processing, include signature,
     * issuer and audience validation etc. A map containing processing
     * result will be returned. <br>
     * Here is a list of keys and values for the returned map: <br>
     * SAML2Constants.ATTRIBUTE_MAP -- Attribute map containing all attributes
     *                                 passed down from IDP inside the 
     *                                 Assertion. The value is a 
     *                                 <code>java.util.Map</code> whose keys 
     *                                 are attribute names and values are 
     *                                 <code>java.util.Set</code> of string 
     *                                 values for the attributes. <br>
     * SAML2Constants.RELAY_STATE -- Relay state, value is a string <br>
     * SAML2Constants.IDPENTITYID -- IDP entity ID, value is a string<br>
     * SAML2Constants.RESPONSE    -- Response object, value is an instance of 
     *                               com.sun.identity.saml2.protocol.Response
     * SAML2Constants.ASSERTION   -- Assertion object, value is an instance of 
     *                               com.sun.identity.saml2.assertion.Assertion
     * SAML2Constants.SUBJECT     -- Subject object, value is an instance of 
     *                               com.sun.identity.saml2.assertion.Subject
     * SAML2Constants.NAMEID      -- NameID object, value is an instance of 
     *                               com.sun.identity.saml2.assertion.NameID
     *
     * @param request HTTP Servlet request
     * @param response HTTP Servlet response.
     * @param out the print writer for writing out presentation
     *
     * @return <code>Map</code> which holds result of the processing.
     * @throws SAML2Exception if the processing failed due to server error.
     * @throws IOException if the processing failed due to IO error.
     * @throws SessionException if the processing failed due to session error.
     * @throws ServletException if the processing failed due to request error.
     *
     * @supported.api
     */
public static Map processResponseForFedlet(HttpServletRequest request, HttpServletResponse response, PrintWriter out) throws SAML2Exception, IOException, SessionException, ServletException {
    if ((request == null) || (response == null)) {
        throw new ServletException(SAML2SDKUtils.bundle.getString("nullInput"));
    }
    String requestURL = request.getRequestURL().toString();
    SAML2MetaManager metaManager = new SAML2MetaManager();
    if (metaManager == null) {
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("errorMetaManager"));
    }
    String metaAlias = SAML2MetaUtils.getMetaAliasByUri(requestURL);
    if ((metaAlias == null) || (metaAlias.length() == 0)) {
        // Check in case metaAlias has been supplied as a parameter
        metaAlias = request.getParameter(SAML2MetaManager.NAME_META_ALIAS_IN_URI);
        if (metaAlias == null || metaAlias.length() == 0) {
            // pick the first available one
            List spMetaAliases = metaManager.getAllHostedServiceProviderMetaAliases("/");
            if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) {
                // get first one
                metaAlias = (String) spMetaAliases.get(0);
            }
            if ((metaAlias == null) || (metaAlias.length() == 0)) {
                throw new ServletException(SAML2SDKUtils.bundle.getString("nullSPEntityID"));
            }
        }
    }
    String hostEntityId = null;
    try {
        hostEntityId = metaManager.getEntityByMetaAlias(metaAlias);
    } catch (SAML2MetaException sme) {
        SAML2SDKUtils.debug.error("SPACSUtils.processResponseForFedlet", sme);
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("metaDataError"));
    }
    if (hostEntityId == null) {
        // logging?
        throw new SAML2Exception(SAML2SDKUtils.bundle.getString("metaDataError"));
    }
    // organization is always root org
    String orgName = "/";
    String relayState = request.getParameter(SAML2Constants.RELAY_STATE);
    SessionProvider sessionProvider = null;
    ResponseInfo respInfo = null;
    try {
        sessionProvider = SessionManager.getProvider();
    } catch (SessionException se) {
        SAML2SDKUtils.debug.error("SPACSUtils.processResponseForFedlet", se);
        throw new SAML2Exception(se);
    }
    respInfo = SPACSUtils.getResponse(request, response, orgName, hostEntityId, metaManager);
    Object newSession = null;
    // Throws a SAML2Exception if the response cannot be validated
    // or contains a non-Success StatusCode, invoking the SPAdapter SPI
    // for taking action on the failed validation.
    // The resulting exception has its redirectionDone flag set if
    // the SPAdapter issued a HTTP redirect.
    newSession = SPACSUtils.processResponse(request, response, out, metaAlias, null, respInfo, orgName, hostEntityId, metaManager, null);
    SAML2SDKUtils.debug.message("SSO SUCCESS");
    String[] redirected = sessionProvider.getProperty(newSession, SAML2Constants.RESPONSE_REDIRECTED);
    if ((redirected != null) && (redirected.length != 0) && redirected[0].equals("true")) {
        SAML2SDKUtils.debug.message("Already redirected in SPAdapter.");
        // response redirected already in SPAdapter
        return createMapForFedlet(respInfo, null, hostEntityId);
    }
    // redirect to relay state
    String finalUrl = SPACSUtils.getRelayState(relayState, orgName, hostEntityId, metaManager);
    String realFinalUrl = finalUrl;
    if (finalUrl != null && finalUrl.length() != 0) {
        try {
            realFinalUrl = sessionProvider.rewriteURL(newSession, finalUrl);
        } catch (SessionException se) {
            SAML2SDKUtils.debug.message("SPACSUtils.processRespForFedlet", se);
            realFinalUrl = finalUrl;
        }
    }
    String redirectUrl = SPACSUtils.getIntermediateURL(orgName, hostEntityId, metaManager);
    String realRedirectUrl = null;
    if (redirectUrl != null && redirectUrl.length() != 0) {
        if (realFinalUrl != null && realFinalUrl.length() != 0) {
            if (redirectUrl.indexOf("?") != -1) {
                redirectUrl += "&goto=";
            } else {
                redirectUrl += "?goto=";
            }
            redirectUrl += URLEncDec.encode(realFinalUrl);
            try {
                realRedirectUrl = sessionProvider.rewriteURL(newSession, redirectUrl);
            } catch (SessionException se) {
                SAML2SDKUtils.debug.message("SPACSUtils.processRespForFedlet: rewriting failed.", se);
                realRedirectUrl = redirectUrl;
            }
        } else {
            realRedirectUrl = redirectUrl;
        }
    } else {
        realRedirectUrl = finalUrl;
    }
    return createMapForFedlet(respInfo, realRedirectUrl, hostEntityId);
}
Also used : ServletException(javax.servlet.ServletException) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SessionException(com.sun.identity.plugin.session.SessionException) List(java.util.List) ArrayList(java.util.ArrayList) SAML2MetaManager(com.sun.identity.saml2.meta.SAML2MetaManager) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) SessionProvider(com.sun.identity.plugin.session.SessionProvider)

Example 23 with SAML2Exception

use of com.sun.identity.saml2.common.SAML2Exception in project OpenAM by OpenRock.

the class SPSSOFederate method createAuthnRequest.

/**
     * Create an AuthnRequest.
     *
     * @param realmName the authentication realm for this request
     * @param spEntityID the entity id for the service provider
     * @param paramsMap the map of parameters for the authentication request
     * @param spConfigMap the configuration map for the service provider
     * @param extensionsList a list of extendsions for the authentication request
     * @param spsso the SPSSODescriptorElement for theservcie provider
     * @param idpsso the IDPSSODescriptorElement for the identity provider
     * @param ssourl the url for the single sign on request
     * @param isForECP boolean to indicatge if the request originated from an ECP
     * @return a new AuthnRequest object
     * @throws SAML2Exception
     */
public static AuthnRequest createAuthnRequest(final String realmName, final String spEntityID, final Map paramsMap, final Map spConfigMap, final List extensionsList, final SPSSODescriptorElement spsso, final IDPSSODescriptorElement idpsso, final String ssourl, final boolean isForECP) throws SAML2Exception {
    // generate unique request ID
    String requestID = SAML2Utils.generateID();
    if ((requestID == null) || (requestID.length() == 0)) {
        throw new SAML2Exception(SAML2Utils.bundle.getString("cannotGenerateID"));
    }
    // retrieve data from the params map and if not found get
    // default values from the SPConfig Attributes
    // destinationURI required if message is signed.
    String destinationURI = getParameter(paramsMap, SAML2Constants.DESTINATION);
    Boolean isPassive = doPassive(paramsMap, spConfigMap);
    Boolean isforceAuthn = isForceAuthN(paramsMap, spConfigMap);
    boolean allowCreate = isAllowCreate(paramsMap, spConfigMap);
    boolean includeRequestedAuthnContextFlag = includeRequestedAuthnContext(paramsMap, spConfigMap);
    String consent = getParameter(paramsMap, SAML2Constants.CONSENT);
    Extensions extensions = createExtensions(extensionsList);
    String nameIDPolicyFormat = getParameter(paramsMap, SAML2Constants.NAMEID_POLICY_FORMAT);
    // get NameIDPolicy Element 
    NameIDPolicy nameIDPolicy = createNameIDPolicy(spEntityID, nameIDPolicyFormat, allowCreate, spsso, idpsso, realmName, paramsMap);
    Issuer issuer = createIssuer(spEntityID);
    Integer acsIndex = getIndex(paramsMap, SAML2Constants.ACS_URL_INDEX);
    Integer attrIndex = getIndex(paramsMap, SAML2Constants.ATTR_INDEX);
    String protocolBinding = isForECP ? SAML2Constants.PAOS : getParameter(paramsMap, "binding");
    OrderedSet acsSet = getACSUrl(spsso, protocolBinding);
    String acsURL = (String) acsSet.get(0);
    protocolBinding = (String) acsSet.get(1);
    if (!SAML2Utils.isSPProfileBindingSupported(realmName, spEntityID, SAML2Constants.ACS_SERVICE, protocolBinding)) {
        SAML2Utils.debug.error("SPSSOFederate.createAuthnRequest:" + protocolBinding + "is not supported for " + spEntityID);
        String[] data = { spEntityID, protocolBinding };
        LogUtil.error(Level.INFO, LogUtil.BINDING_NOT_SUPPORTED, data, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("unsupportedBinding"));
    }
    AuthnRequest authnReq = ProtocolFactory.getInstance().createAuthnRequest();
    if (!isForECP) {
        if ((destinationURI == null) || (destinationURI.length() == 0)) {
            authnReq.setDestination(XMLUtils.escapeSpecialCharacters(ssourl));
        } else {
            authnReq.setDestination(XMLUtils.escapeSpecialCharacters(destinationURI));
        }
    }
    authnReq.setConsent(consent);
    authnReq.setIsPassive(isPassive);
    authnReq.setForceAuthn(isforceAuthn);
    authnReq.setAttributeConsumingServiceIndex(attrIndex);
    authnReq.setAssertionConsumerServiceIndex(acsIndex);
    authnReq.setAssertionConsumerServiceURL(XMLUtils.escapeSpecialCharacters(acsURL));
    authnReq.setProtocolBinding(protocolBinding);
    authnReq.setIssuer(issuer);
    authnReq.setNameIDPolicy(nameIDPolicy);
    if (includeRequestedAuthnContextFlag) {
        authnReq.setRequestedAuthnContext(createReqAuthnContext(realmName, spEntityID, paramsMap, spConfigMap));
    }
    if (extensions != null) {
        authnReq.setExtensions(extensions);
    }
    // Required attributes in authn request
    authnReq.setID(requestID);
    authnReq.setVersion(SAML2Constants.VERSION_2_0);
    authnReq.setIssueInstant(new Date());
    //IDP Proxy 
    Boolean enableIDPProxy = getAttrValueFromMap(spConfigMap, SAML2Constants.ENABLE_IDP_PROXY);
    if ((enableIDPProxy != null) && enableIDPProxy.booleanValue()) {
        Scoping scoping = ProtocolFactory.getInstance().createScoping();
        String proxyCountParam = getParameter(spConfigMap, SAML2Constants.IDP_PROXY_COUNT);
        if (proxyCountParam != null && (!proxyCountParam.equals(""))) {
            scoping.setProxyCount(new Integer(proxyCountParam));
        }
        List proxyIDPs = (List) spConfigMap.get(SAML2Constants.IDP_PROXY_LIST);
        if (proxyIDPs != null && !proxyIDPs.isEmpty()) {
            Iterator iter = proxyIDPs.iterator();
            ArrayList list = new ArrayList();
            while (iter.hasNext()) {
                IDPEntry entry = ProtocolFactory.getInstance().createIDPEntry();
                entry.setProviderID((String) iter.next());
                list.add(entry);
            }
            IDPList idpList = ProtocolFactory.getInstance().createIDPList();
            idpList.setIDPEntries(list);
            scoping.setIDPList(idpList);
        }
        authnReq.setScoping(scoping);
    }
    return authnReq;
}
Also used : OrderedSet(com.sun.identity.shared.datastruct.OrderedSet) NameIDPolicy(com.sun.identity.saml2.protocol.NameIDPolicy) Issuer(com.sun.identity.saml2.assertion.Issuer) ArrayList(java.util.ArrayList) IDPList(com.sun.identity.saml2.protocol.IDPList) Extensions(com.sun.identity.saml2.protocol.Extensions) Date(java.util.Date) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) AuthnRequest(com.sun.identity.saml2.protocol.AuthnRequest) Scoping(com.sun.identity.saml2.protocol.Scoping) Iterator(java.util.Iterator) List(java.util.List) IDPList(com.sun.identity.saml2.protocol.IDPList) ArrayList(java.util.ArrayList) IDPEntry(com.sun.identity.saml2.protocol.IDPEntry)

Example 24 with SAML2Exception

use of com.sun.identity.saml2.common.SAML2Exception in project OpenAM by OpenRock.

the class SPACSUtils method getResponseFromPostECP.

/**
     * Obtains <code>SAML Response</code> from <code>SOAPBody</code>.
     * Used by ECP profile.
     */
private static ResponseInfo getResponseFromPostECP(HttpServletRequest request, HttpServletResponse response, String orgName, String hostEntityId, SAML2MetaManager metaManager) throws SAML2Exception, IOException {
    Message message = null;
    try {
        message = new Message(SOAPCommunicator.getInstance().getSOAPMessage(request));
    } catch (SOAPException soapex) {
        String[] data = { hostEntityId };
        LogUtil.error(Level.INFO, LogUtil.CANNOT_INSTANTIATE_SOAP_MESSAGE_ECP, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "failedToCreateSOAPMessage", soapex.getMessage());
        throw new SAML2Exception(soapex.getMessage());
    } catch (SOAPBindingException soapex) {
        String[] data = { hostEntityId };
        LogUtil.error(Level.INFO, LogUtil.CANNOT_INSTANTIATE_SOAP_MESSAGE_ECP, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "failedToCreateSOAPMessage", soapex.getMessage());
        throw new SAML2Exception(soapex.getMessage());
    } catch (SOAPFaultException sfex) {
        String[] data = { hostEntityId };
        LogUtil.error(Level.INFO, LogUtil.RECEIVE_SOAP_FAULT_ECP, data, null);
        String faultString = sfex.getSOAPFaultMessage().getSOAPFault().getFaultString();
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "failedToCreateSOAPMessage", faultString);
        throw new SAML2Exception(faultString);
    }
    List soapHeaders = message.getOtherSOAPHeaders();
    ECPRelayState ecpRelayState = null;
    if ((soapHeaders != null) && (!soapHeaders.isEmpty())) {
        for (Iterator iter = soapHeaders.iterator(); iter.hasNext(); ) {
            Element headerEle = (Element) iter.next();
            try {
                ecpRelayState = ECPFactory.getInstance().createECPRelayState(headerEle);
                break;
            } catch (SAML2Exception saml2ex) {
            // not ECP RelayState
            }
        }
    }
    String relayState = null;
    if (ecpRelayState != null) {
        relayState = ecpRelayState.getValue();
    }
    List soapBodies = message.getBodies();
    if ((soapBodies == null) || (soapBodies.isEmpty())) {
        String[] data = { hostEntityId };
        LogUtil.error(Level.INFO, LogUtil.CANNOT_INSTANTIATE_SAML_RESPONSE_FROM_ECP, data, null);
        SAMLUtils.sendError(request, response, response.SC_BAD_REQUEST, "missingSAMLResponse", SAML2Utils.bundle.getString("missingSAMLResponse"));
        throw new SAML2Exception(SAML2Utils.bundle.getString("missingSAMLResponse"));
    }
    Element resElem = (Element) soapBodies.get(0);
    Response resp = null;
    try {
        resp = ProtocolFactory.getInstance().createResponse(resElem);
    } catch (SAML2Exception se) {
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message("SPACSUtils.getResponseFromPostECP:" + "Couldn't create Response:", se);
        }
        String[] data = { hostEntityId };
        LogUtil.error(Level.INFO, LogUtil.CANNOT_INSTANTIATE_SAML_RESPONSE_FROM_ECP, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "failedToCreateResponse", se.getMessage());
        throw se;
    }
    String idpEntityID = resp.getIssuer().getValue();
    IDPSSODescriptorElement idpDesc = null;
    try {
        idpDesc = metaManager.getIDPSSODescriptor(orgName, idpEntityID);
    } catch (SAML2MetaException se) {
        String[] data = { orgName, idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.IDP_META_NOT_FOUND, data, null);
        SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "failedToGetIDPSSODescriptor", se.getMessage());
        throw se;
    }
    Set<X509Certificate> certificates = KeyUtil.getVerificationCerts(idpDesc, idpEntityID, SAML2Constants.IDP_ROLE);
    List assertions = resp.getAssertion();
    if ((assertions != null) && (!assertions.isEmpty())) {
        for (Iterator iter = assertions.iterator(); iter.hasNext(); ) {
            Assertion assertion = (Assertion) iter.next();
            if (!assertion.isSigned()) {
                if (SAML2Utils.debug.messageEnabled()) {
                    SAML2Utils.debug.message("SPACSUtils.getResponseFromPostECP: " + " Assertion is not signed.");
                }
                String[] data = { idpEntityID };
                LogUtil.error(Level.INFO, LogUtil.ECP_ASSERTION_NOT_SIGNED, data, null);
                SAMLUtils.sendError(request, response, response.SC_INTERNAL_SERVER_ERROR, "assertionNotSigned", SAML2Utils.bundle.getString("assertionNotSigned"));
                throw new SAML2Exception(SAML2Utils.bundle.getString("assertionNotSigned"));
            } else if (!assertion.isSignatureValid(certificates)) {
                if (SAML2Utils.debug.messageEnabled()) {
                    SAML2Utils.debug.message("SPACSUtils.getResponseFromPostECP: " + " Assertion signature is invalid.");
                }
                String[] data = { idpEntityID };
                LogUtil.error(Level.INFO, LogUtil.ECP_ASSERTION_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"));
            }
        }
    }
    return new ResponseInfo(resp, SAML2Constants.PAOS, relayState);
}
Also used : Message(com.sun.identity.liberty.ws.soapbinding.Message) SOAPMessage(javax.xml.soap.SOAPMessage) SOAPBindingException(com.sun.identity.liberty.ws.soapbinding.SOAPBindingException) 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) Assertion(com.sun.identity.saml2.assertion.Assertion) SOAPFaultException(com.sun.identity.liberty.ws.soapbinding.SOAPFaultException) X509Certificate(java.security.cert.X509Certificate) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) Response(com.sun.identity.saml2.protocol.Response) ArtifactResponse(com.sun.identity.saml2.protocol.ArtifactResponse) HttpServletResponse(javax.servlet.http.HttpServletResponse) SOAPException(javax.xml.soap.SOAPException) ECPRelayState(com.sun.identity.saml2.ecp.ECPRelayState) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)

Example 25 with SAML2Exception

use of com.sun.identity.saml2.common.SAML2Exception in project OpenAM by OpenRock.

the class SPACSUtils method processResponse.

/**
     * Authenticates user with <code>Response</code>.
     * Auth session upgrade will be called if input session is
     * not null.
     * Otherwise, saml2 auth module is called. The name of the auth module
     * is retrieved from <code>SPSSOConfig</code>. If not found, "SAML2" will
     * be used.
     *
     * @param request HTTP Servlet request
     * @param response HTTP Servlet response.
     * @param out the print writer for writing out presentation
     * @param metaAlias metaAlias for the service provider
     * @param session input session object. It could be null.
     * @param respInfo <code>ResponseInfo</code> to be verified.
     * @param realm realm or organization name of the service provider.
     * @param hostEntityId hosted service provider Entity ID.
     * @param metaManager <code>SAML2MetaManager</code> instance for meta operation.
     * @param auditor a <code>SAML2EventLogger</code> auditor object to hook into
     *                tracking information for the saml request
     * @return <code>Object</code> which holds result of the session.
     * @throws SAML2Exception if the processing failed.
     */
public static Object processResponse(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String metaAlias, Object session, ResponseInfo respInfo, String realm, String hostEntityId, SAML2MetaManager metaManager, SAML2EventLogger auditor) throws SAML2Exception {
    String classMethod = "SPACSUtils.processResponse: ";
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "Response : " + respInfo.getResponse());
    }
    Map smap = null;
    try {
        // check Response/Assertion and get back a Map of relevant data
        smap = SAML2Utils.verifyResponse(request, response, respInfo.getResponse(), realm, hostEntityId, respInfo.getProfileBinding());
    } catch (SAML2Exception se) {
        // invoke SPAdapter for failure
        invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.INVALID_RESPONSE, se);
        throw se;
    }
    com.sun.identity.saml2.assertion.Subject assertionSubject = (com.sun.identity.saml2.assertion.Subject) smap.get(SAML2Constants.SUBJECT);
    NameID nameId = assertionSubject.getNameID();
    EncryptedID encId = assertionSubject.getEncryptedID();
    Assertion authnAssertion = (Assertion) smap.get(SAML2Constants.POST_ASSERTION);
    String sessionIndex = (String) smap.get(SAML2Constants.SESSION_INDEX);
    respInfo.setSessionIndex(sessionIndex);
    Integer authLevel = (Integer) smap.get(SAML2Constants.AUTH_LEVEL);
    Long maxSessionTime = (Long) smap.get(SAML2Constants.MAX_SESSION_TIME);
    String inRespToResp = (String) smap.get(SAML2Constants.IN_RESPONSE_TO);
    List assertions = (List) smap.get(SAML2Constants.ASSERTIONS);
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "Assertions : " + assertions);
    }
    SPSSOConfigElement spssoconfig = metaManager.getSPSSOConfig(realm, hostEntityId);
    // get mappers
    SPAccountMapper acctMapper = SAML2Utils.getSPAccountMapper(realm, hostEntityId);
    SPAttributeMapper attrMapper = SAML2Utils.getSPAttributeMapper(realm, hostEntityId);
    String assertionEncryptedAttr = SAML2Utils.getAttributeValueFromSPSSOConfig(spssoconfig, SAML2Constants.WANT_ASSERTION_ENCRYPTED);
    boolean needAttributeEncrypted = getNeedAttributeEncrypted(assertionEncryptedAttr, spssoconfig);
    boolean needNameIDEncrypted = getNeedNameIDEncrypted(assertionEncryptedAttr, spssoconfig);
    Set<PrivateKey> decryptionKeys = KeyUtil.getDecryptionKeys(spssoconfig);
    if (needNameIDEncrypted && encId == null) {
        SAML2Utils.debug.error(classMethod + "process: NameID was not encrypted.");
        SAML2Exception se = new SAML2Exception(SAML2Utils.bundle.getString("nameIDNotEncrypted"));
        // invoke SPAdapter for failure
        invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.INVALID_RESPONSE, se);
        throw se;
    }
    if (encId != null) {
        try {
            nameId = encId.decrypt(decryptionKeys);
        } catch (SAML2Exception se) {
            // invoke SPAdapter for failure
            invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.INVALID_RESPONSE, se);
            throw se;
        }
    }
    respInfo.setNameId(nameId);
    SPSSODescriptorElement spDesc = null;
    try {
        spDesc = metaManager.getSPSSODescriptor(realm, hostEntityId);
    } catch (SAML2MetaException ex) {
        SAML2Utils.debug.error(classMethod, ex);
    }
    if (spDesc == null) {
        SAML2Exception se = new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
        invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.SSO_FAILED_META_DATA_ERROR, se);
        throw se;
    }
    String nameIDFormat = nameId.getFormat();
    if (nameIDFormat != null) {
        List spNameIDFormatList = spDesc.getNameIDFormat();
        if ((spNameIDFormatList != null) && (!spNameIDFormatList.isEmpty()) && (!spNameIDFormatList.contains(nameIDFormat))) {
            Object[] args = { nameIDFormat };
            SAML2Exception se = new SAML2Exception(SAML2Utils.BUNDLE_NAME, "unsupportedNameIDFormatSP", args);
            invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.INVALID_RESPONSE, se);
            throw se;
        }
    }
    boolean isTransient = SAML2Constants.NAMEID_TRANSIENT_FORMAT.equals(nameIDFormat);
    boolean isPersistent = SAML2Constants.PERSISTENT.equals(nameIDFormat);
    boolean ignoreProfile = SAML2PluginsUtils.isIgnoredProfile(realm);
    String existUserName = null;
    SessionProvider sessionProvider = null;
    try {
        sessionProvider = SessionManager.getProvider();
    } catch (SessionException se) {
        // invoke SPAdapter for failure
        SAML2Exception se2 = new SAML2Exception(se);
        invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.SSO_FAILED_SESSION_ERROR, se2);
        throw se2;
    }
    if (session != null) {
        try {
            existUserName = sessionProvider.getPrincipalName(session);
        } catch (SessionException se) {
            // invoke SPAdapter for failure
            SAML2Exception se2 = new SAML2Exception(se);
            invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.SSO_FAILED_SESSION_ERROR, se2);
            throw se2;
        }
    }
    String remoteHostId = authnAssertion.getIssuer().getValue();
    String userName = null;
    boolean isNewAccountLink = false;
    boolean shouldPersistNameID = isPersistent || (!isTransient && !ignoreProfile && acctMapper.shouldPersistNameIDFormat(realm, hostEntityId, remoteHostId, nameIDFormat));
    try {
        if (shouldPersistNameID) {
            if (SAML2Utils.debug.messageEnabled()) {
                SAML2Utils.debug.message(classMethod + "querying data store for existing federation links: realm = " + realm + " hostEntityID = " + hostEntityId + " remoteEntityID = " + remoteHostId);
            }
            try {
                userName = SAML2Utils.getDataStoreProvider().getUserID(realm, SAML2Utils.getNameIDKeyMap(nameId, hostEntityId, remoteHostId, realm, SAML2Constants.SP_ROLE));
            } catch (DataStoreProviderException dse) {
                SAML2Utils.debug.error(classMethod + "DataStoreProviderException whilst retrieving NameID " + "information", dse);
                throw new SAML2Exception(dse.getMessage());
            }
        }
        if (userName == null) {
            userName = acctMapper.getIdentity(authnAssertion, hostEntityId, realm);
            isNewAccountLink = true;
        }
    } catch (SAML2Exception se) {
        // invoke SPAdapter for failure
        invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.SSO_FAILED_NO_USER_MAPPING, se);
        throw se;
    }
    if (userName == null && respInfo.isLocalLogin()) {
        // In case we just got authenticated locally, we should accept the freshly authenticated session's principal
        // as the username corresponding to the received assertion.
        userName = existUserName;
    }
    if (null != auditor) {
        auditor.setUserId(userName);
    }
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "process: userName =[" + userName + "]");
    }
    List attrs = null;
    for (Iterator it = assertions.iterator(); it.hasNext(); ) {
        Assertion assertion = (Assertion) it.next();
        List origAttrs = getSAMLAttributes(assertion, needAttributeEncrypted, decryptionKeys);
        if (origAttrs != null && !origAttrs.isEmpty()) {
            if (attrs == null) {
                attrs = new ArrayList();
            }
            attrs.addAll(origAttrs);
        }
    }
    Map attrMap = null;
    if (attrs != null) {
        try {
            attrMap = attrMapper.getAttributes(attrs, userName, hostEntityId, remoteHostId, realm);
        } catch (SAML2Exception se) {
            // invoke SPAdapter for failure
            invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.SSO_FAILED_ATTRIBUTE_MAPPING, se);
            throw se;
        }
    }
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "process: remoteHostId = " + remoteHostId);
        SAML2Utils.debug.message(classMethod + "process: attrMap = " + attrMap);
    }
    respInfo.setAttributeMap(attrMap);
    // return error code for local user login
    if (StringUtils.isEmpty(userName)) {
        // map the user to the existing session.
        if (session != null) {
            try {
                sessionProvider.invalidateSession(session, request, response);
            } catch (SessionException se) {
                SAML2Utils.debug.error("An error occurred while trying to invalidate session", se);
            }
        }
        throw new SAML2Exception(SAML2Utils.bundle.getString("noUserMapping"));
    }
    boolean writeFedInfo = isNewAccountLink && shouldPersistNameID;
    if (SAML2Utils.debug.messageEnabled()) {
        SAML2Utils.debug.message(classMethod + "userName : " + userName);
        SAML2Utils.debug.message(classMethod + "writeFedInfo : " + writeFedInfo);
    }
    AuthnRequest authnRequest = null;
    if (smap != null) {
        authnRequest = (AuthnRequest) smap.get(SAML2Constants.AUTHN_REQUEST);
    }
    if (inRespToResp != null && inRespToResp.length() != 0) {
        SPCache.requestHash.remove(inRespToResp);
    }
    Map sessionInfoMap = new HashMap();
    sessionInfoMap.put(SessionProvider.REALM, realm);
    sessionInfoMap.put(SessionProvider.PRINCIPAL_NAME, userName);
    // set client info. always use client IP address to prevent
    // reverse host lookup
    String clientAddr = ClientUtils.getClientIPAddress(request);
    sessionInfoMap.put(SessionProvider.HOST, clientAddr);
    sessionInfoMap.put(SessionProvider.HOST_NAME, clientAddr);
    sessionInfoMap.put(SessionProvider.AUTH_LEVEL, String.valueOf(authLevel));
    request.setAttribute(SessionProvider.ATTR_MAP, attrMap);
    try {
        session = sessionProvider.createSession(sessionInfoMap, request, response, null);
    } catch (SessionException se) {
        // invoke SPAdapter for failure
        int failureCode = SAML2ServiceProviderAdapter.SSO_FAILED_SESSION_GENERATION;
        int sessCode = se.getErrCode();
        if (sessCode == SessionException.AUTH_USER_INACTIVE) {
            failureCode = SAML2ServiceProviderAdapter.SSO_FAILED_AUTH_USER_INACTIVE;
        } else if (sessCode == SessionException.AUTH_USER_LOCKED) {
            failureCode = SAML2ServiceProviderAdapter.SSO_FAILED_AUTH_USER_LOCKED;
        } else if (sessCode == SessionException.AUTH_ACCOUNT_EXPIRED) {
            failureCode = SAML2ServiceProviderAdapter.SSO_FAILED_AUTH_ACCOUNT_EXPIRED;
        }
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message("SPACSUtils.processResponse : error code=" + sessCode, se);
        }
        SAML2Exception se2 = new SAML2Exception(se);
        invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, failureCode, se2);
        throw se2;
    }
    // set metaAlias
    String[] values = { metaAlias };
    try {
        setAttrMapInSession(sessionProvider, attrMap, session);
        setDiscoBootstrapCredsInSSOToken(sessionProvider, authnAssertion, session);
        sessionProvider.setProperty(session, SAML2Constants.SP_METAALIAS, values);
    } catch (SessionException se) {
        // invoke SPAdapter for failure
        SAML2Exception se2 = new SAML2Exception(se);
        invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.SSO_FAILED_SESSION_ERROR, se2);
        throw se2;
    }
    NameIDInfo info = null;
    String affiID = nameId.getSPNameQualifier();
    boolean isDualRole = SAML2Utils.isDualRole(hostEntityId, realm);
    AffiliationDescriptorType affiDesc = null;
    if (affiID != null && !affiID.isEmpty()) {
        affiDesc = metaManager.getAffiliationDescriptor(realm, affiID);
    }
    if (affiDesc != null) {
        if (!affiDesc.getAffiliateMember().contains(hostEntityId)) {
            throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
        }
        if (isDualRole) {
            info = new NameIDInfo(affiID, remoteHostId, nameId, SAML2Constants.DUAL_ROLE, true);
        } else {
            info = new NameIDInfo(affiID, remoteHostId, nameId, SAML2Constants.SP_ROLE, true);
        }
    } else {
        if (isDualRole) {
            info = new NameIDInfo(hostEntityId, remoteHostId, nameId, SAML2Constants.DUAL_ROLE, false);
        } else {
            info = new NameIDInfo(hostEntityId, remoteHostId, nameId, SAML2Constants.SP_ROLE, false);
        }
    }
    Map props = new HashMap();
    String nameIDValueString = info.getNameIDValue();
    props.put(LogUtil.NAME_ID, info.getNameIDValue());
    try {
        userName = sessionProvider.getPrincipalName(session);
    } catch (SessionException se) {
        // invoke SPAdapter for failure
        SAML2Exception se2 = new SAML2Exception(se);
        invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.SSO_FAILED_SESSION_ERROR, se2);
        throw se2;
    }
    String[] data1 = { userName, nameIDValueString };
    LogUtil.access(Level.INFO, LogUtil.SUCCESS_FED_SSO, data1, session, props);
    // write fed info into data store
    if (writeFedInfo) {
        try {
            AccountUtils.setAccountFederation(info, userName);
        } catch (SAML2Exception se) {
            // invoke SPAdapter for failure
            invokeSPAdapterForSSOFailure(hostEntityId, realm, request, response, smap, respInfo, SAML2ServiceProviderAdapter.FEDERATION_FAILED_WRITING_ACCOUNT_INFO, se);
            throw se;
        }
        String[] data = { userName, "" };
        if (LogUtil.isAccessLoggable(Level.FINE)) {
            data[1] = info.toValueString();
        }
        LogUtil.access(Level.INFO, LogUtil.FED_INFO_WRITTEN, data, session, props);
    }
    String requestID = respInfo.getResponse().getInResponseTo();
    // save info in memory for logout
    saveInfoInMemory(sessionProvider, session, sessionIndex, metaAlias, info, IDPProxyUtil.isIDPProxyEnabled(requestID), isTransient);
    // invoke SP Adapter
    SAML2ServiceProviderAdapter spAdapter = SAML2Utils.getSPAdapterClass(hostEntityId, realm);
    if (spAdapter != null) {
        boolean redirected = spAdapter.postSingleSignOnSuccess(hostEntityId, realm, request, response, out, session, authnRequest, respInfo.getResponse(), respInfo.getProfileBinding(), writeFedInfo);
        String[] value = null;
        if (redirected) {
            value = new String[] { "true" };
        } else {
            value = new String[] { "false" };
        }
        try {
            sessionProvider.setProperty(session, SAML2Constants.RESPONSE_REDIRECTED, value);
        } catch (SessionException ex) {
            SAML2Utils.debug.warning("SPSingleLogout.processResp", ex);
        } catch (UnsupportedOperationException ex) {
            SAML2Utils.debug.warning("SPSingleLogout.processResp", ex);
        }
    }
    String assertionID = authnAssertion.getID();
    if (respInfo.getProfileBinding().equals(SAML2Constants.HTTP_POST)) {
        SPCache.assertionByIDCache.put(assertionID, SAML2Constants.ONETIME);
        try {
            if (SAML2FailoverUtils.isSAML2FailoverEnabled()) {
                SAML2FailoverUtils.saveSAML2TokenWithoutSecondaryKey(assertionID, SAML2Constants.ONETIME, ((Long) smap.get(SAML2Constants.NOTONORAFTER)).longValue() / 1000);
            }
        } catch (SAML2TokenRepositoryException se) {
            SAML2Utils.debug.error(classMethod + "There was a problem saving the assertionID to the SAML2 Token Repository for assertionID:" + assertionID, se);
        }
    }
    respInfo.setAssertion(authnAssertion);
    return session;
}
Also used : PrivateKey(java.security.PrivateKey) HashMap(java.util.HashMap) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) ArrayList(java.util.ArrayList) SessionException(com.sun.identity.plugin.session.SessionException) EncryptedID(com.sun.identity.saml2.assertion.EncryptedID) SPAccountMapper(com.sun.identity.saml2.plugins.SPAccountMapper) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) SAML2ServiceProviderAdapter(com.sun.identity.saml2.plugins.SAML2ServiceProviderAdapter) SAML2MetaException(com.sun.identity.saml2.meta.SAML2MetaException) SessionProvider(com.sun.identity.plugin.session.SessionProvider) DataStoreProviderException(com.sun.identity.plugin.datastore.DataStoreProviderException) NameIDInfo(com.sun.identity.saml2.common.NameIDInfo) NameID(com.sun.identity.saml2.assertion.NameID) Assertion(com.sun.identity.saml2.assertion.Assertion) SPSSOConfigElement(com.sun.identity.saml2.jaxb.entityconfig.SPSSOConfigElement) AffiliationDescriptorType(com.sun.identity.saml2.jaxb.metadata.AffiliationDescriptorType) Subject(com.sun.identity.saml2.assertion.Subject) Subject(com.sun.identity.saml2.assertion.Subject) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) AuthnRequest(com.sun.identity.saml2.protocol.AuthnRequest) SPAttributeMapper(com.sun.identity.saml2.plugins.SPAttributeMapper) SAML2TokenRepositoryException(org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)275 ArrayList (java.util.ArrayList)92 List (java.util.List)86 SAML2MetaException (com.sun.identity.saml2.meta.SAML2MetaException)72 Element (org.w3c.dom.Element)64 SessionException (com.sun.identity.plugin.session.SessionException)56 IOException (java.io.IOException)51 SPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement)44 Map (java.util.Map)44 HashMap (java.util.HashMap)43 Iterator (java.util.Iterator)43 Issuer (com.sun.identity.saml2.assertion.Issuer)42 Date (java.util.Date)40 SOAPException (javax.xml.soap.SOAPException)39 SAML2TokenRepositoryException (org.forgerock.openam.federation.saml2.SAML2TokenRepositoryException)39 X509Certificate (java.security.cert.X509Certificate)36 NodeList (org.w3c.dom.NodeList)36 IDPSSODescriptorElement (com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)35 Node (org.w3c.dom.Node)34 Response (com.sun.identity.saml2.protocol.Response)30