org.wso2.carbon.identity.provider.saml.SAML1TokenBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.identity.provider.saml.SAML1TokenBuilder.java

Source

/*
 * Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 *  WSO2 Inc. licenses this file to you under the Apache License,
 *  Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.wso2.carbon.identity.provider.saml;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rahas.RahasData;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.utils.Base64;
import org.joda.time.DateTime;
import org.opensaml.saml1.core.Assertion;
import org.opensaml.saml1.core.Attribute;
import org.opensaml.saml1.core.AttributeStatement;
import org.opensaml.saml1.core.AttributeValue;
import org.opensaml.saml1.core.Audience;
import org.opensaml.saml1.core.AudienceRestrictionCondition;
import org.opensaml.saml1.core.Conditions;
import org.opensaml.saml1.core.ConfirmationMethod;
import org.opensaml.saml1.core.Subject;
import org.opensaml.saml1.core.SubjectConfirmation;
import org.opensaml.xml.Configuration;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilder;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.io.MarshallerFactory;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.schema.XSString;
import org.opensaml.xml.schema.impl.XSStringBuilder;
import org.opensaml.xml.security.x509.X509Credential;
import org.opensaml.xml.signature.KeyInfo;
import org.opensaml.xml.signature.Signature;
import org.opensaml.xml.signature.Signer;
import org.opensaml.xml.signature.X509Certificate;
import org.opensaml.xml.signature.X509Data;
import org.w3c.dom.Element;
import org.wso2.carbon.base.ServerConfiguration;
import org.wso2.carbon.identity.provider.GenericIdentityProviderData;
import org.wso2.carbon.identity.provider.IdentityProviderException;
import org.wso2.carbon.identity.provider.RequestedClaimData;

import javax.xml.namespace.QName;
import java.security.cert.CertificateEncodingException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class SAML1TokenBuilder implements SAMLTokenBuilder {

    public static final String CONF_KEY = "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key";
    private static final Log log = LogFactory.getLog(SAML1TokenBuilder.class);
    protected Assertion assertion = null;
    protected AttributeStatement attributeStmt = null;
    protected List<Signature> signatureList = new ArrayList<Signature>();
    protected Element signedAssertion = null;
    protected String appilesTo = null;

    protected static XMLObject buildXMLObject(QName objectQName) throws IdentityProviderException {
        XMLObjectBuilder builder = Configuration.getBuilderFactory().getBuilder(objectQName);
        if (builder == null) {
            throw new IdentityProviderException("Unable to retrieve builder for object QName " + objectQName);
        }
        return builder.buildObject(objectQName.getNamespaceURI(), objectQName.getLocalPart(),
                objectQName.getPrefix());
    }

    @Override
    public void createStatement(GenericIdentityProviderData ipData, RahasData rahasData)
            throws IdentityProviderException {
        if (log.isDebugEnabled()) {
            log.debug("Begin SAML statement creation.");
        }
        attributeStmt = (AttributeStatement) buildXMLObject(AttributeStatement.DEFAULT_ELEMENT_NAME);

        Subject subject = (Subject) buildXMLObject(Subject.DEFAULT_ELEMENT_NAME);
        SubjectConfirmation subjectConf = (SubjectConfirmation) buildXMLObject(
                SubjectConfirmation.DEFAULT_ELEMENT_NAME);
        ConfirmationMethod confMethod = (ConfirmationMethod) buildXMLObject(
                ConfirmationMethod.DEFAULT_ELEMENT_NAME);
        confMethod.setConfirmationMethod(CONF_KEY);
        subjectConf.getConfirmationMethods().add(confMethod);
        subject.setSubjectConfirmation(subjectConf);

        attributeStmt.setSubject(subject);

        Map<String, RequestedClaimData> mapClaims = ipData.getRequestedClaims();

        if (rahasData.getAppliesToAddress() != null) {
            appilesTo = rahasData.getAppliesToAddress();
        }

        Iterator<RequestedClaimData> ite = mapClaims.values().iterator();

        while (ite.hasNext()) {
            RequestedClaimData claim = ite.next();
            String uri = claim.getUri();

            int index = uri.lastIndexOf("/");
            String attrName = uri.substring(index + 1, uri.length());
            String attrNamespace = uri.substring(0, index);

            Attribute attribute = (Attribute) buildXMLObject(Attribute.DEFAULT_ELEMENT_NAME);
            attribute.setAttributeName(attrName);
            attribute.setAttributeNamespace(attrNamespace);

            XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
            XSStringBuilder attributeValueBuilder = (XSStringBuilder) builderFactory.getBuilder(XSString.TYPE_NAME);

            XSString stringValue = attributeValueBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME,
                    XSString.TYPE_NAME);
            stringValue.setValue(claim.getValue());
            attribute.getAttributeValues().add(stringValue);

            attributeStmt.getAttributes().add(attribute);
        }
    }

    @Override
    public void createSAMLAssertion(DateTime notAfter, DateTime notBefore, String assertionId)
            throws IdentityProviderException {
        assertion = (Assertion) buildXMLObject(Assertion.DEFAULT_ELEMENT_NAME);
        Conditions conditions = (Conditions) buildXMLObject(Conditions.DEFAULT_ELEMENT_NAME);
        conditions.setNotBefore(notBefore);
        conditions.setNotOnOrAfter(notAfter);

        ServerConfiguration config = ServerConfiguration.getInstance();
        String host = "http://" + config.getFirstProperty("HostName");
        assertion.setIssuer(host);
        assertion.setIssueInstant(new DateTime());

        if (appilesTo != null) {
            Audience audience = (Audience) buildXMLObject(Audience.DEFAULT_ELEMENT_NAME);
            audience.setUri(appilesTo);
            AudienceRestrictionCondition audienceRestrictions = (AudienceRestrictionCondition) buildXMLObject(
                    AudienceRestrictionCondition.DEFAULT_ELEMENT_NAME);
            audienceRestrictions.getAudiences().add(audience);

            conditions.getAudienceRestrictionConditions().add(audienceRestrictions);
        }

        assertion.setConditions(conditions);

        assertion.getAttributeStatements().add(this.attributeStmt);
        assertion.setID(assertionId);

    }

    @Override
    public void setSignature(String signatureAlgorithm, X509Credential cred) throws IdentityProviderException {
        Signature signature = (Signature) buildXMLObject(Signature.DEFAULT_ELEMENT_NAME);
        signature.setSigningCredential(cred);
        signature.setSignatureAlgorithm(signatureAlgorithm);
        signature.setCanonicalizationAlgorithm(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);

        try {
            KeyInfo keyInfo = (KeyInfo) buildXMLObject(KeyInfo.DEFAULT_ELEMENT_NAME);
            X509Data data = (X509Data) buildXMLObject(X509Data.DEFAULT_ELEMENT_NAME);
            X509Certificate cert = (X509Certificate) buildXMLObject(X509Certificate.DEFAULT_ELEMENT_NAME);
            String value = Base64.encode(cred.getEntityCertificate().getEncoded());
            cert.setValue(value);
            data.getX509Certificates().add(cert);
            keyInfo.getX509Datas().add(data);
            signature.setKeyInfo(keyInfo);
        } catch (CertificateEncodingException e) {
            log.error("Error while getting the encoded certificate", e);
            throw new IdentityProviderException("Error while getting the encoded certificate");
        }

        assertion.setSignature(signature);
        signatureList.add(signature);
    }

    @Override
    public void marshellAndSign() throws IdentityProviderException {
        try {
            MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory();
            Marshaller marshaller = marshallerFactory.getMarshaller(assertion);
            signedAssertion = marshaller.marshall(assertion);

            Signer.signObjects(signatureList);

        } catch (MarshallingException e) {
            log.debug(e);
            throw new IdentityProviderException("errorMarshellingOrSigning", e);
        } catch (Exception e) {
            log.debug(e);
            throw new IdentityProviderException("errorMarshellingOrSigning", e);
        }
    }

    @Override
    public Element getSAMLasDOM() throws IdentityProviderException {
        return signedAssertion;
    }

}