All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.rahas.impl.SAMLTokenRenewer Maven / Gradle / Ivy

There is a newer version: 1.8.0
Show newest version
package org.apache.rahas.impl;

import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.impl.dom.jaxp.DocumentBuilderFactoryImpl;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.Parameter;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.RahasData;
import org.apache.rahas.Token;
import org.apache.rahas.TokenRenewer;
import org.apache.rahas.TokenStorage;
import org.apache.rahas.TrustException;
import org.apache.rahas.TrustUtil;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.util.XmlSchemaDateFormat;
import org.apache.xml.security.signature.XMLSignature;
import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class SAMLTokenRenewer implements TokenRenewer {
    
    private String configParamName;

    private OMElement configElement;

    private String configFile;

    public SOAPEnvelope renew(RahasData data) throws TrustException {
        
        // retrieve the message context
        MessageContext inMsgCtx = data.getInMessageContext();
        
        SAMLTokenIssuerConfig config = null;
        if (this.configElement != null) {
            config = new SAMLTokenIssuerConfig(configElement
                            .getFirstChildWithName(SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
        }

        // Look for the file
        if (config == null && this.configFile != null) {
            config = new SAMLTokenIssuerConfig(this.configFile);
        }

        // Look for the param
        if (config == null && this.configParamName != null) {
            Parameter param = inMsgCtx.getParameter(this.configParamName);
            if (param != null && param.getParameterElement() != null) {
                config = new SAMLTokenIssuerConfig(param
                        .getParameterElement().getFirstChildWithName(
                                SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
            } else {
                throw new TrustException("expectedParameterMissing",
                        new String[] { this.configParamName });
            }
        }

        if (config == null) {
            throw new TrustException("configurationIsNull");
        }
        
        // retrieve the list of tokens from the message context
        TokenStorage tkStorage = TrustUtil.getTokenStore(inMsgCtx);
        
        try {
            // Set the DOM impl to DOOM
            DocumentBuilderFactoryImpl.setDOOMRequired(true);

            // Create envelope
            SOAPEnvelope env = TrustUtil.createSOAPEnvelope(inMsgCtx
                    .getEnvelope().getNamespace().getNamespaceURI());

            // Create RSTR element, with respective version
            OMElement rstrElem;
            int wstVersion = data.getVersion();
            if (RahasConstants.VERSION_05_02 == wstVersion) {
                rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(
                        wstVersion, env.getBody());
            } else {
                OMElement rstrcElem = TrustUtil
                        .createRequestSecurityTokenResponseCollectionElement(
                                wstVersion, env.getBody());
                rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(
                        wstVersion, rstrcElem);
            }
            
            Crypto crypto;
            if (config.cryptoElement != null) { 
                // crypto props defined as elements
                crypto = CryptoFactory.getInstance(TrustUtil
                        .toProperties(config.cryptoElement), inMsgCtx
                        .getAxisService().getClassLoader());
            } else { 
                // crypto props defined in a properties file
                crypto = CryptoFactory.getInstance(config.cryptoPropertiesFile,
                        inMsgCtx.getAxisService().getClassLoader());
            }

            // Create TokenType element
            TrustUtil.createTokenTypeElement(wstVersion, rstrElem).setText(
                    RahasConstants.TOK_TYPE_SAML_10);
            
            // Creation and expiration times
            Date creationTime = new Date();
            Date expirationTime = new Date();
            expirationTime.setTime(creationTime.getTime() + config.ttl);
            
            // Use GMT time in milliseconds
            DateFormat zulu = new XmlSchemaDateFormat();

            // Add the Lifetime element
            TrustUtil.createLifetimeElement(wstVersion, rstrElem, zulu
                    .format(creationTime), zulu.format(expirationTime));

            // Obtain the token
            Token tk = tkStorage.getToken(data.getTokenId());

            OMElement assertionOMElement = tk.getToken();
            SAMLAssertion samlAssertion = null;

            try {
                samlAssertion = new SAMLAssertion((Element) assertionOMElement);
                samlAssertion.unsign();
                samlAssertion.setNotBefore(creationTime);
                samlAssertion.setNotOnOrAfter(expirationTime);
                
                // sign the assertion
                X509Certificate[] issuerCerts = crypto
                        .getCertificates(config.issuerKeyAlias);

                String sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_RSA;
                String pubKeyAlgo = issuerCerts[0].getPublicKey().getAlgorithm();
                if (pubKeyAlgo.equalsIgnoreCase("DSA")) {
                    sigAlgo = XMLSignature.ALGO_ID_SIGNATURE_DSA;
                }
                java.security.Key issuerPK = crypto.getPrivateKey(
                        config.issuerKeyAlias, config.issuerKeyPassword);
                
                samlAssertion.sign(sigAlgo, issuerPK, Arrays.asList(issuerCerts));
                
                // Create the RequestedSecurityToken element and add the SAML token
                // to it
                OMElement reqSecTokenElem = TrustUtil
                        .createRequestedSecurityTokenElement(wstVersion, rstrElem);
                
                Node tempNode = samlAssertion.toDOM();
                reqSecTokenElem.addChild((OMNode) ((Element) rstrElem)
                        .getOwnerDocument().importNode(tempNode, true));


            } catch (SAMLException e) {
                throw new TrustException("Cannot create SAML Assertion",e);             
            } catch (WSSecurityException e) {
                throw new TrustException("Cannot create SAML Assertion",e);
            } catch (Exception e) {
                throw new TrustException("Cannot create SAML Assertion",e);
            }
            return env;
        } finally {
            DocumentBuilderFactoryImpl.setDOOMRequired(false);
        }

    }

    /**
     * {@inheritDoc}
     */
    public void setConfigurationFile(String configFile) {
        this.configFile = configFile;

    }
    
    /**
     * {@inheritDoc}
     */
    public void setConfigurationElement(OMElement configElement) {
        this.configElement = configElement;
    }

    /**
     * {@inheritDoc}
     */
    public void setConfigurationParamName(String configParamName) {
        this.configParamName = configParamName;
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy