Search in sources :

Example 6 with SubjectConfirmationData

use of com.sun.identity.saml2.assertion.SubjectConfirmationData in project OpenAM by OpenRock.

the class SAML2Utils method isBearerSubjectConfirmation.

private static Map isBearerSubjectConfirmation(final List subjectConfirms, final String inRespToResponse, final SPSSODescriptorElement spDesc, final SPSSOConfigElement spConfig, final String assertionID) throws SAML2Exception {
    String method = "SAML2Utils.isBearerSubjectConfirmation:";
    Map retMap = new HashMap();
    boolean hasBearer = false;
    for (Iterator it = subjectConfirms.iterator(); it.hasNext(); ) {
        SubjectConfirmation subjectConfirm = (SubjectConfirmation) it.next();
        if (subjectConfirm == null || subjectConfirm.getMethod() == null || !subjectConfirm.getMethod().equals(SAML2Constants.SUBJECT_CONFIRMATION_METHOD_BEARER)) {
            continue;
        }
        // since this is bearer SC, all below must be true
        SubjectConfirmationData subjectConfData = subjectConfirm.getSubjectConfirmationData();
        if (subjectConfData == null) {
            if (debug.messageEnabled()) {
                debug.message(method + "missing SubjectConfirmationData.");
            }
            String[] data = { assertionID };
            LogUtil.error(Level.INFO, LogUtil.MISSING_SUBJECT_COMFIRMATION_DATA, data, null);
            throw new SAML2Exception(bundle.getString("missingSubjectConfirmationData"));
        }
        String recipient = subjectConfData.getRecipient();
        if (recipient == null || recipient.length() == 0) {
            if (debug.messageEnabled()) {
                debug.message(method + "missing Recipient in Assertion.");
            }
            String[] data = { assertionID };
            LogUtil.error(Level.INFO, LogUtil.MISSING_RECIPIENT, data, null);
            throw new SAML2Exception(bundle.getString("missingRecipient"));
        }
        boolean foundMatch = false;
        Iterator acsIter = spDesc.getAssertionConsumerService().iterator();
        while (acsIter.hasNext()) {
            AssertionConsumerServiceElement acs = (AssertionConsumerServiceElement) acsIter.next();
            if (recipient.equals(acs.getLocation())) {
                foundMatch = true;
                break;
            }
        }
        if (!foundMatch) {
            if (debug.messageEnabled()) {
                debug.message(method + "this sp is not the intended " + "recipient.");
            }
            String[] data = { assertionID, recipient };
            LogUtil.error(Level.INFO, LogUtil.WRONG_RECIPIENT, data, null);
            throw new SAML2Exception(bundle.getString("wrongRecipient"));
        }
        // in seconds
        int timeskew = SAML2Constants.ASSERTION_TIME_SKEW_DEFAULT;
        String timeskewStr = getAttributeValueFromSPSSOConfig(spConfig, SAML2Constants.ASSERTION_TIME_SKEW);
        if (timeskewStr != null && timeskewStr.trim().length() > 0) {
            timeskew = Integer.parseInt(timeskewStr);
            if (timeskew < 0) {
                timeskew = SAML2Constants.ASSERTION_TIME_SKEW_DEFAULT;
            }
        }
        if (debug.messageEnabled()) {
            debug.message(method + "timeskew = " + timeskew);
        }
        Date notOnOrAfter = subjectConfData.getNotOnOrAfter();
        if (notOnOrAfter == null || ((notOnOrAfter.getTime() + timeskew * 1000) < System.currentTimeMillis())) {
            if (debug.messageEnabled()) {
                debug.message(method + "Time in SubjectConfirmationData of " + "Assertion:" + assertionID + " is invalid.");
            }
            String[] data = { assertionID };
            LogUtil.error(Level.INFO, LogUtil.INVALID_TIME_SUBJECT_CONFIRMATION_DATA, data, null);
            throw new SAML2Exception(bundle.getString("invalidTimeOnSubjectConfirmationData"));
        }
        retMap.put(SAML2Constants.NOTONORAFTER, notOnOrAfter);
        Date notBefore = subjectConfData.getNotBefore();
        if (notBefore != null) {
            if ((notBefore.getTime() + timeskew * 1000) > System.currentTimeMillis()) {
                if (debug.messageEnabled()) {
                    debug.message(method + "SubjectConfirmationData included " + "NotBefore.");
                }
                String[] data = { assertionID };
                LogUtil.error(Level.INFO, LogUtil.CONTAINED_NOT_BEFORE, data, null);
                throw new SAML2Exception(bundle.getString("containedNotBefore"));
            }
        }
        retMap.put(SAML2Constants.NOTBEFORE, notBefore);
        String inRespTo = subjectConfData.getInResponseTo();
        if (inRespTo != null && inRespTo.length() != 0) {
            if (!inRespTo.equals(inRespToResponse)) {
                if (debug.messageEnabled()) {
                    debug.message(method + "InResponseTo in Assertion is " + "different from the one in Response.");
                }
                String[] data = { assertionID };
                LogUtil.error(Level.INFO, LogUtil.WRONG_INRESPONSETO_ASSERTION, data, null);
                throw new SAML2Exception(bundle.getString("wrongInResponseToInAssertion"));
            }
        } else {
            if (inRespToResponse != null && inRespToResponse.length() != 0) {
                if (debug.messageEnabled()) {
                    debug.message(method + "Assertion doesn't contain " + "InResponseTo, but Response does.");
                }
                String[] data = { assertionID };
                LogUtil.error(Level.INFO, LogUtil.WRONG_INRESPONSETO_ASSERTION, data, null);
                throw new SAML2Exception(bundle.getString("wrongInResponseToInAssertion"));
            }
        }
        hasBearer = true;
        break;
    }
    retMap.put(SAML2Constants.IS_BEARER, Boolean.valueOf(hasBearer));
    return retMap;
}
Also used : SubjectConfirmation(com.sun.identity.saml2.assertion.SubjectConfirmation) HashMap(java.util.HashMap) Iterator(java.util.Iterator) AssertionConsumerServiceElement(com.sun.identity.saml2.jaxb.metadata.AssertionConsumerServiceElement) SubjectConfirmationData(com.sun.identity.saml2.assertion.SubjectConfirmationData) Map(java.util.Map) HashMap(java.util.HashMap) Date(java.util.Date)

