Search in sources :

Example 11 with Response

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

the class IDPSSOUtil method signResponse.

/**
     * Signs SAMLv2 Response.
     *
     * @param realm       the realm name.
     * @param idpEntityID the identity provider entity identifier
     * @param response    the SAMLv2 <code>Response</code>
     * @throws <code>SAML2Exception</code> if there is an
     *                                     error signing the response.
     */
private static void signResponse(String realm, String idpEntityID, Response response) throws SAML2Exception {
    String classMethod = "IDPSSOUtil:signResponse";
    KeyProvider kp = KeyUtil.getKeyProviderInstance();
    if (kp == null) {
        SAML2Utils.debug.error(classMethod + "Unable to get a key provider instance.");
        throw new SAML2Exception(SAML2Utils.bundle.getString("nullKeyProvider"));
    }
    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.");
        throw new SAML2Exception(SAML2Utils.bundle.getString("missingSigningCertAlias"));
    }
    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);
    }
    response.sign(key, kp.getX509Certificate(idpSignCertAlias));
}
Also used : KeyProvider(com.sun.identity.saml.xmlsig.KeyProvider) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) PrivateKey(java.security.PrivateKey)

Example 12 with Response

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

the class IDPSSOUtil method sendResponseECP.

/**
     * This method sends SAML Response back to ECP.
     *
     * @param request The servlet request.
     * @param response The servlet response.
     * @param out The print writer for writing out presentation.
     * @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 res         the <code>SAML Response</code> object
     * @throws SAML2Exception if the operation is not successful
     */
public static void sendResponseECP(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String idpEntityID, String realm, String acsURL, Response res) throws SAML2Exception {
    ECPFactory ecpFactory = ECPFactory.getInstance();
    ECPResponse ecpResponse = ecpFactory.createECPResponse();
    ecpResponse.setMustUnderstand(Boolean.TRUE);
    ecpResponse.setActor(SAML2Constants.SOAP_ACTOR_NEXT);
    ecpResponse.setAssertionConsumerServiceURL(acsURL);
    String header = ecpResponse.toXMLString(true, true);
    String body = res.toXMLString(true, true);
    try {
        SOAPMessage reply = SOAPCommunicator.getInstance().createSOAPMessage(header, body, false);
        String[] logdata = { idpEntityID, realm, acsURL, "" };
        if (LogUtil.isAccessLoggable(Level.FINE)) {
            logdata[3] = SOAPCommunicator.getInstance().soapMessageToString(reply);
        }
        LogUtil.access(Level.INFO, LogUtil.SEND_ECP_RESPONSE, logdata, null);
        // are generated as part of the save.
        if (reply.saveRequired()) {
            reply.saveChanges();
        }
        response.setStatus(HttpServletResponse.SC_OK);
        SAML2Utils.putHeaders(reply.getMimeHeaders(), response);
        // Write out the message on the response stream
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        reply.writeTo(stream);
        out.println(stream.toString());
        out.flush();
    } catch (Exception ex) {
        SAML2Utils.debug.error("IDPSSOUtil.sendResponseECP", ex);
        String[] data = { idpEntityID, realm, acsURL };
        LogUtil.error(Level.INFO, LogUtil.SEND_ECP_RESPONSE_FAILED, data, null);
        SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "failedToSendECPResponse", ex.getMessage());
        return;
    }
}
Also used : ECPResponse(com.sun.identity.saml2.ecp.ECPResponse) ByteArrayOutputStream(java.io.ByteArrayOutputStream) SOAPMessage(javax.xml.soap.SOAPMessage) ECPFactory(com.sun.identity.saml2.ecp.ECPFactory) SAML2InvalidNameIDPolicyException(com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException) SessionException(com.sun.identity.plugin.session.SessionException) COTException(com.sun.identity.cot.COTException) 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)

Example 13 with Response

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

the class IDPSSOUtil method getResponse.

/**
     * Returns a <code>SAML Response</code> object.
     *
     * @param request The HTTP request.
     * @param session The user's session object.
     * @param authnReq The <code>AuthnRequest</code> object.
     * @param recipientEntityID The entity ID of the response recipient.
     * @param idpEntityID The entity ID of the identity provider.
     * @param realm The realm name.
     * @param nameIDFormat The <code>NameIDFormat</code>.
     * @param acsURL The <code>ACS</code> service <code>url</code>.
     * @param affiliationID AffiliationID for IDP initiated SSO.
     * @param matchingAuthnContext the <code>AuthnContext</code> used to find authentication type and scheme.
     * @return the <code>SAML Response</code> object.
     * @throws SAML2Exception if the operation is not successful.
     */
public static Response getResponse(HttpServletRequest request, Object session, AuthnRequest authnReq, String recipientEntityID, String idpEntityID, String idpMetaAlias, String realm, String nameIDFormat, String acsURL, String affiliationID, AuthnContext matchingAuthnContext) throws SAML2Exception {
    String classMethod = "IDPSSOUtil.getResponse: ";
    Response res = ProtocolFactory.getInstance().createResponse();
    Status status = ProtocolFactory.getInstance().createStatus();
    if (status == null) {
        return null;
    }
    StatusCode statusCode = ProtocolFactory.getInstance().createStatusCode();
    if (statusCode == null) {
        return null;
    }
    try {
        List assertionList = new ArrayList();
        Assertion assertion = getAssertion(request, session, authnReq, recipientEntityID, idpEntityID, idpMetaAlias, realm, nameIDFormat, acsURL, affiliationID, matchingAuthnContext);
        if (assertion == null) {
            SAML2Utils.debug.error(classMethod + "Unable to get Assertion.");
            return null;
        }
        assertionList.add(assertion);
        res.setAssertion(assertionList);
        statusCode.setValue(SAML2Constants.SUCCESS);
    } catch (SAML2InvalidNameIDPolicyException se) {
        statusCode.setValue(SAML2Constants.REQUESTER);
        StatusCode subStatusCode = ProtocolFactory.getInstance().createStatusCode();
        subStatusCode.setValue(SAML2Constants.INVALID_NAME_ID_POLICY);
        statusCode.setStatusCode(subStatusCode);
        status.setStatusMessage(se.getMessage());
    }
    status.setStatusCode(statusCode);
    res.setStatus(status);
    if (authnReq != null) {
        // sp initiated case, need to set InResponseTo attribute
        res.setInResponseTo(authnReq.getID());
    }
    res.setVersion(SAML2Constants.VERSION_2_0);
    res.setIssueInstant(new Date());
    res.setID(SAML2Utils.generateID());
    // set the idp entity id as the response issuer
    Issuer issuer = AssertionFactory.getInstance().createIssuer();
    issuer.setValue(idpEntityID);
    res.setIssuer(issuer);
    res.setDestination(XMLUtils.escapeSpecialCharacters(acsURL));
    return res;
}
Also used : ECPResponse(com.sun.identity.saml2.ecp.ECPResponse) Response(com.sun.identity.saml2.protocol.Response) HttpServletResponse(javax.servlet.http.HttpServletResponse) Status(com.sun.identity.saml2.protocol.Status) Issuer(com.sun.identity.saml2.assertion.Issuer) ArrayList(java.util.ArrayList) EncryptedAssertion(com.sun.identity.saml2.assertion.EncryptedAssertion) Assertion(com.sun.identity.saml2.assertion.Assertion) List(java.util.List) ArrayList(java.util.ArrayList) SAML2InvalidNameIDPolicyException(com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException) StatusCode(com.sun.identity.saml2.protocol.StatusCode) Date(java.util.Date)

Example 14 with Response

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

the class IDPSSOUtil method getSubject.

