<?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="../../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../../jacoco-resources/report.gif" type="image/gif"/><title>AllSuccessfulStrategy.java</title><link rel="stylesheet" href="../../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../../index.html" class="el_report">Apache Shiro :: All (aggregate jar)</a> &gt; <a href="../index.html" class="el_bundle">shiro-core</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.authc.pam</a> &gt; <span class="el_source">AllSuccessfulStrategy.java</span></div><h1>AllSuccessfulStrategy.java</h1><pre class="source lang-java linenums">/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.shiro.authc.pam;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.realm.Realm;


/**
 * &lt;tt&gt;AuthenticationStrategy&lt;/tt&gt; implementation that requires &lt;em&gt;all&lt;/em&gt; configured realms to
 * &lt;b&gt;successfully&lt;/b&gt; process the submitted &lt;tt&gt;AuthenticationToken&lt;/tt&gt; during the log-in attempt.
 * &lt;p/&gt;
 * &lt;p&gt;If one or more realms do not support the submitted token, or one or more are unable to acquire
 * &lt;tt&gt;AuthenticationInfo&lt;/tt&gt; for the token, this implementation will immediately fail the log-in attempt for the
 * associated subject (user).
 *
 * @since 0.2
 */
<span class="fc" id="L41">public class AllSuccessfulStrategy extends AbstractAuthenticationStrategy {</span>

    /** Private class log instance. */
<span class="fc" id="L44">    private static final Logger log = LoggerFactory.getLogger(AllSuccessfulStrategy.class);</span>

    /**
     * Because all realms in this strategy must complete successfully, this implementation ensures that the given
     * &lt;code&gt;Realm&lt;/code&gt; {@link org.apache.shiro.realm.Realm#supports(org.apache.shiro.authc.AuthenticationToken) supports} the given
     * &lt;code&gt;token&lt;/code&gt; argument.  If it does not, this method throws an
     * {@link UnsupportedTokenException UnsupportedTokenException} to end the authentication
     * process immediately. If the realm does support the token, the &lt;code&gt;info&lt;/code&gt; argument is returned immediately.
     */
    public AuthenticationInfo beforeAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
<span class="pc bpc" id="L54" title="1 of 2 branches missed.">        if (!realm.supports(token)) {</span>
<span class="fc" id="L55">            String msg = &quot;Realm [&quot; + realm + &quot;] of type [&quot; + realm.getClass().getName() + &quot;] does not support &quot; +</span>
<span class="fc" id="L56">                    &quot; the submitted AuthenticationToken [&quot; + token + &quot;].  The [&quot; + getClass().getName() +</span>
                    &quot;] implementation requires all configured realm(s) to support and be able to process the submitted &quot; +
                    &quot;AuthenticationToken.&quot;;
<span class="fc" id="L59">            throw new UnsupportedTokenException(msg);</span>
        }

<span class="nc" id="L62">        return info;</span>
    }

    /**
     * Merges the specified &lt;code&gt;info&lt;/code&gt; into the &lt;code&gt;aggregate&lt;/code&gt; argument and returns it (just as the
     * parent implementation does), but additionally ensures the following:
     * &lt;ol&gt;
     * &lt;li&gt;if the &lt;code&gt;Throwable&lt;/code&gt; argument is not &lt;code&gt;null&lt;/code&gt;, re-throws it to immediately cancel the
     * authentication process, since this strategy requires all realms to authenticate successfully.&lt;/li&gt;
     * &lt;li&gt;neither the &lt;code&gt;info&lt;/code&gt; or &lt;code&gt;aggregate&lt;/code&gt; argument is &lt;code&gt;null&lt;/code&gt; to ensure that each
     * realm did in fact authenticate successfully&lt;/li&gt;
     * &lt;/ol&gt;
     */
    public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo info, AuthenticationInfo aggregate, Throwable t)
            throws AuthenticationException {
<span class="nc bnc" id="L77" title="All 2 branches missed.">        if (t != null) {</span>
<span class="nc bnc" id="L78" title="All 2 branches missed.">            if (t instanceof AuthenticationException) {</span>
                //propagate:
<span class="nc" id="L80">                throw ((AuthenticationException) t);</span>
            } else {
<span class="nc" id="L82">                String msg = &quot;Unable to acquire account data from realm [&quot; + realm + &quot;].  The [&quot; +</span>
<span class="nc" id="L83">                        getClass().getName() + &quot; implementation requires all configured realm(s) to operate successfully &quot; +</span>
                        &quot;for a successful authentication.&quot;;
<span class="nc" id="L85">                throw new AuthenticationException(msg, t);</span>
            }
        }
<span class="nc bnc" id="L88" title="All 2 branches missed.">        if (info == null) {</span>
<span class="nc" id="L89">            String msg = &quot;Realm [&quot; + realm + &quot;] could not find any associated account data for the submitted &quot; +</span>
<span class="nc" id="L90">                    &quot;AuthenticationToken [&quot; + token + &quot;].  The [&quot; + getClass().getName() + &quot;] implementation requires &quot; +</span>
                    &quot;all configured realm(s) to acquire valid account data for a submitted token during the &quot; +
                    &quot;log-in process.&quot;;
<span class="nc" id="L93">            throw new UnknownAccountException(msg);</span>
        }

<span class="nc" id="L96">        log.debug(&quot;Account successfully authenticated using realm [{}]&quot;, realm);</span>

        // If non-null account is returned, then the realm was able to authenticate the
        // user - so merge the account with any accumulated before:
<span class="nc" id="L100">        merge(info, aggregate);</span>

<span class="nc" id="L102">        return aggregate;</span>
    }
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.7.201606060606</span></div></body></html>