<?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>SAML2AssertionHandler.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="info"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> &gt; <a href="index.source.html" class="el_package">org.apache.rampart.saml</a> &gt; <span class="el_source">SAML2AssertionHandler.java</span></div><h1>SAML2AssertionHandler.java</h1><pre class="source lang-java linenums">/*
 * Copyright (c) The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
 * 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 &quot;AS IS&quot; 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.apache.rampart.saml;

import org.apache.axiom.om.OMElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rahas.RahasConstants;
import org.apache.rahas.TrustException;
import org.apache.rahas.impl.util.SAML2KeyInfo;
import org.apache.rahas.impl.util.SAML2Utils;
import org.apache.rampart.TokenCallbackHandler;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Conditions;
import org.opensaml.saml2.core.Subject;
import org.opensaml.saml2.core.SubjectConfirmationData;


/**
 * This class handles SAML2 assertions.Processes SAML2 assertion and will extract SAML2 attributes
 * such as assertion id, start date, end date etc ...
 */
public class SAML2AssertionHandler extends SAMLAssertionHandler{

<span class="nc" id="L41">    private static final Log log = LogFactory.getLog(SAML2AssertionHandler.class);</span>

    private Assertion assertion;


<span class="nc" id="L46">    public SAML2AssertionHandler(Assertion samlAssertion) {</span>
<span class="nc" id="L47">        this.assertion = samlAssertion;</span>
<span class="nc" id="L48">        this.processSAMLAssertion();</span>
<span class="nc" id="L49">    }</span>

    /**
     * Checks whether SAML assertion is bearer - urn:oasis:names:tc:SAML:2.0:cm:bearer
     *
     * @return true if assertion is bearer else false.
     */
    public boolean isBearerAssertion() {

        // if the subject confirmation method is Bearer, do not try to get the KeyInfo
<span class="nc" id="L59">        return SAML2Utils.getSAML2SubjectConfirmationMethod(assertion).equals(</span>
                RahasConstants.SAML20_SUBJECT_CONFIRMATION_BEARER);
    }

    protected void processSAMLAssertion() {

<span class="nc" id="L65">        this.setAssertionId(assertion.getID());</span>

<span class="nc" id="L67">        Subject subject = assertion.getSubject();</span>

        //Read the validity period from the 'Conditions' element, else read it from SC Data
<span class="nc bnc" id="L70" title="All 2 branches missed.">        if (assertion.getConditions() != null) {</span>
<span class="nc" id="L71">            Conditions conditions = assertion.getConditions();</span>
<span class="nc bnc" id="L72" title="All 2 branches missed.">            if (conditions.getNotBefore() != null) {</span>
<span class="nc" id="L73">                this.setDateNotBefore(conditions.getNotBefore().toDate());</span>
            }
<span class="nc bnc" id="L75" title="All 2 branches missed.">            if (conditions.getNotOnOrAfter() != null) {</span>
<span class="nc" id="L76">                this.setDateNotOnOrAfter(conditions.getNotOnOrAfter().toDate());</span>
            }
<span class="nc" id="L78">        } else {</span>
<span class="nc" id="L79">            SubjectConfirmationData scData = subject.getSubjectConfirmations()</span>
                    .get(0).getSubjectConfirmationData();
<span class="nc bnc" id="L81" title="All 2 branches missed.">            if (scData.getNotBefore() != null) {</span>
<span class="nc" id="L82">                this.setDateNotBefore(scData.getNotBefore().toDate());</span>
            }
<span class="nc bnc" id="L84" title="All 2 branches missed.">            if (scData.getNotOnOrAfter() != null) {</span>
<span class="nc" id="L85">                this.setDateNotOnOrAfter(scData.getNotOnOrAfter().toDate());</span>
            }
        }

<span class="nc" id="L89">    }</span>

    public byte[] getAssertionKeyInfoSecret(Crypto signatureCrypto, TokenCallbackHandler tokenCallbackHandler)
            throws WSSecurityException {
        // TODO : SAML2KeyInfo element needs to be moved to WSS4J.
<span class="nc" id="L94">        SAML2KeyInfo saml2KeyInfo = SAML2Utils.</span>
                getSAML2KeyInfo(assertion, signatureCrypto, tokenCallbackHandler);

<span class="nc" id="L97">        return saml2KeyInfo.getSecret();</span>
    }

    public OMElement getAssertionElement() throws TrustException{
        try {
<span class="nc" id="L102">            return (OMElement) SAML2Utils.getElementFromAssertion(assertion);</span>
<span class="nc" id="L103">        } catch (TrustException e) {</span>
<span class="nc" id="L104">            log.error(&quot;Error getting Axiom representation of SAML2 assertion.&quot;, e);</span>
<span class="nc" id="L105">            throw e;</span>
        }
    }



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