<?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>FormAuthenticationFilter.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 :: Jar Bundle</a> &gt; <a href="../index.html" class="el_bundle">shiro-web</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.web.filter.authc</a> &gt; <span class="el_source">FormAuthenticationFilter.java</span></div><h1>FormAuthenticationFilter.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.web.filter.authc;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;


/**
 * Requires the requesting user to be authenticated for the request to continue, and if they are not, forces the user
 * to login via by redirecting them to the {@link #setLoginUrl(String) loginUrl} you configure.
 * &lt;p/&gt;
 * &lt;p&gt;This filter constructs a {@link UsernamePasswordToken UsernamePasswordToken} with the values found in
 * {@link #setUsernameParam(String) username}, {@link #setPasswordParam(String) password},
 * and {@link #setRememberMeParam(String) rememberMe} request parameters.  It then calls
 * {@link org.apache.shiro.subject.Subject#login(org.apache.shiro.authc.AuthenticationToken) Subject.login(usernamePasswordToken)},
 * effectively automatically performing a login attempt.  Note that the login attempt will only occur when the
 * {@link #isLoginSubmission(javax.servlet.ServletRequest, javax.servlet.ServletResponse) isLoginSubmission(request,response)}
 * is &lt;code&gt;true&lt;/code&gt;, which by default occurs when the request is for the {@link #setLoginUrl(String) loginUrl} and
 * is a POST request.
 * &lt;p/&gt;
 * &lt;p&gt;If the login attempt fails, the resulting &lt;code&gt;AuthenticationException&lt;/code&gt; fully qualified class name will
 * be set as a request attribute under the {@link #setFailureKeyAttribute(String) failureKeyAttribute} key.  This
 * FQCN can be used as an i18n key or lookup mechanism to explain to the user why their login attempt failed
 * (e.g. no account, incorrect password, etc).
 * &lt;p/&gt;
 * &lt;p&gt;If you would prefer to handle the authentication validation and login in your own code, consider using the
 * {@link PassThruAuthenticationFilter} instead, which allows requests to the
 * {@link #loginUrl} to pass through to your application's code directly.
 *
 * @see PassThruAuthenticationFilter
 * @since 0.9
 */
public class FormAuthenticationFilter extends AuthenticatingFilter {

    //TODO - complete JavaDoc

    public static final String DEFAULT_ERROR_KEY_ATTRIBUTE_NAME = &quot;shiroLoginFailure&quot;;

    public static final String DEFAULT_USERNAME_PARAM = &quot;username&quot;;
    public static final String DEFAULT_PASSWORD_PARAM = &quot;password&quot;;
    public static final String DEFAULT_REMEMBER_ME_PARAM = &quot;rememberMe&quot;;

<span class="fc" id="L69">    private static final Logger log = LoggerFactory.getLogger(FormAuthenticationFilter.class);</span>

<span class="fc" id="L71">    private String usernameParam = DEFAULT_USERNAME_PARAM;</span>
<span class="fc" id="L72">    private String passwordParam = DEFAULT_PASSWORD_PARAM;</span>
<span class="fc" id="L73">    private String rememberMeParam = DEFAULT_REMEMBER_ME_PARAM;</span>

<span class="fc" id="L75">    private String failureKeyAttribute = DEFAULT_ERROR_KEY_ATTRIBUTE_NAME;</span>

<span class="fc" id="L77">    public FormAuthenticationFilter() {</span>
<span class="fc" id="L78">        setLoginUrl(DEFAULT_LOGIN_URL);</span>
<span class="fc" id="L79">    }</span>

    @Override
    public void setLoginUrl(String loginUrl) {
<span class="fc" id="L83">        String previous = getLoginUrl();</span>
<span class="pc bpc" id="L84" title="1 of 2 branches missed.">        if (previous != null) {</span>
<span class="fc" id="L85">            this.appliedPaths.remove(previous);</span>
        }
<span class="fc" id="L87">        super.setLoginUrl(loginUrl);</span>
<span class="fc bfc" id="L88" title="All 2 branches covered.">        if (log.isTraceEnabled()) {</span>
<span class="fc" id="L89">            log.trace(&quot;Adding login url to applied paths.&quot;);</span>
        }
<span class="fc" id="L91">        this.appliedPaths.put(getLoginUrl(), null);</span>
<span class="fc" id="L92">    }</span>

    public String getUsernameParam() {
<span class="nc" id="L95">        return usernameParam;</span>
    }

    /**
     * Sets the request parameter name to look for when acquiring the username.  Unless overridden by calling this
     * method, the default is &lt;code&gt;username&lt;/code&gt;.
     *
     * @param usernameParam the name of the request param to check for acquiring the username.
     */
    public void setUsernameParam(String usernameParam) {
<span class="nc" id="L105">        this.usernameParam = usernameParam;</span>
<span class="nc" id="L106">    }</span>

    public String getPasswordParam() {
<span class="nc" id="L109">        return passwordParam;</span>
    }

    /**
     * Sets the request parameter name to look for when acquiring the password.  Unless overridden by calling this
     * method, the default is &lt;code&gt;password&lt;/code&gt;.
     *
     * @param passwordParam the name of the request param to check for acquiring the password.
     */
    public void setPasswordParam(String passwordParam) {
<span class="nc" id="L119">        this.passwordParam = passwordParam;</span>
<span class="nc" id="L120">    }</span>