Example 7 with SubjectConfirmationData

use of com.sun.identity.saml2.assertion.SubjectConfirmationData in project OpenAM by OpenRock.

the class Saml2GrantTypeHandler method validAssertion.

private boolean validAssertion(Assertion assertion, String deploymentURL) throws SAML2Exception {
    //must contain issuer
    final Issuer issuer = assertion.getIssuer();
    if (issuer == null) {
        logger.error("Issuer does not exist");
        return false;
    }
    /**
         * The Assertion MUST contain <Conditions> element with an
         * <AudienceRestriction> element with an <Audience> element
         * containing a URI reference that identifies the authorization
         * server, or the service provider SAML entity of its controlling
         * domain, as an intended audience.  The token endpoint URL of the
         * authorization server MAY be used as an acceptable value for an
         *       <Audience> element.  The authorization server MUST verify that it
         * is an intended audience for the Assertion.
         *
         */
    final Conditions conditions = assertion.getConditions();
    if (conditions == null) {
        logger.error("Saml2BearerServerResource.validAssertion(): Conditions does not exist");
        return false;
    }
    final List<AudienceRestriction> audienceRestriction = conditions.getAudienceRestrictions();
    if (audienceRestriction == null || audienceRestriction.isEmpty()) {
        logger.error("Saml2BearerServerResource.validAssertion(): Audience Restriction does not exist");
        return false;
    }
    boolean found = false;
    logger.trace("Saml2BearerServerResource.validAssertion(): URL of authorization server: " + deploymentURL);
    for (final AudienceRestriction restriction : audienceRestriction) {
        final List<String> audiences = restriction.getAudience();
        if (audiences == null || audiences.isEmpty()) {
            continue;
        }
        for (final String audience : audiences) {
            String deployURL = deploymentURL;
            String aud = audience;
            //check for the url with and without trailing /
            if (deployURL.endsWith("/")) {
                deployURL = deploymentURL.substring(0, deployURL.length() - 1);
            }
            if (aud.endsWith("/")) {
                aud = aud.substring(0, aud.length() - 1);
            }
            if (aud.equalsIgnoreCase(deployURL)) {
                found = true;
            }
        }
    }
    if (found == false) {
        logger.error("Didn't find the oauth2 provider in audience restrictions");
        return false;
    }
    /**
         * The Assertion MUST contain a <Subject> element.  The subject MAY
         * identify the resource owner for whom the access token is being
         * requested.  For client authentication, the Subject MUST be the
         * "client_id" of the OAuth client.  When using an Assertion as an
         * authorization grant, the Subject SHOULD identify an authorized
         * accessor for whom the access token is being requested (typically
         * the resource owner, or an authorized delegate).  Additional
         * information identifying the subject/principal of the transaction
         * MAY be included in an <AttributeStatement>.
         */
    final Subject subject = assertion.getSubject();
    if (subject == null) {
        logger.error("Subject does not exist");
        return false;
    }
    final String resourceOwner = subject.getNameID().getValue();
    /**
         * The Assertion MUST have an expiry that limits the time window
         * during which it can be used.  The expiry can be expressed either
         * as the NotOnOrAfter attribute of the <Conditions> element or as
         * the NotOnOrAfter attribute of a suitable <SubjectConfirmationData>
         * element.
         */
    /**
         * The <Subject> element MUST contain at least one
         * <SubjectConfirmation> element that allows the authorization server
         * to confirm it as a Bearer Assertion.  Such a <SubjectConfirmation>
         * element MUST have a Method attribute with a value of
         * "urn:oasis:names:tc:SAML:2.0:cm:bearer".  The
         * <SubjectConfirmation> element MUST contain a
         * <SubjectConfirmationData> element, unless the Assertion has a
         * suitable NotOnOrAfter attribute on the <Conditions> element, in
         * which case the <SubjectConfirmationData> element MAY be omitted.
         * When present, the <SubjectConfirmationData> element MUST have a
         * Recipient attribute with a value indicating the token endpoint URL
         * of the authorization server (or an acceptable alias).  The
         * authorization server MUST verify that the value of the Recipient
         * attribute matches the token endpoint URL (or an acceptable alias)
         * to which the Assertion was delivered.  The
         * <SubjectConfirmationData> element MUST have a NotOnOrAfter
         * attribute that limits the window during which the Assertion can be
         * confirmed.  The <SubjectConfirmationData> element MAY also contain
         * an Address attribute limiting the client address from which the
         * Assertion can be delivered.  Verification of the Address is at the
         * discretion of the authorization server.
         */
    final List<SubjectConfirmation> subjectConfirmations = subject.getSubjectConfirmation();
    found = false;
    if (subjectConfirmations == null || subjectConfirmations.isEmpty()) {
        logger.error("Subject Confirmations does not exist");
        return false;
    }
    //if conditions is expired assertion is expired
    if (!assertion.isTimeValid()) {
        logger.error("Assertion expired");
        return false;
    } else {
        found = true;
    }
    for (final SubjectConfirmation subjectConfirmation : subjectConfirmations) {
        if (subjectConfirmation.getMethod() == null) {
            continue;
        }
        if (subjectConfirmation.getMethod().equalsIgnoreCase(OAuth2Constants.SAML20.SUBJECT_CONFIRMATION_METHOD)) {
            final SubjectConfirmationData subjectConfirmationData = subjectConfirmation.getSubjectConfirmationData();
            if (subjectConfirmationData == null) {
                continue;
            } else if (subjectConfirmationData.getNotOnOrAfter().before(new Date()) && subjectConfirmationData.getRecipient().equalsIgnoreCase(deploymentURL)) {
                found = true;
            }
        //TODO check Client Address
        }
    }
    if (!found) {
        logger.error("Assertion expired or subject expired");
        return false;
    }
    if (!assertion.isSigned()) {
        logger.error("Assertion must be signed");
        return false;
    }
    if (!SAMLUtils.checkSignatureValid(assertion.toXMLString(), "ID", issuer.getValue())) {
        logger.error("Assertion signature verification failed");
        return false;
    }
    return true;
}
Also used : AudienceRestriction(com.sun.identity.saml2.assertion.AudienceRestriction) SubjectConfirmation(com.sun.identity.saml2.assertion.SubjectConfirmation) Issuer(com.sun.identity.saml2.assertion.Issuer) SubjectConfirmationData(com.sun.identity.saml2.assertion.SubjectConfirmationData) Conditions(com.sun.identity.saml2.assertion.Conditions) Subject(com.sun.identity.saml2.assertion.Subject) Date(java.util.Date)

