| <?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 :: Web</a> > <a href="index.source.html" class="el_package">org.apache.shiro.web.util</a> > <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 |
| * "License"); 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 |
| * "AS IS" 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. |
| * <p/> |
| * 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() + "_SHIRO_THREAD_CONTEXT_KEY";</span> |
| <span class="fc" id="L57"> public static final String SERVLET_RESPONSE_KEY = ServletResponse.class.getName() + "_SHIRO_THREAD_CONTEXT_KEY";</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 = "shiroSavedRequest"; |
| |
| /** |
| * Standard Servlet 2.3+ spec request attributes for include URI and paths. |
| * <p>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 = "javax.servlet.include.request_uri"; |
| public static final String INCLUDE_CONTEXT_PATH_ATTRIBUTE = "javax.servlet.include.context_path"; |
| public static final String INCLUDE_SERVLET_PATH_ATTRIBUTE = "javax.servlet.include.servlet_path"; |
| public static final String INCLUDE_PATH_INFO_ATTRIBUTE = "javax.servlet.include.path_info"; |
| public static final String INCLUDE_QUERY_STRING_ATTRIBUTE = "javax.servlet.include.query_string"; |
| |
| /** |
| * Standard Servlet 2.4+ spec request attributes for forward URI and paths. |
| * <p>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 = "javax.servlet.forward.request_uri"; |
| public static final String FORWARD_CONTEXT_PATH_ATTRIBUTE = "javax.servlet.forward.context_path"; |
| public static final String FORWARD_SERVLET_PATH_ATTRIBUTE = "javax.servlet.forward.servlet_path"; |
| public static final String FORWARD_PATH_INFO_ATTRIBUTE = "javax.servlet.forward.path_info"; |
| public static final String FORWARD_QUERY_STRING_ATTRIBUTE = "javax.servlet.forward.query_string"; |
| |
| /** |
| * Default character encoding to use when <code>request.getCharacterEncoding</code> |
| * returns <code>null</code>, according to the Servlet spec. |
| * |
| * @see javax.servlet.ServletRequest#getCharacterEncoding |
| */ |
| public static final String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1"; |
| |
| /** |
| * Return the path within the web application for the given request. |
| * Detects include request URL if called within a RequestDispatcher include. |
| * <p/> |
| * For example, for a request to URL |
| * <p/> |
| * <code>http://www.somehost.com/myapp/my/url.jsp</code>, |
| * <p/> |
| * for an application deployed to <code>/mayapp</code> (the application's context path), this method would return |
| * <p/> |
| * <code>/my/url.jsp</code>. |
| * |
| * @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="pc bpc" id="L113" title="1 of 2 branches missed."> 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 : "/");</span> |
| } else { |
| // Special case: rather unusual. |
| <span class="nc" id="L119"> return requestUri;</span> |
| } |
| } |
| |
| /** |
| * Return the request URI for the given request, detecting an include request |
| * URL if called within a RequestDispatcher include. |
| * <p>As the value returned by <code>request.getRequestURI()</code> is <i>not</i> |
| * decoded by the servlet container, this method will decode it. |
| * <p>The URI that the web container resolves <i>should</i> be correct, but some |
| * containers like JBoss/Jetty incorrectly include ";" strings like ";jsessionid" |
| * 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="pc bpc" id="L137" title="1 of 2 branches missed."> 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 ("/./", |
| * "/../", and so on ) it it. <strong>WARNING</strong> - 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 ("/./", |
| * "/../", and so on ) it it. <strong>WARNING</strong> - 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 && normalized.indexOf('\\') >= 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("/."))</span> |
| <span class="nc" id="L182"> return "/";</span> |
| |
| // Add a leading "/" if necessary |
| <span class="pc bpc" id="L185" title="1 of 2 branches missed."> if (!normalized.startsWith("/"))</span> |
| <span class="nc" id="L186"> normalized = "/" + normalized;</span> |
| |
| // Resolve occurrences of "//" in the normalized path |
| while (true) { |
| <span class="fc" id="L190"> int index = normalized.indexOf("//");</span> |
| <span class="pc bpc" id="L191" title="1 of 2 branches missed."> if (index < 0)</span> |
| <span class="fc" id="L192"> break;</span> |
| <span class="nc" id="L193"> normalized = normalized.substring(0, index) +</span> |
| <span class="nc" id="L194"> normalized.substring(index + 1);</span> |
| <span class="nc" id="L195"> }</span> |
| |
| // Resolve occurrences of "/./" in the normalized path |
| while (true) { |
| <span class="fc" id="L199"> int index = normalized.indexOf("/./");</span> |
| <span class="fc bfc" id="L200" title="All 2 branches covered."> if (index < 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 "/../" in the normalized path |
| while (true) { |
| <span class="fc" id="L208"> int index = normalized.indexOf("/../");</span> |
| <span class="fc bfc" id="L209" title="All 2 branches covered."> if (index < 0)</span> |
| <span class="fc" id="L210"> break;</span> |
| <span class="pc bpc" id="L211" title="1 of 2 branches missed."> if (index == 0)</span> |
| <span class="nc" 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. |
| * <p>As the value returned by <code>request.getContextPath()</code> is <i>not</i> |
| * 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="pc bpc" id="L248" title="1 of 2 branches missed."> if (contextPath == null) {</span> |
| <span class="fc" id="L249"> contextPath = request.getContextPath();</span> |
| } |
| <span class="fc bfc" id="L251" title="All 2 branches covered."> if ("/".equals(contextPath)) {</span> |
| // Invalid case, but happens for includes on Jetty: silently adapt it. |
| <span class="fc" id="L253"> contextPath = "";</span> |
| } |
| <span class="fc" id="L255"> return decodeRequestString(request, contextPath);</span> |
| } |
| |
| /** |
| * Find the Shiro {@link WebEnvironment} for this web application, which is typically loaded via the |
| * {@link org.apache.shiro.web.env.EnvironmentLoaderListener}. |
| * <p/> |
| * 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="L274"> WebEnvironment we = getWebEnvironment(sc);</span> |
| <span class="pc bpc" id="L275" title="1 of 2 branches missed."> if (we == null) {</span> |
| <span class="nc" id="L276"> throw new IllegalStateException("No WebEnvironment found: no EnvironmentLoaderListener registered?");</span> |
| } |
| <span class="fc" id="L278"> return we;</span> |
| } |
| |
| /** |
| * Find the Shiro {@link WebEnvironment} for this web application, which is typically loaded via |
| * {@link org.apache.shiro.web.env.EnvironmentLoaderListener}. |
| * <p/> |
| * 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 <code>null</code> 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="L294"> 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 <code>null</code> if none |
| * @since 1.2 |
| */ |
| public static WebEnvironment getWebEnvironment(ServletContext sc, String attrName) { |
| <span class="pc bpc" id="L306" title="1 of 2 branches missed."> if (sc == null) {</span> |
| <span class="nc" id="L307"> throw new IllegalArgumentException("ServletContext argument must not be null.");</span> |
| } |
| <span class="fc" id="L309"> Object attr = sc.getAttribute(attrName);</span> |
| <span class="pc bpc" id="L310" title="1 of 2 branches missed."> if (attr == null) {</span> |
| <span class="nc" id="L311"> return null;</span> |
| } |
| <span class="pc bpc" id="L313" title="1 of 2 branches missed."> if (attr instanceof RuntimeException) {</span> |
| <span class="nc" id="L314"> throw (RuntimeException) attr;</span> |
| } |
| <span class="pc bpc" id="L316" title="1 of 2 branches missed."> if (attr instanceof Error) {</span> |
| <span class="nc" id="L317"> throw (Error) attr;</span> |
| } |
| <span class="pc bpc" id="L319" title="1 of 2 branches missed."> if (attr instanceof Exception) {</span> |
| <span class="nc" id="L320"> throw new IllegalStateException((Exception) attr);</span> |
| } |
| <span class="pc bpc" id="L322" title="1 of 2 branches missed."> if (!(attr instanceof WebEnvironment)) {</span> |
| <span class="nc" id="L323"> throw new IllegalStateException("Context attribute is not of type WebEnvironment: " + attr);</span> |
| } |
| <span class="fc" id="L325"> 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 "ISO-8859-1". |
| * <p>The default implementation uses <code>URLDecoder.decode(input, enc)</code>. |
| * |
| * @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({"deprecation"}) |
| public static String decodeRequestString(HttpServletRequest request, String source) { |
| <span class="fc" id="L344"> String enc = determineEncoding(request);</span> |
| try { |
| <span class="fc" id="L346"> return URLDecoder.decode(source, enc);</span> |
| <span class="nc" id="L347"> } catch (UnsupportedEncodingException ex) {</span> |
| <span class="nc bnc" id="L348" title="All 2 branches missed."> if (log.isWarnEnabled()) {</span> |
| <span class="nc" id="L349"> log.warn("Could not decode request string [" + source + "] with encoding '" + enc +</span> |
| <span class="nc" id="L350"> "': falling back to platform default encoding; exception message: " + ex.getMessage());</span> |
| } |
| <span class="nc" id="L352"> return URLDecoder.decode(source);</span> |
| } |
| } |
| |
| /** |
| * Determine the encoding for the given request. |
| * Can be overridden in subclasses. |
| * <p>The default implementation checks the request's |
| * {@link ServletRequest#getCharacterEncoding() character encoding}, and if that |
| * <code>null</code>, falls back to the {@link #DEFAULT_CHARACTER_ENCODING}. |
| * |
| * @param request current HTTP request |
| * @return the encoding for the request (never <code>null</code>) |
| * @see javax.servlet.ServletRequest#getCharacterEncoding() |
| */ |
| protected static String determineEncoding(HttpServletRequest request) { |
| <span class="fc" id="L368"> String enc = request.getCharacterEncoding();</span> |
| <span class="pc bpc" id="L369" title="1 of 2 branches missed."> if (enc == null) {</span> |
| <span class="fc" id="L370"> enc = DEFAULT_CHARACTER_ENCODING;</span> |
| } |
| <span class="fc" id="L372"> return enc;</span> |
| } |
| |
| /* |
| * Returns {@code true} IFF the specified {@code SubjectContext}: |
| * <ol> |
| * <li>A {@link WebSubjectContext} instance</li> |
| * <li>The {@code WebSubjectContext}'s request/response pair are not null</li> |
| * <li>The request is an {@link HttpServletRequest} instance</li> |
| * <li>The response is an {@link HttpServletResponse} instance</li> |
| * </ol> |
| * |
| * @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="L390" title="All 4 branches covered."> return requestPairSource instanceof RequestPairSource && isWeb((RequestPairSource) requestPairSource);</span> |
| } |
| |
| public static boolean isHttp(Object requestPairSource) { |
| <span class="pc bpc" id="L394" title="1 of 4 branches missed."> return requestPairSource instanceof RequestPairSource && isHttp((RequestPairSource) requestPairSource);</span> |
| } |
| |
| public static ServletRequest getRequest(Object requestPairSource) { |
| <span class="pc bpc" id="L398" title="1 of 2 branches missed."> if (requestPairSource instanceof RequestPairSource) {</span> |
| <span class="fc" id="L399"> return ((RequestPairSource) requestPairSource).getServletRequest();</span> |
| } |
| <span class="nc" id="L401"> return null;</span> |
| } |
| |
| public static ServletResponse getResponse(Object requestPairSource) { |
| <span class="pc bpc" id="L405" title="1 of 2 branches missed."> if (requestPairSource instanceof RequestPairSource) {</span> |
| <span class="fc" id="L406"> return ((RequestPairSource) requestPairSource).getServletResponse();</span> |
| } |
| <span class="nc" id="L408"> return null;</span> |
| } |
| |
| public static HttpServletRequest getHttpRequest(Object requestPairSource) { |
| <span class="fc" id="L412"> ServletRequest request = getRequest(requestPairSource);</span> |
| <span class="pc bpc" id="L413" title="1 of 2 branches missed."> if (request instanceof HttpServletRequest) {</span> |
| <span class="fc" id="L414"> return (HttpServletRequest) request;</span> |
| } |
| <span class="nc" id="L416"> return null;</span> |
| } |
| |
| public static HttpServletResponse getHttpResponse(Object requestPairSource) { |
| <span class="fc" id="L420"> ServletResponse response = getResponse(requestPairSource);</span> |
| <span class="pc bpc" id="L421" title="1 of 2 branches missed."> if (response instanceof HttpServletResponse) {</span> |
| <span class="fc" id="L422"> return (HttpServletResponse) response;</span> |
| } |
| <span class="nc" id="L424"> return null;</span> |
| } |
| |
| private static boolean isWeb(RequestPairSource source) { |
| <span class="fc" id="L428"> ServletRequest request = source.getServletRequest();</span> |
| <span class="fc" id="L429"> ServletResponse response = source.getServletResponse();</span> |
| <span class="pc bpc" id="L430" title="1 of 4 branches missed."> return request != null && response != null;</span> |
| } |
| |
| private static boolean isHttp(RequestPairSource source) { |
| <span class="fc" id="L434"> ServletRequest request = source.getServletRequest();</span> |
| <span class="fc" id="L435"> ServletResponse response = source.getServletResponse();</span> |
| <span class="pc bpc" id="L436" title="2 of 4 branches missed."> return request instanceof HttpServletRequest && response instanceof HttpServletResponse;</span> |
| } |
| |
| /** |
| * Returns {@code true} if a session is allowed to be created for a subject-associated request, {@code false} |
| * otherwise. |
| * <p/> |
| * <b>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.</b> |
| * |
| * @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="L452" title="All 2 branches covered."> if (requestPairSource instanceof RequestPairSource) {</span> |
| <span class="fc" id="L453"> RequestPairSource source = (RequestPairSource) requestPairSource;</span> |
| <span class="fc" id="L454"> return _isSessionCreationEnabled(source.getServletRequest());</span> |
| } |
| <span class="fc" id="L456"> return true; //by default</span> |
| } |
| |
| /** |
| * Returns {@code true} if a session is allowed to be created for a subject-associated request, {@code false} |
| * otherwise. |
| * <p/> |
| * <b>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.</b> |
| * |
| * @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="L471" title="1 of 2 branches missed."> if (request != null) {</span> |
| <span class="fc" id="L472"> Object val = request.getAttribute(DefaultSubjectContext.SESSION_CREATION_ENABLED);</span> |
| <span class="fc bfc" id="L473" title="All 4 branches covered."> if (val != null && val instanceof Boolean) {</span> |
| <span class="fc" id="L474"> return (Boolean) val;</span> |
| } |
| } |
| <span class="fc" id="L477"> return true; //by default</span> |
| } |
| |
| /** |
| * A convenience method that merely casts the incoming <code>ServletRequest</code> to an |
| * <code>HttpServletRequest</code>: |
| * <p/> |
| * <code>return (HttpServletRequest)request;</code> |
| * <p/> |
| * 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 <code>request</code> argument casted to an <code>HttpServletRequest</code>. |
| */ |
| public static HttpServletRequest toHttp(ServletRequest request) { |
| <span class="fc" id="L493"> return (HttpServletRequest) request;</span> |
| } |
| |
| /** |
| * A convenience method that merely casts the incoming <code>ServletResponse</code> to an |
| * <code>HttpServletResponse</code>: |
| * <p/> |
| * <code>return (HttpServletResponse)response;</code> |
| * <p/> |
| * 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 <code>response</code> argument casted to an <code>HttpServletResponse</code>. |
| */ |
| public static HttpServletResponse toHttp(ServletResponse response) { |
| <span class="fc" id="L509"> 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="L524"> RedirectView view = new RedirectView(url, contextRelative, http10Compatible);</span> |
| <span class="fc" id="L525"> view.renderMergedOutputModel(queryParams, toHttp(request), toHttp(response));</span> |
| <span class="fc" id="L526"> }</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="L538"> issueRedirect(request, response, url, null, true, true);</span> |
| <span class="fc" id="L539"> }</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="L552"> issueRedirect(request, response, url, queryParams, true, true);</span> |
| <span class="nc" id="L553"> }</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="L567"> issueRedirect(request, response, url, queryParams, contextRelative, true);</span> |
| <span class="nc" id="L568"> }</span> |
| |
| /** |
| * <p>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.</p> |
| * <p/> |
| * <p>Values that are considered "true" include (case-insensitive): true, t, 1, enabled, y, yes, on.</p> |
| * |
| * @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 "true" - false otherwise. |
| */ |
| public static boolean isTrue(ServletRequest request, String paramName) { |
| <span class="nc" id="L581"> String value = getCleanParam(request, paramName);</span> |
| <span class="nc bnc" id="L582" title="All 2 branches missed."> return value != null &&</span> |
| <span class="nc bnc" id="L583" title="All 2 branches missed."> (value.equalsIgnoreCase("true") ||</span> |
| <span class="nc bnc" id="L584" title="All 2 branches missed."> value.equalsIgnoreCase("t") ||</span> |
| <span class="nc bnc" id="L585" title="All 2 branches missed."> value.equalsIgnoreCase("1") ||</span> |
| <span class="nc bnc" id="L586" title="All 2 branches missed."> value.equalsIgnoreCase("enabled") ||</span> |
| <span class="nc bnc" id="L587" title="All 2 branches missed."> value.equalsIgnoreCase("y") ||</span> |
| <span class="nc bnc" id="L588" title="All 2 branches missed."> value.equalsIgnoreCase("yes") ||</span> |
| <span class="nc bnc" id="L589" title="All 2 branches missed."> value.equalsIgnoreCase("on"));</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="L601"> return StringUtils.clean(request.getParameter(paramName));</span> |
| } |
| |
| public static void saveRequest(ServletRequest request) { |
| <span class="nc" id="L605"> Subject subject = SecurityUtils.getSubject();</span> |
| <span class="nc" id="L606"> Session session = subject.getSession();</span> |
| <span class="nc" id="L607"> HttpServletRequest httpRequest = toHttp(request);</span> |
| <span class="nc" id="L608"> SavedRequest savedRequest = new SavedRequest(httpRequest);</span> |
| <span class="nc" id="L609"> session.setAttribute(SAVED_REQUEST_KEY, savedRequest);</span> |
| <span class="nc" id="L610"> }</span> |
| |
| public static SavedRequest getAndClearSavedRequest(ServletRequest request) { |
| <span class="nc" id="L613"> SavedRequest savedRequest = getSavedRequest(request);</span> |
| <span class="nc bnc" id="L614" title="All 2 branches missed."> if (savedRequest != null) {</span> |
| <span class="nc" id="L615"> Subject subject = SecurityUtils.getSubject();</span> |
| <span class="nc" id="L616"> Session session = subject.getSession();</span> |
| <span class="nc" id="L617"> session.removeAttribute(SAVED_REQUEST_KEY);</span> |
| } |
| <span class="nc" id="L619"> return savedRequest;</span> |
| } |
| |
| public static SavedRequest getSavedRequest(ServletRequest request) { |
| <span class="nc" id="L623"> SavedRequest savedRequest = null;</span> |
| <span class="nc" id="L624"> Subject subject = SecurityUtils.getSubject();</span> |
| <span class="nc" id="L625"> Session session = subject.getSession(false);</span> |
| <span class="nc bnc" id="L626" title="All 2 branches missed."> if (session != null) {</span> |
| <span class="nc" id="L627"> savedRequest = (SavedRequest) session.getAttribute(SAVED_REQUEST_KEY);</span> |
| } |
| <span class="nc" id="L629"> 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}. |
| * <p/> |
| * 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="L653"> String successUrl = null;</span> |
| <span class="nc" id="L654"> boolean contextRelative = true;</span> |
| <span class="nc" id="L655"> SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(request);</span> |
| <span class="nc bnc" id="L656" title="All 4 branches missed."> if (savedRequest != null && savedRequest.getMethod().equalsIgnoreCase(AccessControlFilter.GET_METHOD)) {</span> |
| <span class="nc" id="L657"> successUrl = savedRequest.getRequestUrl();</span> |
| <span class="nc" id="L658"> contextRelative = false;</span> |
| } |
| |
| <span class="nc bnc" id="L661" title="All 2 branches missed."> if (successUrl == null) {</span> |
| <span class="nc" id="L662"> successUrl = fallbackUrl;</span> |
| } |
| |
| <span class="nc bnc" id="L665" title="All 2 branches missed."> if (successUrl == null) {</span> |
| <span class="nc" id="L666"> throw new IllegalStateException("Success URL not available via saved request or via the " +</span> |
| "successUrlFallback method parameter. One of these must be non-null for " + |
| "issueSuccessRedirect() to work."); |
| } |
| |
| <span class="nc" id="L671"> WebUtils.issueRedirect(request, response, successUrl, null, contextRelative);</span> |
| <span class="nc" id="L672"> }</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> |