<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../.resources/report.css" type="text/css"/><link rel="shortcut icon" href="../.resources/report.gif" type="image/gif"/><title>SAMLTokenValidator.java</title><link rel="stylesheet" href="../.resources/prettify.css" type="text/css"/><script type="text/javascript" src="../.resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="right"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> &gt; <a href="index.html" class="el_package">org.apache.rahas.impl</a> &gt; <span class="el_source">SAMLTokenValidator.java</span></div><h1>SAMLTokenValidator.java</h1><pre class="source lang-java linenums">package org.apache.rahas.impl;

import java.security.PublicKey;
import java.security.cert.X509Certificate;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.Parameter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.RahasData;
import org.apache.rahas.Token;
import org.apache.rahas.TokenStorage;
import org.apache.rahas.TokenValidator;
import org.apache.rahas.TrustException;
import org.apache.rahas.TrustUtil;
import org.apache.rahas.impl.util.CommonUtil;
import org.apache.rahas.impl.util.SAMLUtils;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.opensaml.saml1.core.Assertion;
import org.opensaml.xml.signature.SignatureValidator;
import org.opensaml.xml.validation.ValidationException;
import org.w3c.dom.Element;

/**
 * Implementation of a SAML Token Validator for the Security Token Service.
 */
@SuppressWarnings({&quot;UnusedDeclaration&quot;})
<span class="nc" id="L34">public class SAMLTokenValidator implements TokenValidator {</span>

<span class="nc" id="L36">    Log log = LogFactory.getLog(SAMLTokenValidator.class);</span>

    private String configFile;
    private OMElement configElement;
    private String configParamName;

    /**
     * Returns a SOAPEnvelope with the result of the validation.
     * 
     * @param data
     *                the RahasData object, containing information about the
     *                request.
     */
    public SOAPEnvelope validate(RahasData data) throws TrustException {
        // retrieve the message context
<span class="nc" id="L51">        MessageContext inMsgCtx = data.getInMessageContext();</span>

        // retrieve the list of tokens from the message context
<span class="nc" id="L54">        TokenStorage tkStorage = TrustUtil.getTokenStore(inMsgCtx);</span>

        // Create envelope
<span class="nc" id="L57">        SOAPEnvelope env = TrustUtil.createSOAPEnvelope(inMsgCtx</span>
                .getEnvelope().getNamespace().getNamespaceURI());

        // Create RSTR element, with respective version
        OMElement rstrElem;
<span class="nc" id="L62">        int wstVersion = data.getVersion();</span>
<span class="nc bnc" id="L63" title="All 2 branches missed.">        if (RahasConstants.VERSION_05_02 == wstVersion) {</span>
<span class="nc" id="L64">            rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(</span>
                    wstVersion, env.getBody());
        } else {
<span class="nc" id="L67">            OMElement rstrcElem = TrustUtil</span>
                    .createRequestSecurityTokenResponseCollectionElement(
                            wstVersion, env.getBody());
<span class="nc" id="L70">            rstrElem = TrustUtil.createRequestSecurityTokenResponseElement(</span>
                    wstVersion, rstrcElem);
        }

        // Create TokenType element, set to RSTR/Status
<span class="nc" id="L75">        TrustUtil.createTokenTypeElement(wstVersion, rstrElem).setText(</span>
                TrustUtil.getWSTNamespace(wstVersion)
                        + RahasConstants.TOK_TYPE_STATUS);

        // Create Status element
<span class="nc" id="L80">        OMElement statusElement = createMessageElement(wstVersion,</span>
                rstrElem, RahasConstants.LocalNames.STATUS);

        // Obtain the token
<span class="nc" id="L84">        Token tk = tkStorage.getToken(data.getTokenId());</span>

        // create the crypto object
<span class="nc" id="L87">        PublicKey issuerPBKey = getIssuerPublicKey(inMsgCtx);</span>

<span class="nc" id="L89">        boolean valid = isValid(tk, issuerPBKey);</span>
        String validityCode;

<span class="nc bnc" id="L92" title="All 2 branches missed.">        if (valid) {</span>
<span class="nc" id="L93">            validityCode = RahasConstants.STATUS_CODE_VALID;</span>
        } else {
<span class="nc" id="L95">            validityCode = RahasConstants.STATUS_CODE_INVALID;</span>
        }

        // Create Code element (inside Status) and set it to the
        // correspondent value
<span class="nc" id="L100">        createMessageElement(wstVersion, statusElement,</span>
                RahasConstants.LocalNames.CODE).setText(
                TrustUtil.getWSTNamespace(wstVersion) + validityCode);

<span class="nc" id="L104">        return env;</span>
    }

    /**
     * Checks whether the token is valid or not, by verifying the issuer's own
     * signature. If it has been signed by the token issuer, then it is a valid
     * token.
     * 
     * @param token
     *                the token to validate.
     * @param issuerPBKey Public key which should be used during validation.
     * @return true if the token has been signed by the issuer.
     */
    private boolean isValid(Token token, PublicKey issuerPBKey) {
        // extract SAMLAssertion object from token
<span class="nc" id="L119">        OMElement assertionOMElement = token.getToken();</span>
        Assertion samlAssertion;

        try {
<span class="nc" id="L123">            samlAssertion = SAMLUtils.buildAssertion((Element) assertionOMElement);</span>

<span class="nc" id="L125">            log.info(&quot;Verifying token validity...&quot;);</span>

            // check if the token has been signed by the issuer.
<span class="nc" id="L128">            SignatureValidator validator = new SignatureValidator(samlAssertion.getSignature().getSigningCredential());</span>
<span class="nc" id="L129">            validator.validate(samlAssertion.getSignature());</span>

<span class="nc" id="L131">        } catch (ValidationException e) {</span>
<span class="nc" id="L132">            log.error(&quot;Signature verification failed on SAML token.&quot;, e);</span>
<span class="nc" id="L133">            return false;</span>
<span class="nc" id="L134">        }</span>

        // if there was no exception, then the token is valid
<span class="nc" id="L137">        return true;</span>
    }

    //here we basically reuse the SAMLTokenIssuer config
    // to create the crypto object, so we can load the issuer's certificates
    private PublicKey getIssuerPublicKey(MessageContext inMsgCtx) {
<span class="nc" id="L143">        PublicKey issuerPBKey = null;</span>
<span class="nc" id="L144">        SAMLTokenIssuerConfig config = null;</span>

        try {
<span class="nc bnc" id="L147" title="All 2 branches missed.">            if (configElement != null) {</span>
<span class="nc" id="L148">                config = new SAMLTokenIssuerConfig(</span>
                        configElement
                                .getFirstChildWithName(SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
            }

            // Look for the file
<span class="nc bnc" id="L154" title="All 4 branches missed.">            if ((config == null) &amp;&amp; (configFile != null)) {</span>
<span class="nc" id="L155">                config = new SAMLTokenIssuerConfig(configFile);</span>
            }

            // Look for the param
<span class="nc bnc" id="L159" title="All 4 branches missed.">            if ((config == null) &amp;&amp; (configParamName != null)) {</span>
<span class="nc" id="L160">                Parameter param = inMsgCtx.getParameter(configParamName);</span>
<span class="nc bnc" id="L161" title="All 4 branches missed.">                if ((param != null) &amp;&amp; (param.getParameterElement() != null)) {</span>
<span class="nc" id="L162">                    config = new SAMLTokenIssuerConfig(param</span>
                            .getParameterElement().getFirstChildWithName(
                                    SAMLTokenIssuerConfig.SAML_ISSUER_CONFIG));
                } else {
<span class="nc" id="L166">                    throw new TrustException(&quot;expectedParameterMissing&quot;,</span>
                            new String[] { configParamName });
                }
            }

<span class="nc bnc" id="L171" title="All 2 branches missed.">            if (config == null) {</span>
<span class="nc" id="L172">                throw new TrustException(&quot;configurationIsNull&quot;);</span>
            }

            Crypto crypto;
<span class="nc bnc" id="L176" title="All 2 branches missed.">            if (config.cryptoElement != null) { // crypto props</span>
                // defined as
                // elements
<span class="nc" id="L179">                crypto = CryptoFactory.getInstance(TrustUtil</span>
                        .toProperties(config.cryptoElement), inMsgCtx
                        .getAxisService().getClassLoader());
            } else { // crypto props defined in a properties file
<span class="nc" id="L183">                crypto = CryptoFactory.getInstance(config.cryptoPropertiesFile,</span>
                        inMsgCtx.getAxisService().getClassLoader());
            }

<span class="nc" id="L187">            X509Certificate issuerCert = CommonUtil.getCertificateByAlias(crypto,config.getIssuerKeyAlias());</span>

<span class="nc" id="L189">            issuerPBKey = issuerCert.getPublicKey();</span>

<span class="nc" id="L191">        } catch (Exception e) {</span>
<span class="nc" id="L192">            log.error(&quot;Could not retrieve issuer public key&quot;, e);</span>
<span class="nc" id="L193">        }</span>
<span class="nc" id="L194">        return issuerPBKey;</span>
    }


    private static OMElement createMessageElement(int version,
            OMElement parent, String elementName) throws TrustException {
<span class="nc" id="L200">        return createOMElement(parent, TrustUtil.getWSTNamespace(version),</span>
                elementName, RahasConstants.WST_PREFIX);
    }

    private static OMElement createOMElement(OMElement parent, String ns,
            String ln, String prefix) {
<span class="nc" id="L206">        return parent.getOMFactory().createOMElement(new QName(ns, ln, prefix),</span>
                parent);
    }

    // ========================================================================

    /**
     * Set the configuration file of this TokenValidator. &lt;p/&gt; This is the text
     * value of the &amp;lt;configuration-file&amp;gt; element of the
     * token-dispatcher-configuration
     * 
     * @param configFile  configuration file to be used.
     */
    public void setConfigurationFile(String configFile) {
<span class="nc" id="L220">        this.configFile = configFile;</span>
<span class="nc" id="L221">    }</span>

    /**
     * Set the name of the configuration parameter. &lt;p/&gt; If this is used then
     * there must be a &lt;code&gt;org.apache.axis2.description.Parameter&lt;/code&gt;
     * object available in the via the messageContext when the
     * &lt;code&gt;TokenValidator&lt;/code&gt; is called.
     * 
     * @param configParamName Parameter name.
     * @see org.apache.axis2.description.Parameter
     */
    public void setConfigurationParamName(String configParamName) {
<span class="nc" id="L233">        this.configParamName = configParamName;</span>
<span class="nc" id="L234">    }</span>

    public void setConfigurationElement(OMElement configElement) {
<span class="nc" id="L237">        this.configElement = configElement;</span>
<span class="nc" id="L238">    }</span>

}
</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.6.1.201212231917</span></div></body></html>