Example 8 with SubjectConfirmationData

use of com.sun.identity.saml2.assertion.SubjectConfirmationData in project OpenAM by OpenRock.

the class DefaultSubjectProvider method get.

public Subject get(String subjectId, String spAcsUrl, SAML2Config saml2Config, SAML2SubjectConfirmation subjectConfirmation, Date assertionIssueInstant, ProofTokenState proofTokenState) throws TokenCreationException {
    try {
        Subject subject = AssertionFactory.getInstance().createSubject();
        setNameIdentifier(subject, subjectId, saml2Config.getNameIdFormat());
        SubjectConfirmation subConfirmation = AssertionFactory.getInstance().createSubjectConfirmation();
        switch(subjectConfirmation) {
            case BEARER:
                subConfirmation.setMethod(SAML2Constants.SUBJECT_CONFIRMATION_METHOD_BEARER);
                /*
                    see section 4.1.4.2 of http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf -
                    Recipient attribute of SubjectConfirmation element must be set to the Service Provider
                    ACS url.
                     */
                SubjectConfirmationData bearerConfirmationData = AssertionFactory.getInstance().createSubjectConfirmationData();
                bearerConfirmationData.setRecipient(spAcsUrl);
                /*
                    see section 4.1.4.2 of http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf - NotBefore cannot
                    be set, but NotOnOrAfter must be set.
                     */
                bearerConfirmationData.setNotOnOrAfter(new Date(assertionIssueInstant.getTime() + (saml2Config.getTokenLifetimeInSeconds() * 1000)));
                subConfirmation.setSubjectConfirmationData(bearerConfirmationData);
                break;
            case SENDER_VOUCHES:
                subConfirmation.setMethod(SAML2Constants.SUBJECT_CONFIRMATION_METHOD_SENDER_VOUCHES);
                break;
            case HOLDER_OF_KEY:
                subConfirmation.setMethod(SAML2Constants.SUBJECT_CONFIRMATION_METHOD_HOLDER_OF_KEY);
                subConfirmation.setSubjectConfirmationData(getHoKSubjectConfirmationData(proofTokenState.getX509Certificate()));
                break;
            default:
                throw new TokenCreationException(ResourceException.INTERNAL_ERROR, "Unexpected SubjectConfirmation value in DefaultSubjectProvider: " + subjectConfirmation);
        }
        List<SubjectConfirmation> subjectConfirmationList = new ArrayList<>();
        subjectConfirmationList.add(subConfirmation);
        subject.setSubjectConfirmation(subjectConfirmationList);
        return subject;
    } catch (SAML2Exception e) {
        throw new TokenCreationException(ResourceException.INTERNAL_ERROR, "Exception caught setting subject confirmation state in DefaultSubjectProvider: " + e, e);
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) SAML2SubjectConfirmation(org.forgerock.openam.sts.token.SAML2SubjectConfirmation) SubjectConfirmation(com.sun.identity.saml2.assertion.SubjectConfirmation) ArrayList(java.util.ArrayList) SubjectConfirmationData(com.sun.identity.saml2.assertion.SubjectConfirmationData) TokenCreationException(org.forgerock.openam.sts.TokenCreationException) Subject(com.sun.identity.saml2.assertion.Subject) Date(java.util.Date)

Example 9 with SubjectConfirmationData

use of com.sun.identity.saml2.assertion.SubjectConfirmationData in project OpenAM by OpenRock.

the class DefaultSubjectProvider method getHoKSubjectConfirmationData.

private SubjectConfirmationData getHoKSubjectConfirmationData(X509Certificate certificate) throws TokenCreationException {
    Element keyInfoElement;
    try {
        keyInfoElement = keyInfoFactory.generatePublicKeyInfo(certificate);
    } catch (ParserConfigurationException e) {
        throw new TokenCreationException(ResourceException.INTERNAL_ERROR, "Exception caught generating KeyInfo for HoK SubjectConfirmation DefaultSubjectProvider: " + e, e);
    } catch (XMLSecurityException e) {
        throw new TokenCreationException(ResourceException.INTERNAL_ERROR, "Exception caught generating KeyInfo for HoK SubjectConfirmation DefaultSubjectProvider: " + e, e);
    }
    try {
        final List<Element> elementList = new ArrayList<Element>();
        elementList.add(keyInfoElement);
        final SubjectConfirmationData subjectConfirmationData = AssertionFactory.getInstance().createSubjectConfirmationData();
        subjectConfirmationData.setContentType(KEY_INFO_CONFIRMATION_DATA_TYPE);
        subjectConfirmationData.setContent(elementList);
        return subjectConfirmationData;
    } catch (SAML2Exception e) {
        throw new TokenCreationException(ResourceException.INTERNAL_ERROR, "Exception caught generating SubjectConfirmationData with HoK KeyInfo element in DefaultSubjectProvider: " + e, e);
    }
}
Also used : SAML2Exception(com.sun.identity.saml2.common.SAML2Exception) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) SubjectConfirmationData(com.sun.identity.saml2.assertion.SubjectConfirmationData) TokenCreationException(org.forgerock.openam.sts.TokenCreationException) XMLSecurityException(org.apache.xml.security.exceptions.XMLSecurityException)