/**
     * Returns a <code>SAML Subject</code> object
     *
     * @param session           the user's session
     * @param authnReq          the <code>AuthnRequest</code> object
     * @param acsURL            the <code>ACS</code> service <code>url</code>
     * @param nameIDFormat      the <code>NameIDFormat</code>
     * @param realm             The realm name
     * @param idpEntityID       the entity id of the identity provider
     * @param recipientEntityID the entity id of the response recipient
     * @param effectiveTime     the effective time of the assertion
     * @param affiliationID     affiliationID for IDP initiated SSO
     * @return the <code>SAML Subject</code> object
     * @throws SAML2Exception if the operation is not successful
     */
private static Subject getSubject(Object session, AuthnRequest authnReq, String acsURL, String nameIDFormat, String realm, String idpEntityID, String recipientEntityID, int effectiveTime, String affiliationID) throws SAML2Exception {
    String classMethod = "IDPSSOUtil.getSubject: ";
    Subject subject = AssertionFactory.getInstance().createSubject();
    boolean ignoreProfile = false;
    String userName = null;
    try {
        userName = sessionProvider.getPrincipalName(session);
        ignoreProfile = SAML2Utils.isIgnoreProfileSet(session);
    } catch (SessionException se) {
        SAML2Utils.debug.error(classMethod + "There was a problem with the session.", se);
        throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
    }
    // allow create is the default
    boolean allowCreate = true;
    String remoteEntityID = null;
    String spNameQualifier = null;
    boolean isAffiliation = false;
    if (authnReq != null) {
        remoteEntityID = authnReq.getIssuer().getValue();
        NameIDPolicy nameIDPolicy = authnReq.getNameIDPolicy();
        if (nameIDPolicy != null) {
            // this will take care of affiliation
            allowCreate = nameIDPolicy.isAllowCreate();
            spNameQualifier = nameIDPolicy.getSPNameQualifier();
            if (spNameQualifier != null && !spNameQualifier.isEmpty()) {
                AffiliationDescriptorType affiDesc = metaManager.getAffiliationDescriptor(realm, spNameQualifier);
                if (affiDesc != null) {
                    if (affiDesc.getAffiliateMember().contains(remoteEntityID)) {
                        isAffiliation = true;
                        remoteEntityID = spNameQualifier;
                    } else {
                        throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
                    }
                }
            } else {
                spNameQualifier = recipientEntityID;
            }
        }
    } else {
        // IDP initialted SSO
        if (affiliationID != null) {
            AffiliationDescriptorType affiDesc = metaManager.getAffiliationDescriptor(realm, affiliationID);
            if (affiDesc == null) {
                throw new SAML2Exception(SAML2Utils.bundle.getString("affiliationNotFound"));
            }
            if (affiDesc.getAffiliateMember().contains(recipientEntityID)) {
                isAffiliation = true;
                remoteEntityID = affiliationID;
                spNameQualifier = affiliationID;
            } else {
                throw new SAML2Exception(SAML2Utils.bundle.getString("spNotAffiliationMember"));
            }
        } else {
            remoteEntityID = recipientEntityID;
            spNameQualifier = recipientEntityID;
        }
    }
    SPSSODescriptorElement spsso = getSPSSODescriptor(realm, recipientEntityID, classMethod);
    if (spsso == null) {
        String[] data = { recipientEntityID };
        LogUtil.error(Level.INFO, LogUtil.SP_METADATA_ERROR, data, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
    IDPSSODescriptorElement idpsso = metaManager.getIDPSSODescriptor(realm, idpEntityID);
    if (idpsso == null) {
        String[] data = { idpEntityID };
        LogUtil.error(Level.INFO, LogUtil.IDP_METADATA_ERROR, data, null);
        throw new SAML2Exception(SAML2Utils.bundle.getString("metaDataError"));
    }
    nameIDFormat = SAML2Utils.verifyNameIDFormat(nameIDFormat, spsso, idpsso);
    boolean isTransient = SAML2Constants.NAMEID_TRANSIENT_FORMAT.equals(nameIDFormat);
    boolean isPersistent = SAML2Constants.PERSISTENT.equals(nameIDFormat);
    NameIDInfo nameIDInfo;
    NameID nameID = null;
    IDPAccountMapper idpAccountMapper = SAML2Utils.getIDPAccountMapper(realm, idpEntityID);
    //Use-cases for NameID persistence:
    //* persistent NameID -> The NameID MUST be stored
    //* transient NameID -> The NameID MUST NOT be stored
    //* ignored user profile mode -> The NameID CANNOT be stored
    //* for any other cases -> The NameID MAY be stored based on customizable logic
    boolean shouldPersistNameID = isPersistent || (!isTransient && !ignoreProfile && idpAccountMapper.shouldPersistNameIDFormat(realm, idpEntityID, remoteEntityID, nameIDFormat));
    if (!isTransient) {
        String userID;
        try {
            userID = sessionProvider.getPrincipalName(session);
        } catch (SessionException se) {
            SAML2Utils.debug.error(classMethod + "Unable to get principal name from the session.", se);
            throw new SAML2Exception(SAML2Utils.bundle.getString("invalidSSOToken"));
        }
        if (isPersistent || shouldPersistNameID) {
            nameIDInfo = AccountUtils.getAccountFederation(userID, idpEntityID, remoteEntityID);
            if (nameIDInfo != null) {
                nameID = nameIDInfo.getNameID();
                if (!nameIDFormat.equals(nameID.getFormat())) {
                    AccountUtils.removeAccountFederation(nameIDInfo, userID);
                    DoManageNameID.removeIDPFedSession(remoteEntityID, nameID.getValue());
                    nameID = null;
                }
            }
        }
    }
    if (nameID == null) {
        if (!allowCreate && isPersistent) {
            throw new SAML2InvalidNameIDPolicyException(SAML2Utils.bundle.getString("cannotCreateNameID"));
        }
        nameID = idpAccountMapper.getNameID(session, idpEntityID, spNameQualifier, realm, nameIDFormat);
        SAML2Utils.debug.message(classMethod + " shouldPersistNameID = " + shouldPersistNameID);
        if (shouldPersistNameID && allowCreate) {
            // write federation info into the persistent datastore
            if (SAML2Utils.isDualRole(idpEntityID, realm)) {
                nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.DUAL_ROLE, false);
            } else {
                nameIDInfo = new NameIDInfo(idpEntityID, remoteEntityID, nameID, SAML2Constants.IDP_ROLE, isAffiliation);
            }
            AccountUtils.setAccountFederation(nameIDInfo, userName);
        }
    }
    subject.setNameID(nameID);
    if (isTransient) {
        IDPCache.userIDByTransientNameIDValue.put(nameID.getValue(), userName);
    }
    String inResponseTo = null;
    if (authnReq != null) {
        inResponseTo = authnReq.getID();
    }
    SubjectConfirmation sc = getSubjectConfirmation(inResponseTo, acsURL, effectiveTime);
    if (sc == null) {
        SAML2Utils.debug.error(classMethod + "Unable to get subject confirmation");
        throw new SAML2Exception(SAML2Utils.bundle.getString("noSubjectConfirmation"));
    }
    List list = new ArrayList();
    list.add(sc);
    subject.setSubjectConfirmation(list);
    return subject;
}
Also used : NameIDInfo(com.sun.identity.saml2.common.NameIDInfo) IDPAccountMapper(com.sun.identity.saml2.plugins.IDPAccountMapper) NameIDPolicy(com.sun.identity.saml2.protocol.NameIDPolicy) NameID(com.sun.identity.saml2.assertion.NameID) SPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement) ArrayList(java.util.ArrayList) SessionException(com.sun.identity.plugin.session.SessionException) AffiliationDescriptorType(com.sun.identity.saml2.jaxb.metadata.AffiliationDescriptorType) Subject(com.sun.identity.saml2.assertion.Subject) SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SubjectConfirmation(com.sun.identity.saml2.assertion.SubjectConfirmation) List(java.util.List) ArrayList(java.util.ArrayList) SAML2InvalidNameIDPolicyException(com.sun.identity.saml2.common.SAML2InvalidNameIDPolicyException) IDPSSODescriptorElement(com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement)

Example 15 with Response

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

the class IDPSSOUtil method sendResponse.

/**
     * Sends a response to service provider
     *
     * @param response     the <code>HttpServletResponse</code> object
     * @param acsBinding   the assertion consumer service binding
     * @param spEntityID   the entity id of the service provider
     * @param idpEntityID  the entity id of the identity provider
     * @param idpMetaAlias the meta alias of the identity provider
     * @param realm        the realm name
     * @param relayState   the relay state
     * @param acsURL       the assertion consumer service <code>url</code>
     * @param res          the <code>SAML Response</code> object
     * @throws SAML2Exception if the operation is not successful
     */
public static void sendResponse(HttpServletRequest request, HttpServletResponse response, PrintWriter out, String acsBinding, String spEntityID, String idpEntityID, String idpMetaAlias, String realm, String relayState, String acsURL, Response res, Object session) throws SAML2Exception {
    String classMethod = "IDPSSOUtil.sendResponse: ";
    String nameIDString = SAML2Utils.getNameIDStringFromResponse(res);
    Map props = new HashMap();
    props.put(LogUtil.NAME_ID, nameIDString);
    // send the response back through HTTP POST or Artifact
    if (acsBinding.equals(SAML2Constants.HTTP_POST)) {
        // 4.1.4.5 POST-Specific Processing Rules (sstc-saml-profiles-errata-2.0-wd-06-diff.pdf)
        //If response is not signed and POST binding is used, the assertion(s) MUST be signed.
        // encryption is optional based on SP config settings.
        boolean signAssertion = true;
        // check if response needs to be signed.
        boolean signResponse = SAML2Utils.wantPOSTResponseSigned(realm, spEntityID, SAML2Constants.SP_ROLE);
        // so will base on wantAssertionsSigned flag
        if (signResponse) {
            signAssertion = wantAssertionsSigned(spEntityID, realm);
        }
        signAndEncryptResponseComponents(realm, spEntityID, idpEntityID, res, signAssertion);
        if (signResponse) {
            signResponse(realm, idpEntityID, res);
        }
        String resMsg = res.toXMLString(true, true);
        if (SAML2Utils.debug.messageEnabled()) {
            SAML2Utils.debug.message(classMethod + "SAML Response content :\n" + resMsg);
        }
        String encodedResMsg = SAML2Utils.encodeForPOST(resMsg);
        String[] logdata1 = { spEntityID, idpMetaAlias, resMsg };
        LogUtil.access(Level.INFO, LogUtil.POST_RESPONSE, logdata1, session, props);
        try {
            SAML2Utils.postToTarget(request, response, "SAMLResponse", encodedResMsg, "RelayState", relayState, acsURL);
        } catch (SAML2Exception saml2E) {
            String[] data = { acsURL };
            LogUtil.error(Level.INFO, LogUtil.POST_TO_TARGET_FAILED, data, session, props);
            throw saml2E;
        }
    } else if (acsBinding.equals(SAML2Constants.HTTP_ARTIFACT)) {
        IDPSSOUtil.sendResponseArtifact(request, response, idpEntityID, spEntityID, realm, acsURL, relayState, res, session, props);
    } else if (acsBinding.equals(SAML2Constants.PAOS)) {
        // signing assertion is a must for ECP profile.
        // encryption is optional based on SP config settings.
        signAndEncryptResponseComponents(realm, spEntityID, idpEntityID, res, true);
        IDPSSOUtil.sendResponseECP(request, response, out, idpEntityID, realm, acsURL, res);
    } else {
        SAML2Utils.debug.error(classMethod + "unsupported return binding.");
        throw new SAML2Exception(SAML2Utils.bundle.getString("UnSupportedReturnBinding"));
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) HashMap(java.util.HashMap) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

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