<?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>SAMLAssertionHandler.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.rampart.saml</a> &gt; <span class="el_source">SAMLAssertionHandler.java</span></div><h1>SAMLAssertionHandler.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.TrustException;
import org.apache.rampart.TokenCallbackHandler;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;

import java.util.Date;

/**
 * A class to handle attributes to common SAML1 and SAML2 assertions.
 */
<span class="nc" id="L33">public abstract class SAMLAssertionHandler {</span>


    private String assertionId;

    private Date dateNotBefore;

    private Date dateNotOnOrAfter;

    public String getAssertionId() {
<span class="nc" id="L43">        return assertionId;</span>
    }

    protected void setAssertionId(String assertionId) {
<span class="nc" id="L47">        this.assertionId = assertionId;</span>
<span class="nc" id="L48">    }</span>

    public Date getDateNotBefore() {
<span class="nc" id="L51">        return dateNotBefore;</span>
    }

    protected void setDateNotBefore(Date dateNotBefore) {
<span class="nc" id="L55">        this.dateNotBefore = dateNotBefore;</span>
<span class="nc" id="L56">    }</span>

    public Date getDateNotOnOrAfter() {
<span class="nc" id="L59">        return dateNotOnOrAfter;</span>
    }

    protected void setDateNotOnOrAfter(Date dateNotOnOrAfter) {
<span class="nc" id="L63">        this.dateNotOnOrAfter = dateNotOnOrAfter;</span>
<span class="nc" id="L64">    }</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 abstract boolean isBearerAssertion();

    protected abstract void processSAMLAssertion();


    /**
     * Gets the secret in assertion.
     * @param signatureCrypto Signature crypto info, private,public keys.
     * @param tokenCallbackHandler The token callback class. TODO Why ?
     * @return Secret as a byte array
     * @throws WSSecurityException If an error occurred while validating the signature.
     */
    public abstract byte[] getAssertionKeyInfoSecret(Crypto signatureCrypto, TokenCallbackHandler tokenCallbackHandler)
            throws WSSecurityException;

    /**
     * Gets the assertion element as an Axiom OMElement.
     * @return OMElement representation of assertion.
     * @throws TrustException if an error occurred while converting Assertion to an OMElement.
     */
    public abstract OMElement getAssertionElement() throws TrustException;
}
</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>