Example 10 with SubjectConfirmationData

use of com.sun.identity.saml2.assertion.SubjectConfirmationData in project OpenAM by OpenRock.

the class DefaultSubjectProviderTest method testBearerStateSettings.

@Test
public void testBearerStateSettings() throws TokenCreationException {
    SubjectProvider subjectProvider = new DefaultSubjectProvider(Guice.createInjector(new MyModule()).getInstance(KeyInfoFactory.class));
    Date issueInstant = new Date();
    //must be set only when SubjectConfirmation is HoK
    ProofTokenState proof = null;
    Subject subject = subjectProvider.get(SUBJECT_ID, AUDIENCE_ID, createSAML2Config(), SAML2SubjectConfirmation.BEARER, issueInstant, proof);
    assertTrue(SUBJECT_ID.equals(subject.getNameID().getValue()));
    assertTrue(NAME_ID_FORMAT.equals(subject.getNameID().getFormat()));
    SubjectConfirmation subjectConfirmation = (SubjectConfirmation) subject.getSubjectConfirmation().get(0);
    assertTrue(SAML2Constants.SUBJECT_CONFIRMATION_METHOD_BEARER.equals(subjectConfirmation.getMethod()));
    SubjectConfirmationData subjectConfirmationData = subjectConfirmation.getSubjectConfirmationData();
    assertTrue((issueInstant.getTime() + (TOKEN_LIFETIME_SECONDS * 1000)) == subjectConfirmationData.getNotOnOrAfter().getTime());
}
Also used : SAML2SubjectConfirmation(org.forgerock.openam.sts.token.SAML2SubjectConfirmation) SubjectConfirmation(com.sun.identity.saml2.assertion.SubjectConfirmation) ProofTokenState(org.forgerock.openam.sts.user.invocation.ProofTokenState) SubjectConfirmationData(com.sun.identity.saml2.assertion.SubjectConfirmationData) Date(java.util.Date) Subject(com.sun.identity.saml2.assertion.Subject) KeyInfoFactory(org.forgerock.openam.sts.tokengeneration.saml2.xmlsig.KeyInfoFactory) Test(org.testng.annotations.Test)

