10 changed files with 26 additions and 207 deletions
@ -1,191 +0,0 @@
@@ -1,191 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2013 the original author or authors. |
||||
* |
||||
* Licensed 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.springframework.security.config.annotation.web.builders; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.PrintWriter; |
||||
import java.io.StringWriter; |
||||
import java.util.List; |
||||
|
||||
import javax.servlet.Filter; |
||||
import javax.servlet.FilterChain; |
||||
import javax.servlet.FilterConfig; |
||||
import javax.servlet.ServletException; |
||||
import javax.servlet.ServletRequest; |
||||
import javax.servlet.ServletResponse; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletRequestWrapper; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.servlet.http.HttpSession; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.springframework.security.web.FilterChainProxy; |
||||
import org.springframework.security.web.SecurityFilterChain; |
||||
import org.springframework.security.web.util.UrlUtils; |
||||
|
||||
/** |
||||
* Spring Security debugging filter. |
||||
* <p> |
||||
* Logs information (such as session creation) to help the user understand how requests are being handled |
||||
* by Spring Security and provide them with other relevant information (such as when sessions are being created). |
||||
* |
||||
* |
||||
* @author Luke Taylor |
||||
* @author Rob Winch |
||||
* @since 3.1 |
||||
*/ |
||||
class DebugFilter implements Filter { |
||||
private static final String ALREADY_FILTERED_ATTR_NAME = DebugFilter.class.getName().concat(".FILTERED"); |
||||
|
||||
private final FilterChainProxy fcp; |
||||
private final Logger logger = new Logger(); |
||||
|
||||
public DebugFilter(FilterChainProxy fcp) { |
||||
this.fcp = fcp; |
||||
} |
||||
|
||||
public final void doFilter(ServletRequest srvltRequest, ServletResponse srvltResponse, FilterChain filterChain) |
||||
throws ServletException, IOException { |
||||
|
||||
if (!(srvltRequest instanceof HttpServletRequest) || !(srvltResponse instanceof HttpServletResponse)) { |
||||
throw new ServletException("DebugFilter just supports HTTP requests"); |
||||
} |
||||
HttpServletRequest request = (HttpServletRequest) srvltRequest; |
||||
HttpServletResponse response = (HttpServletResponse) srvltResponse; |
||||
|
||||
List<Filter> filters = getFilters(request); |
||||
logger.log("Request received for '" + UrlUtils.buildRequestUrl(request) + "':\n\n" + |
||||
request + "\n\n" + |
||||
"servletPath:" + request.getServletPath() + "\n" + |
||||
"pathInfo:" + request.getPathInfo() + "\n\n" + |
||||
formatFilters(filters)); |
||||
|
||||
if (request.getAttribute(ALREADY_FILTERED_ATTR_NAME) == null) { |
||||
invokeWithWrappedRequest(request, response, filterChain); |
||||
} else { |
||||
fcp.doFilter(request, response, filterChain); |
||||
} |
||||
} |
||||
|
||||
private void invokeWithWrappedRequest(HttpServletRequest request, |
||||
HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException { |
||||
request.setAttribute(ALREADY_FILTERED_ATTR_NAME, Boolean.TRUE); |
||||
request = new DebugRequestWrapper(request); |
||||
try { |
||||
fcp.doFilter(request, response, filterChain); |
||||
} |
||||
finally { |
||||
request.removeAttribute(ALREADY_FILTERED_ATTR_NAME); |
||||
} |
||||
} |
||||
|
||||
String formatFilters(List<Filter> filters) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
sb.append("Security filter chain: "); |
||||
if (filters == null) { |
||||
sb.append("no match"); |
||||
} else if (filters.isEmpty()) { |
||||
sb.append("[] empty (bypassed by security='none') "); |
||||
} else { |
||||
sb.append("[\n"); |
||||
for (Filter f : filters) { |
||||
sb.append(" ").append(f.getClass().getSimpleName()).append("\n"); |
||||
} |
||||
sb.append("]"); |
||||
} |
||||
|
||||
return sb.toString(); |
||||
} |
||||
|
||||
private List<Filter> getFilters(HttpServletRequest request) { |
||||
for (SecurityFilterChain chain : fcp.getFilterChains()) { |
||||
if (chain.matches(request)) { |
||||
return chain.getFilters(); |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
public void init(FilterConfig filterConfig) throws ServletException { |
||||
} |
||||
|
||||
public void destroy() { |
||||
} |
||||
} |
||||
|
||||
class DebugRequestWrapper extends HttpServletRequestWrapper { |
||||
private static final Logger logger = new Logger(); |
||||
|
||||
public DebugRequestWrapper(HttpServletRequest request) { |
||||
super(request); |
||||
} |
||||
|
||||
@Override |
||||
public HttpSession getSession() { |
||||
boolean sessionExists = super.getSession(false) != null; |
||||
HttpSession session = super.getSession(); |
||||
|
||||
if (!sessionExists) { |
||||
logger.log("New HTTP session created: " + session.getId(), true); |
||||
} |
||||
|
||||
return session; |
||||
} |
||||
|
||||
@Override |
||||
public HttpSession getSession(boolean create) { |
||||
if (!create) { |
||||
return super.getSession(create); |
||||
} |
||||
return getSession(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Controls output for the Spring Security debug feature. |
||||
* |
||||
* @author Luke Taylor |
||||
* @since 3.1 |
||||
*/ |
||||
final class Logger { |
||||
final static Log logger = LogFactory.getLog("Spring Security Debugger"); |
||||
|
||||
void log(String message) { |
||||
log(message, false); |
||||
} |
||||
|
||||
void log(String message, boolean dumpStack) { |
||||
StringBuilder output = new StringBuilder(256); |
||||
output.append("\n\n************************************************************\n\n"); |
||||
output.append(message).append("\n"); |
||||
|
||||
if (dumpStack) { |
||||
StringWriter os = new StringWriter(); |
||||
new Exception().printStackTrace(new PrintWriter(os)); |
||||
StringBuffer buffer = os.getBuffer(); |
||||
// Remove the exception in case it scares people.
|
||||
int start = buffer.indexOf("java.lang.Exception"); |
||||
buffer.replace(start, start + 19, ""); |
||||
output.append("\nCall stack: \n").append(os.toString()); |
||||
} |
||||
|
||||
output.append("\n\n************************************************************\n\n"); |
||||
|
||||
logger.info(output.toString()); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue