blob: be6cd5c25f1d23ad6880d82ad651a4d8b2776cc8 [file] [log] [blame]
<?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>WebUtils.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-web</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.web.util</a> &gt; <span class="el_source">WebUtils.java</span></div><h1>WebUtils.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.util;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.util.StringUtils;
import org.apache.shiro.web.env.EnvironmentLoader;
import org.apache.shiro.web.env.WebEnvironment;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Map;
/**
* Simple utility class for operations used across multiple class hierarchies in the web framework code.
* &lt;p/&gt;
* Some methods in this class were copied from the Spring Framework so we didn't have to re-invent the wheel,
* and in these cases, we have retained all license, copyright and author information.
*
* @since 0.9
*/
<span class="nc" id="L50">public class WebUtils {</span>
//TODO - complete JavaDoc
<span class="fc" id="L54"> private static final Logger log = LoggerFactory.getLogger(WebUtils.class);</span>
<span class="fc" id="L56"> public static final String SERVLET_REQUEST_KEY = ServletRequest.class.getName() + &quot;_SHIRO_THREAD_CONTEXT_KEY&quot;;</span>
<span class="fc" id="L57"> public static final String SERVLET_RESPONSE_KEY = ServletResponse.class.getName() + &quot;_SHIRO_THREAD_CONTEXT_KEY&quot;;</span>
/**
* {@link org.apache.shiro.session.Session Session} key used to save a request and later restore it, for example when redirecting to a
* requested page after login, equal to {@code shiroSavedRequest}.
*/
public static final String SAVED_REQUEST_KEY = &quot;shiroSavedRequest&quot;;
/**
* Standard Servlet 2.3+ spec request attributes for include URI and paths.
* &lt;p&gt;If included via a RequestDispatcher, the current resource will see the
* originating request. Its own URI and paths are exposed as request attributes.
*/
public static final String INCLUDE_REQUEST_URI_ATTRIBUTE = &quot;javax.servlet.include.request_uri&quot;;
public static final String INCLUDE_CONTEXT_PATH_ATTRIBUTE = &quot;javax.servlet.include.context_path&quot;;
public static final String INCLUDE_SERVLET_PATH_ATTRIBUTE = &quot;javax.servlet.include.servlet_path&quot;;
public static final String INCLUDE_PATH_INFO_ATTRIBUTE = &quot;javax.servlet.include.path_info&quot;;
public static final String INCLUDE_QUERY_STRING_ATTRIBUTE = &quot;javax.servlet.include.query_string&quot;;
/**
* Standard Servlet 2.4+ spec request attributes for forward URI and paths.
* &lt;p&gt;If forwarded to via a RequestDispatcher, the current resource will see its
* own URI and paths. The originating URI and paths are exposed as request attributes.
*/
public static final String FORWARD_REQUEST_URI_ATTRIBUTE = &quot;javax.servlet.forward.request_uri&quot;;
public static final String FORWARD_CONTEXT_PATH_ATTRIBUTE = &quot;javax.servlet.forward.context_path&quot;;
public static final String FORWARD_SERVLET_PATH_ATTRIBUTE = &quot;javax.servlet.forward.servlet_path&quot;;
public static final String FORWARD_PATH_INFO_ATTRIBUTE = &quot;javax.servlet.forward.path_info&quot;;
public static final String FORWARD_QUERY_STRING_ATTRIBUTE = &quot;javax.servlet.forward.query_string&quot;;
/**
* Default character encoding to use when &lt;code&gt;request.getCharacterEncoding&lt;/code&gt;
* returns &lt;code&gt;null&lt;/code&gt;, according to the Servlet spec.
*
* @see javax.servlet.ServletRequest#getCharacterEncoding
*/
public static final String DEFAULT_CHARACTER_ENCODING = &quot;ISO-8859-1&quot;;
/**
* Return the path within the web application for the given request.
* Detects include request URL if called within a RequestDispatcher include.
* &lt;p/&gt;
* For example, for a request to URL
* &lt;p/&gt;
* &lt;code&gt;http://www.somehost.com/myapp/my/url.jsp&lt;/code&gt;,
* &lt;p/&gt;
* for an application deployed to &lt;code&gt;/mayapp&lt;/code&gt; (the application's context path), this method would return
* &lt;p/&gt;
* &lt;code&gt;/my/url.jsp&lt;/code&gt;.
*
* @param request current HTTP request
* @return the path within the web application
*/
public static String getPathWithinApplication(HttpServletRequest request) {
<span class="fc" id="L111"> String contextPath = getContextPath(request);</span>
<span class="fc" id="L112"> String requestUri = getRequestUri(request);</span>
<span class="fc bfc" id="L113" title="All 2 branches covered."> if (StringUtils.startsWithIgnoreCase(requestUri, contextPath)) {</span>
// Normal case: URI contains context path.
<span class="fc" id="L115"> String path = requestUri.substring(contextPath.length());</span>
<span class="pc bpc" id="L116" title="1 of 2 branches missed."> return (StringUtils.hasText(path) ? path : &quot;/&quot;);</span>
} else {
// Special case: rather unusual.
<span class="fc" id="L119"> return requestUri;</span>
}
}
/**
* Return the request URI for the given request, detecting an include request
* URL if called within a RequestDispatcher include.
* &lt;p&gt;As the value returned by &lt;code&gt;request.getRequestURI()&lt;/code&gt; is &lt;i&gt;not&lt;/i&gt;
* decoded by the servlet container, this method will decode it.
* &lt;p&gt;The URI that the web container resolves &lt;i&gt;should&lt;/i&gt; be correct, but some
* containers like JBoss/Jetty incorrectly include &quot;;&quot; strings like &quot;;jsessionid&quot;
* in the URI. This method cuts off such incorrect appendices.
*
* @param request current HTTP request
* @return the request URI
*/
public static String getRequestUri(HttpServletRequest request) {
<span class="fc" id="L136"> String uri = (String) request.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE);</span>
<span class="fc bfc" id="L137" title="All 2 branches covered."> if (uri == null) {</span>
<span class="fc" id="L138"> uri = request.getRequestURI();</span>
}
<span class="fc" id="L140"> return normalize(decodeAndCleanUriString(request, uri));</span>
}
/**
* Normalize a relative URI path that may have relative values (&quot;/./&quot;,
* &quot;/../&quot;, and so on ) it it. &lt;strong&gt;WARNING&lt;/strong&gt; - This method is
* useful only for normalizing application-generated paths. It does not
* try to perform security checks for malicious input.
* Normalize operations were was happily taken from org.apache.catalina.util.RequestUtil in
* Tomcat trunk, r939305
*
* @param path Relative path to be normalized
* @return normalized path
*/
public static String normalize(String path) {
<span class="fc" id="L155"> return normalize(path, true);</span>
}
/**
* Normalize a relative URI path that may have relative values (&quot;/./&quot;,
* &quot;/../&quot;, and so on ) it it. &lt;strong&gt;WARNING&lt;/strong&gt; - This method is
* useful only for normalizing application-generated paths. It does not
* try to perform security checks for malicious input.
* Normalize operations were was happily taken from org.apache.catalina.util.RequestUtil in
* Tomcat trunk, r939305
*
* @param path Relative path to be normalized
* @param replaceBackSlash Should '\\' be replaced with '/'
* @return normalized path
*/
private static String normalize(String path, boolean replaceBackSlash) {
<span class="pc bpc" id="L172" title="1 of 2 branches missed."> if (path == null)</span>
<span class="nc" id="L173"> return null;</span>
// Create a place for the normalized path
<span class="fc" id="L176"> String normalized = path;</span>
<span class="pc bpc" id="L178" title="2 of 4 branches missed."> if (replaceBackSlash &amp;&amp; normalized.indexOf('\\') &gt;= 0)</span>
<span class="nc" id="L179"> normalized = normalized.replace('\\', '/');</span>
<span class="pc bpc" id="L181" title="1 of 2 branches missed."> if (normalized.equals(&quot;/.&quot;))</span>
<span class="nc" id="L182"> return &quot;/&quot;;</span>
// Add a leading &quot;/&quot; if necessary
<span class="fc bfc" id="L185" title="All 2 branches covered."> if (!normalized.startsWith(&quot;/&quot;))</span>
<span class="fc" id="L186"> normalized = &quot;/&quot; + normalized;</span>
// Resolve occurrences of &quot;//&quot; in the normalized path
while (true) {
<span class="fc" id="L190"> int index = normalized.indexOf(&quot;//&quot;);</span>
<span class="fc bfc" id="L191" title="All 2 branches covered."> if (index &lt; 0)</span>
<span class="fc" id="L192"> break;</span>
<span class="fc" id="L193"> normalized = normalized.substring(0, index) +</span>
<span class="fc" id="L194"> normalized.substring(index + 1);</span>
<span class="fc" id="L195"> }</span>
// Resolve occurrences of &quot;/./&quot; in the normalized path
while (true) {
<span class="fc" id="L199"> int index = normalized.indexOf(&quot;/./&quot;);</span>
<span class="fc bfc" id="L200" title="All 2 branches covered."> if (index &lt; 0)</span>
<span class="fc" id="L201"> break;</span>
<span class="fc" id="L202"> normalized = normalized.substring(0, index) +</span>
<span class="fc" id="L203"> normalized.substring(index + 2);</span>
<span class="fc" id="L204"> }</span>
// Resolve occurrences of &quot;/../&quot; in the normalized path
while (true) {
<span class="fc" id="L208"> int index = normalized.indexOf(&quot;/../&quot;);</span>
<span class="fc bfc" id="L209" title="All 2 branches covered."> if (index &lt; 0)</span>
<span class="fc" id="L210"> break;</span>
<span class="fc bfc" id="L211" title="All 2 branches covered."> if (index == 0)</span>
<span class="fc" id="L212"> return (null); // Trying to go outside our context</span>
<span class="fc" id="L213"> int index2 = normalized.lastIndexOf('/', index - 1);</span>
<span class="fc" id="L214"> normalized = normalized.substring(0, index2) +</span>
<span class="fc" id="L215"> normalized.substring(index + 3);</span>
<span class="fc" id="L216"> }</span>
// Return the normalized path that we have completed
<span class="fc" id="L219"> return (normalized);</span>
}
/**
* Decode the supplied URI string and strips any extraneous portion after a ';'.
*
* @param request the incoming HttpServletRequest
* @param uri the application's URI string
* @return the supplied URI string stripped of any extraneous portion after a ';'.
*/
private static String decodeAndCleanUriString(HttpServletRequest request, String uri) {
<span class="fc" id="L232"> uri = decodeRequestString(request, uri);</span>
<span class="fc" id="L233"> int semicolonIndex = uri.indexOf(';');</span>
<span class="pc bpc" id="L234" title="1 of 2 branches missed."> return (semicolonIndex != -1 ? uri.substring(0, semicolonIndex) : uri);</span>
}
/**
* Return the context path for the given request, detecting an include request
* URL if called within a RequestDispatcher include.
* &lt;p&gt;As the value returned by &lt;code&gt;request.getContextPath()&lt;/code&gt; is &lt;i&gt;not&lt;/i&gt;
* decoded by the servlet container, this method will decode it.
*
* @param request current HTTP request
* @return the context path
*/
public static String getContextPath(HttpServletRequest request) {
<span class="fc" id="L247"> String contextPath = (String) request.getAttribute(INCLUDE_CONTEXT_PATH_ATTRIBUTE);</span>
<span class="fc bfc" id="L248" title="All 2 branches covered."> if (contextPath == null) {</span>
<span class="fc" id="L249"> contextPath = request.getContextPath();</span>
}
<span class="fc" id="L251"> contextPath = normalize(decodeRequestString(request, contextPath));</span>
<span class="fc bfc" id="L252" title="All 2 branches covered."> if (&quot;/&quot;.equals(contextPath)) {</span>
// the normalize method will return a &quot;/&quot; and includes on Jetty, will also be a &quot;/&quot;.
<span class="fc" id="L254"> contextPath = &quot;&quot;;</span>
}
<span class="fc" id="L256"> return contextPath;</span>
}
/**
* Find the Shiro {@link WebEnvironment} for this web application, which is typically loaded via the
* {@link org.apache.shiro.web.env.EnvironmentLoaderListener}.
* &lt;p/&gt;
* This implementation rethrows an exception that happened on environment startup to differentiate between a failed
* environment startup and no environment at all.
*
* @param sc ServletContext to find the web application context for
* @return the root WebApplicationContext for this web app
* @throws IllegalStateException if the root WebApplicationContext could not be found
* @see org.apache.shiro.web.env.EnvironmentLoader#ENVIRONMENT_ATTRIBUTE_KEY
* @since 1.2
*/
public static WebEnvironment getRequiredWebEnvironment(ServletContext sc)
throws IllegalStateException {
<span class="fc" id="L275"> WebEnvironment we = getWebEnvironment(sc);</span>
<span class="pc bpc" id="L276" title="1 of 2 branches missed."> if (we == null) {</span>
<span class="nc" id="L277"> throw new IllegalStateException(&quot;No WebEnvironment found: no EnvironmentLoaderListener registered?&quot;);</span>
}
<span class="fc" id="L279"> return we;</span>
}
/**
* Find the Shiro {@link WebEnvironment} for this web application, which is typically loaded via
* {@link org.apache.shiro.web.env.EnvironmentLoaderListener}.
* &lt;p/&gt;
* This implementation rethrows an exception that happened on environment startup to differentiate between a failed
* environment startup and no environment at all.
*
* @param sc ServletContext to find the web application context for
* @return the root WebApplicationContext for this web app, or &lt;code&gt;null&lt;/code&gt; if none
* @see org.apache.shiro.web.env.EnvironmentLoader#ENVIRONMENT_ATTRIBUTE_KEY
* @since 1.2
*/
public static WebEnvironment getWebEnvironment(ServletContext sc) {
<span class="fc" id="L295"> return getWebEnvironment(sc, EnvironmentLoader.ENVIRONMENT_ATTRIBUTE_KEY);</span>
}
/**
* Find the Shiro {@link WebEnvironment} for this web application.
*
* @param sc ServletContext to find the web application context for
* @param attrName the name of the ServletContext attribute to look for
* @return the desired WebEnvironment for this web app, or &lt;code&gt;null&lt;/code&gt; if none
* @since 1.2
*/
public static WebEnvironment getWebEnvironment(ServletContext sc, String attrName) {
<span class="pc bpc" id="L307" title="1 of 2 branches missed."> if (sc == null) {</span>
<span class="nc" id="L308"> throw new IllegalArgumentException(&quot;ServletContext argument must not be null.&quot;);</span>
}
<span class="fc" id="L310"> Object attr = sc.getAttribute(attrName);</span>
<span class="pc bpc" id="L311" title="1 of 2 branches missed."> if (attr == null) {</span>
<span class="nc" id="L312"> return null;</span>
}
<span class="pc bpc" id="L314" title="1 of 2 branches missed."> if (attr instanceof RuntimeException) {</span>
<span class="nc" id="L315"> throw (RuntimeException) attr;</span>
}
<span class="pc bpc" id="L317" title="1 of 2 branches missed."> if (attr instanceof Error) {</span>
<span class="nc" id="L318"> throw (Error) attr;</span>
}
<span class="pc bpc" id="L320" title="1 of 2 branches missed."> if (attr instanceof Exception) {</span>
<span class="nc" id="L321"> throw new IllegalStateException((Exception) attr);</span>
}
<span class="pc bpc" id="L323" title="1 of 2 branches missed."> if (!(attr instanceof WebEnvironment)) {</span>
<span class="nc" id="L324"> throw new IllegalStateException(&quot;Context attribute is not of type WebEnvironment: &quot; + attr);</span>
}
<span class="fc" id="L326"> return (WebEnvironment) attr;</span>
}
/**
* Decode the given source string with a URLDecoder. The encoding will be taken
* from the request, falling back to the default &quot;ISO-8859-1&quot;.
* &lt;p&gt;The default implementation uses &lt;code&gt;URLDecoder.decode(input, enc)&lt;/code&gt;.
*
* @param request current HTTP request
* @param source the String to decode
* @return the decoded String
* @see #DEFAULT_CHARACTER_ENCODING
* @see javax.servlet.ServletRequest#getCharacterEncoding
* @see java.net.URLDecoder#decode(String, String)
* @see java.net.URLDecoder#decode(String)
*/
@SuppressWarnings({&quot;deprecation&quot;})
public static String decodeRequestString(HttpServletRequest request, String source) {
<span class="fc" id="L345"> String enc = determineEncoding(request);</span>
try {
<span class="fc" id="L347"> return URLDecoder.decode(source, enc);</span>
<span class="nc" id="L348"> } catch (UnsupportedEncodingException ex) {</span>
<span class="nc bnc" id="L349" title="All 2 branches missed."> if (log.isWarnEnabled()) {</span>
<span class="nc" id="L350"> log.warn(&quot;Could not decode request string [&quot; + source + &quot;] with encoding '&quot; + enc +</span>
<span class="nc" id="L351"> &quot;': falling back to platform default encoding; exception message: &quot; + ex.getMessage());</span>
}
<span class="nc" id="L353"> return URLDecoder.decode(source);</span>
}
}
/**
* Determine the encoding for the given request.
* Can be overridden in subclasses.
* &lt;p&gt;The default implementation checks the request's
* {@link ServletRequest#getCharacterEncoding() character encoding}, and if that
* &lt;code&gt;null&lt;/code&gt;, falls back to the {@link #DEFAULT_CHARACTER_ENCODING}.
*
* @param request current HTTP request
* @return the encoding for the request (never &lt;code&gt;null&lt;/code&gt;)
* @see javax.servlet.ServletRequest#getCharacterEncoding()
*/
protected static String determineEncoding(HttpServletRequest request) {
<span class="fc" id="L369"> String enc = request.getCharacterEncoding();</span>
<span class="fc bfc" id="L370" title="All 2 branches covered."> if (enc == null) {</span>
<span class="fc" id="L371"> enc = DEFAULT_CHARACTER_ENCODING;</span>
}
<span class="fc" id="L373"> return enc;</span>
}
/*
* Returns {@code true} IFF the specified {@code SubjectContext}:
* &lt;ol&gt;
* &lt;li&gt;A {@link WebSubjectContext} instance&lt;/li&gt;
* &lt;li&gt;The {@code WebSubjectContext}'s request/response pair are not null&lt;/li&gt;
* &lt;li&gt;The request is an {@link HttpServletRequest} instance&lt;/li&gt;
* &lt;li&gt;The response is an {@link HttpServletResponse} instance&lt;/li&gt;
* &lt;/ol&gt;
*
* @param context the SubjectContext to check to see if it is HTTP compatible.
* @return {@code true} IFF the specified context has HTTP request/response objects, {@code false} otherwise.
* @since 1.0
*/
public static boolean isWeb(Object requestPairSource) {
<span class="fc bfc" id="L391" title="All 4 branches covered."> return requestPairSource instanceof RequestPairSource &amp;&amp; isWeb((RequestPairSource) requestPairSource);</span>
}
public static boolean isHttp(Object requestPairSource) {
<span class="pc bpc" id="L395" title="1 of 4 branches missed."> return requestPairSource instanceof RequestPairSource &amp;&amp; isHttp((RequestPairSource) requestPairSource);</span>
}
public static ServletRequest getRequest(Object requestPairSource) {
<span class="pc bpc" id="L399" title="1 of 2 branches missed."> if (requestPairSource instanceof RequestPairSource) {</span>
<span class="fc" id="L400"> return ((RequestPairSource) requestPairSource).getServletRequest();</span>
}
<span class="nc" id="L402"> return null;</span>
}
public static ServletResponse getResponse(Object requestPairSource) {
<span class="pc bpc" id="L406" title="1 of 2 branches missed."> if (requestPairSource instanceof RequestPairSource) {</span>
<span class="fc" id="L407"> return ((RequestPairSource) requestPairSource).getServletResponse();</span>
}
<span class="nc" id="L409"> return null;</span>
}
public static HttpServletRequest getHttpRequest(Object requestPairSource) {
<span class="fc" id="L413"> ServletRequest request = getRequest(requestPairSource);</span>
<span class="pc bpc" id="L414" title="1 of 2 branches missed."> if (request instanceof HttpServletRequest) {</span>
<span class="fc" id="L415"> return (HttpServletRequest) request;</span>
}
<span class="nc" id="L417"> return null;</span>
}
public static HttpServletResponse getHttpResponse(Object requestPairSource) {
<span class="fc" id="L421"> ServletResponse response = getResponse(requestPairSource);</span>
<span class="pc bpc" id="L422" title="1 of 2 branches missed."> if (response instanceof HttpServletResponse) {</span>
<span class="fc" id="L423"> return (HttpServletResponse) response;</span>
}
<span class="nc" id="L425"> return null;</span>
}
private static boolean isWeb(RequestPairSource source) {
<span class="fc" id="L429"> ServletRequest request = source.getServletRequest();</span>
<span class="fc" id="L430"> ServletResponse response = source.getServletResponse();</span>
<span class="pc bpc" id="L431" title="1 of 4 branches missed."> return request != null &amp;&amp; response != null;</span>
}
private static boolean isHttp(RequestPairSource source) {
<span class="fc" id="L435"> ServletRequest request = source.getServletRequest();</span>
<span class="fc" id="L436"> ServletResponse response = source.getServletResponse();</span>
<span class="pc bpc" id="L437" title="2 of 4 branches missed."> return request instanceof HttpServletRequest &amp;&amp; response instanceof HttpServletResponse;</span>
}
/**
* Returns {@code true} if a session is allowed to be created for a subject-associated request, {@code false}
* otherwise.
* &lt;p/&gt;
* &lt;b&gt;This method exists for Shiro's internal framework needs and should never be called by Shiro end-users. It
* could be changed/removed at any time.&lt;/b&gt;
*
* @param requestPairSource a {@link RequestPairSource} instance, almost always a
* {@link org.apache.shiro.web.subject.WebSubject WebSubject} instance.
* @return {@code true} if a session is allowed to be created for a subject-associated request, {@code false}
* otherwise.
*/
public static boolean _isSessionCreationEnabled(Object requestPairSource) {
<span class="fc bfc" id="L453" title="All 2 branches covered."> if (requestPairSource instanceof RequestPairSource) {</span>
<span class="fc" id="L454"> RequestPairSource source = (RequestPairSource) requestPairSource;</span>
<span class="fc" id="L455"> return _isSessionCreationEnabled(source.getServletRequest());</span>
}
<span class="fc" id="L457"> return true; //by default</span>
}
/**
* Returns {@code true} if a session is allowed to be created for a subject-associated request, {@code false}
* otherwise.
* &lt;p/&gt;
* &lt;b&gt;This method exists for Shiro's internal framework needs and should never be called by Shiro end-users. It
* could be changed/removed at any time.&lt;/b&gt;
*
* @param request incoming servlet request.
* @return {@code true} if a session is allowed to be created for a subject-associated request, {@code false}
* otherwise.
*/
public static boolean _isSessionCreationEnabled(ServletRequest request) {
<span class="pc bpc" id="L472" title="1 of 2 branches missed."> if (request != null) {</span>
<span class="fc" id="L473"> Object val = request.getAttribute(DefaultSubjectContext.SESSION_CREATION_ENABLED);</span>
<span class="fc bfc" id="L474" title="All 4 branches covered."> if (val != null &amp;&amp; val instanceof Boolean) {</span>
<span class="fc" id="L475"> return (Boolean) val;</span>
}
}
<span class="fc" id="L478"> return true; //by default</span>
}
/**
* A convenience method that merely casts the incoming &lt;code&gt;ServletRequest&lt;/code&gt; to an
* &lt;code&gt;HttpServletRequest&lt;/code&gt;:
* &lt;p/&gt;
* &lt;code&gt;return (HttpServletRequest)request;&lt;/code&gt;
* &lt;p/&gt;
* Logic could be changed in the future for logging or throwing an meaningful exception in
* non HTTP request environments (e.g. Portlet API).
*
* @param request the incoming ServletRequest
* @return the &lt;code&gt;request&lt;/code&gt; argument casted to an &lt;code&gt;HttpServletRequest&lt;/code&gt;.
*/
public static HttpServletRequest toHttp(ServletRequest request) {
<span class="fc" id="L494"> return (HttpServletRequest) request;</span>
}
/**
* A convenience method that merely casts the incoming &lt;code&gt;ServletResponse&lt;/code&gt; to an
* &lt;code&gt;HttpServletResponse&lt;/code&gt;:
* &lt;p/&gt;
* &lt;code&gt;return (HttpServletResponse)response;&lt;/code&gt;
* &lt;p/&gt;
* Logic could be changed in the future for logging or throwing an meaningful exception in
* non HTTP request environments (e.g. Portlet API).
*
* @param response the outgoing ServletResponse
* @return the &lt;code&gt;response&lt;/code&gt; argument casted to an &lt;code&gt;HttpServletResponse&lt;/code&gt;.
*/
public static HttpServletResponse toHttp(ServletResponse response) {
<span class="fc" id="L510"> return (HttpServletResponse) response;</span>
}
/**
* Redirects the current request to a new URL based on the given parameters.
*
* @param request the servlet request.
* @param response the servlet response.
* @param url the URL to redirect the user to.
* @param queryParams a map of parameters that should be set as request parameters for the new request.
* @param contextRelative true if the URL is relative to the servlet context path, or false if the URL is absolute.
* @param http10Compatible whether to stay compatible with HTTP 1.0 clients.
* @throws java.io.IOException if thrown by response methods.
*/
public static void issueRedirect(ServletRequest request, ServletResponse response, String url, Map queryParams, boolean contextRelative, boolean http10Compatible) throws IOException {
<span class="fc" id="L525"> RedirectView view = new RedirectView(url, contextRelative, http10Compatible);</span>
<span class="fc" id="L526"> view.renderMergedOutputModel(queryParams, toHttp(request), toHttp(response));</span>
<span class="fc" id="L527"> }</span>
/**
* Redirects the current request to a new URL based on the given parameters and default values
* for unspecified parameters.
*
* @param request the servlet request.
* @param response the servlet response.
* @param url the URL to redirect the user to.
* @throws java.io.IOException if thrown by response methods.
*/
public static void issueRedirect(ServletRequest request, ServletResponse response, String url) throws IOException {
<span class="fc" id="L539"> issueRedirect(request, response, url, null, true, true);</span>
<span class="fc" id="L540"> }</span>
/**
* Redirects the current request to a new URL based on the given parameters and default values
* for unspecified parameters.
*
* @param request the servlet request.
* @param response the servlet response.
* @param url the URL to redirect the user to.
* @param queryParams a map of parameters that should be set as request parameters for the new request.
* @throws java.io.IOException if thrown by response methods.
*/
public static void issueRedirect(ServletRequest request, ServletResponse response, String url, Map queryParams) throws IOException {
<span class="nc" id="L553"> issueRedirect(request, response, url, queryParams, true, true);</span>
<span class="nc" id="L554"> }</span>
/**
* Redirects the current request to a new URL based on the given parameters and default values
* for unspecified parameters.
*
* @param request the servlet request.
* @param response the servlet response.
* @param url the URL to redirect the user to.
* @param queryParams a map of parameters that should be set as request parameters for the new request.
* @param contextRelative true if the URL is relative to the servlet context path, or false if the URL is absolute.
* @throws java.io.IOException if thrown by response methods.
*/
public static void issueRedirect(ServletRequest request, ServletResponse response, String url, Map queryParams, boolean contextRelative) throws IOException {
<span class="nc" id="L568"> issueRedirect(request, response, url, queryParams, contextRelative, true);</span>
<span class="nc" id="L569"> }</span>
/**
* &lt;p&gt;Checks to see if a request param is considered true using a loose matching strategy for
* general values that indicate that something is true or enabled, etc.&lt;/p&gt;
* &lt;p/&gt;
* &lt;p&gt;Values that are considered &quot;true&quot; include (case-insensitive): true, t, 1, enabled, y, yes, on.&lt;/p&gt;
*
* @param request the servlet request
* @param paramName @return true if the param value is considered true or false if it isn't.
* @return true if the given parameter is considered &quot;true&quot; - false otherwise.
*/
public static boolean isTrue(ServletRequest request, String paramName) {
<span class="nc" id="L582"> String value = getCleanParam(request, paramName);</span>
<span class="nc bnc" id="L583" title="All 2 branches missed."> return value != null &amp;&amp;</span>
<span class="nc bnc" id="L584" title="All 2 branches missed."> (value.equalsIgnoreCase(&quot;true&quot;) ||</span>
<span class="nc bnc" id="L585" title="All 2 branches missed."> value.equalsIgnoreCase(&quot;t&quot;) ||</span>
<span class="nc bnc" id="L586" title="All 2 branches missed."> value.equalsIgnoreCase(&quot;1&quot;) ||</span>
<span class="nc bnc" id="L587" title="All 2 branches missed."> value.equalsIgnoreCase(&quot;enabled&quot;) ||</span>
<span class="nc bnc" id="L588" title="All 2 branches missed."> value.equalsIgnoreCase(&quot;y&quot;) ||</span>
<span class="nc bnc" id="L589" title="All 2 branches missed."> value.equalsIgnoreCase(&quot;yes&quot;) ||</span>
<span class="nc bnc" id="L590" title="All 2 branches missed."> value.equalsIgnoreCase(&quot;on&quot;));</span>
}
/**
* Convenience method that returns a request parameter value, first running it through
* {@link StringUtils#clean(String)}.
*
* @param request the servlet request.
* @param paramName the parameter name.
* @return the clean param value, or null if the param does not exist or is empty.
*/
public static String getCleanParam(ServletRequest request, String paramName) {
<span class="nc" id="L602"> return StringUtils.clean(request.getParameter(paramName));</span>
}
public static void saveRequest(ServletRequest request) {
<span class="nc" id="L606"> Subject subject = SecurityUtils.getSubject();</span>
<span class="nc" id="L607"> Session session = subject.getSession();</span>
<span class="nc" id="L608"> HttpServletRequest httpRequest = toHttp(request);</span>
<span class="nc" id="L609"> SavedRequest savedRequest = new SavedRequest(httpRequest);</span>
<span class="nc" id="L610"> session.setAttribute(SAVED_REQUEST_KEY, savedRequest);</span>
<span class="nc" id="L611"> }</span>
public static SavedRequest getAndClearSavedRequest(ServletRequest request) {
<span class="nc" id="L614"> SavedRequest savedRequest = getSavedRequest(request);</span>
<span class="nc bnc" id="L615" title="All 2 branches missed."> if (savedRequest != null) {</span>
<span class="nc" id="L616"> Subject subject = SecurityUtils.getSubject();</span>
<span class="nc" id="L617"> Session session = subject.getSession();</span>
<span class="nc" id="L618"> session.removeAttribute(SAVED_REQUEST_KEY);</span>
}
<span class="nc" id="L620"> return savedRequest;</span>
}
public static SavedRequest getSavedRequest(ServletRequest request) {
<span class="nc" id="L624"> SavedRequest savedRequest = null;</span>
<span class="nc" id="L625"> Subject subject = SecurityUtils.getSubject();</span>
<span class="nc" id="L626"> Session session = subject.getSession(false);</span>
<span class="nc bnc" id="L627" title="All 2 branches missed."> if (session != null) {</span>
<span class="nc" id="L628"> savedRequest = (SavedRequest) session.getAttribute(SAVED_REQUEST_KEY);</span>
}
<span class="nc" id="L630"> return savedRequest;</span>
}
/**
* Redirects the to the request url from a previously
* {@link #saveRequest(javax.servlet.ServletRequest) saved} request, or if there is no saved request, redirects the
* end user to the specified {@code fallbackUrl}. If there is no saved request or fallback url, this method
* throws an {@link IllegalStateException}.
* &lt;p/&gt;
* This method is primarily used to support a common login scenario - if an unauthenticated user accesses a
* page that requires authentication, it is expected that request is
* {@link #saveRequest(javax.servlet.ServletRequest) saved} first and then redirected to the login page. Then,
* after a successful login, this method can be called to redirect them back to their originally requested URL, a
* nice usability feature.
*
* @param request the incoming request
* @param response the outgoing response
* @param fallbackUrl the fallback url to redirect to if there is no saved request available.
* @throws IllegalStateException if there is no saved request and the {@code fallbackUrl} is {@code null}.
* @throws IOException if there is an error redirecting
* @since 1.0
*/
public static void redirectToSavedRequest(ServletRequest request, ServletResponse response, String fallbackUrl)
throws IOException {
<span class="nc" id="L654"> String successUrl = null;</span>
<span class="nc" id="L655"> boolean contextRelative = true;</span>
<span class="nc" id="L656"> SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);</span>
<span class="nc bnc" id="L657" title="All 4 branches missed."> if (savedRequest != null &amp;&amp; savedRequest.getMethod().equalsIgnoreCase(AccessControlFilter.GET_METHOD)) {</span>
<span class="nc" id="L658"> successUrl = savedRequest.getRequestUrl();</span>
<span class="nc" id="L659"> contextRelative = false;</span>
}
<span class="nc bnc" id="L662" title="All 2 branches missed."> if (successUrl == null) {</span>
<span class="nc" id="L663"> successUrl = fallbackUrl;</span>
}
<span class="nc bnc" id="L666" title="All 2 branches missed."> if (successUrl == null) {</span>
<span class="nc" id="L667"> throw new IllegalStateException(&quot;Success URL not available via saved request or via the &quot; +</span>
&quot;successUrlFallback method parameter. One of these must be non-null for &quot; +
&quot;issueSuccessRedirect() to work.&quot;);
}
<span class="nc" id="L672"> WebUtils.issueRedirect(request, response, successUrl, null, contextRelative);</span>
<span class="nc" id="L673"> }</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>