Aggregations

SubjectConfirmationData (com.sun.identity.saml2.assertion.SubjectConfirmationData)8 SubjectConfirmation (com.sun.identity.saml2.assertion.SubjectConfirmation)7 Date (java.util.Date)7 SAML2Exception (com.sun.identity.saml2.common.SAML2Exception)5 Subject (com.sun.identity.saml2.assertion.Subject)4 ArrayList (java.util.ArrayList)4 SAML2SubjectConfirmation (org.forgerock.openam.sts.token.SAML2SubjectConfirmation)3 List (java.util.List)2 TokenCreationException (org.forgerock.openam.sts.TokenCreationException)2 KeyInfoFactory (org.forgerock.openam.sts.tokengeneration.saml2.xmlsig.KeyInfoFactory)2 Test (org.testng.annotations.Test)2 Element (org.w3c.dom.Element)2 Node (org.w3c.dom.Node)2 AudienceRestriction (com.sun.identity.saml2.assertion.AudienceRestriction)1 Conditions (com.sun.identity.saml2.assertion.Conditions)1 Issuer (com.sun.identity.saml2.assertion.Issuer)1 AssertionConsumerServiceElement (com.sun.identity.saml2.jaxb.metadata.AssertionConsumerServiceElement)1 HashMap (java.util.HashMap)1 Iterator (java.util.Iterator)1 Map (java.util.Map)1