    public String getRememberMeParam() {
<span class="nc" id="L123">        return rememberMeParam;</span>
    }

    /**
     * Sets the request parameter name to look for when acquiring the rememberMe boolean value.  Unless overridden
     * by calling this method, the default is &lt;code&gt;rememberMe&lt;/code&gt;.
     * &lt;p/&gt;
     * RememberMe will be &lt;code&gt;true&lt;/code&gt; if the parameter value equals any of those supported by
     * {@link org.apache.shiro.web.util.WebUtils#isTrue(javax.servlet.ServletRequest, String) WebUtils.isTrue(request,value)}, &lt;code&gt;false&lt;/code&gt;
     * otherwise.
     *
     * @param rememberMeParam the name of the request param to check for acquiring the rememberMe boolean value.
     */
    public void setRememberMeParam(String rememberMeParam) {
<span class="nc" id="L137">        this.rememberMeParam = rememberMeParam;</span>
<span class="nc" id="L138">    }</span>

    public String getFailureKeyAttribute() {
<span class="nc" id="L141">        return failureKeyAttribute;</span>
    }

    public void setFailureKeyAttribute(String failureKeyAttribute) {
<span class="nc" id="L145">        this.failureKeyAttribute = failureKeyAttribute;</span>
<span class="nc" id="L146">    }</span>

    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
<span class="nc bnc" id="L149" title="All 2 branches missed.">        if (isLoginRequest(request, response)) {</span>
<span class="nc bnc" id="L150" title="All 2 branches missed.">            if (isLoginSubmission(request, response)) {</span>
<span class="nc bnc" id="L151" title="All 2 branches missed.">                if (log.isTraceEnabled()) {</span>
<span class="nc" id="L152">                    log.trace(&quot;Login submission detected.  Attempting to execute login.&quot;);</span>
                }
<span class="nc" id="L154">                return executeLogin(request, response);</span>
            } else {
<span class="nc bnc" id="L156" title="All 2 branches missed.">                if (log.isTraceEnabled()) {</span>
<span class="nc" id="L157">                    log.trace(&quot;Login page view.&quot;);</span>
                }
                //allow them to see the login page ;)
<span class="nc" id="L160">                return true;</span>
            }
        } else {
<span class="nc bnc" id="L163" title="All 2 branches missed.">            if (log.isTraceEnabled()) {</span>
<span class="nc" id="L164">                log.trace(&quot;Attempting to access a path which requires authentication.  Forwarding to the &quot; +</span>
<span class="nc" id="L165">                        &quot;Authentication url [&quot; + getLoginUrl() + &quot;]&quot;);</span>
            }

<span class="nc" id="L168">            saveRequestAndRedirectToLogin(request, response);</span>
<span class="nc" id="L169">            return false;</span>
        }
    }

    /**
     * This default implementation merely returns &lt;code&gt;true&lt;/code&gt; if the request is an HTTP &lt;code&gt;POST&lt;/code&gt;,
     * &lt;code&gt;false&lt;/code&gt; otherwise. Can be overridden by subclasses for custom login submission detection behavior.
     *
     * @param request  the incoming ServletRequest
     * @param response the outgoing ServletResponse.
     * @return &lt;code&gt;true&lt;/code&gt; if the request is an HTTP &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt; otherwise.
     */
    @SuppressWarnings({&quot;UnusedDeclaration&quot;})
    protected boolean isLoginSubmission(ServletRequest request, ServletResponse response) {
<span class="nc bnc" id="L183" title="All 4 branches missed.">        return (request instanceof HttpServletRequest) &amp;&amp; WebUtils.toHttp(request).getMethod().equalsIgnoreCase(POST_METHOD);</span>
    }

    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
<span class="nc" id="L187">        String username = getUsername(request);</span>
<span class="nc" id="L188">        String password = getPassword(request);</span>
<span class="nc" id="L189">        return createToken(username, password, request, response);</span>
    }

    protected boolean isRememberMe(ServletRequest request) {
<span class="nc" id="L193">        return WebUtils.isTrue(request, getRememberMeParam());</span>
    }

    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
                                     ServletRequest request, ServletResponse response) throws Exception {
<span class="nc" id="L198">        issueSuccessRedirect(request, response);</span>
        //we handled the success redirect directly, prevent the chain from continuing:
<span class="nc" id="L200">        return false;</span>
    }

    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e,
                                     ServletRequest request, ServletResponse response) {
<span class="nc bnc" id="L205" title="All 2 branches missed.">        if (log.isDebugEnabled()) {</span>
<span class="nc" id="L206">            log.debug( &quot;Authentication exception&quot;, e );</span>
        }
<span class="nc" id="L208">        setFailureAttribute(request, e);</span>
        //login failed, let request continue back to the login page:
<span class="nc" id="L210">        return true;</span>
    }

    protected void setFailureAttribute(ServletRequest request, AuthenticationException ae) {
<span class="nc" id="L214">        String className = ae.getClass().getName();</span>
<span class="nc" id="L215">        request.setAttribute(getFailureKeyAttribute(), className);</span>
<span class="nc" id="L216">    }</span>

    protected String getUsername(ServletRequest request) {
<span class="nc" id="L219">        return WebUtils.getCleanParam(request, getUsernameParam());</span>
    }

    protected String getPassword(ServletRequest request) {
<span class="nc" id="L223">        return WebUtils.getCleanParam(request, getPasswordParam());</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>