【发布时间】:2016-10-21 20:02:59
【问题描述】:
我试图阻止CSRF(Cross site request forgery)。为了防止CSRF,我创建了过滤器来过滤每个请求。
在按预期实施javax.servlet.Filter 后,过滤器就完成了它的工作。但是在实现 servlet 过滤器后,我的应用程序资源没有正确加载。
CSS、jQuery、datatable,所有资源都没有正确加载,有时它们正在加载,有时没有。
在实施过滤器之前,它工作正常。
firebug 中的示例错误:
"NetworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/images/bg-report-content.jpg"
"NetworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/images/bg-header.jpg"
tworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/css/dataTables.bootstrap.css"
"NetworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/js/fnStandingRedraw.js"
"NetworkError: 500 Internal Server Error - http://localhost:8080/myApp/resources/js/dataTables.tableTools.js"
这就是我如何为 CSRF 实现过滤器
我正在做的是,我创建了一个名为LoadSalt 的类,它创建了salt(随机数)。我在jsp中接受的那个随机数。并与 jsp 一起发送请求。
LoadSalt 类
public class LoadSalt implements Filter{
public Cache<String, Boolean> csrfPreventionSaltCache= null;
HttpServletRequest httpReq=null;
//int count=0;
@SuppressWarnings("unchecked")
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//count++;
// Assume its HTTP
httpReq = (HttpServletRequest)request;
if(httpReq.getAttribute("csrfPreventionSaltCache")!=null)
{
csrfPreventionSaltCache= (Cache<String, Boolean>) httpReq.getAttribute("csrfPreventionSaltCache");
}
if(csrfPreventionSaltCache == null)
{
// creating a new cache
csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000)
.expireAfterAccess(5, TimeUnit.MINUTES).build();
// Setting to httpReq
httpReq.setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);
}
// Generate the salt and store it in the users cache
String salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());
//System.out.println("Salt: "+salt);
csrfPreventionSaltCache.put(salt, Boolean.TRUE);
// Add the salt to the current request so it can be used
// by the page rendered in this request
httpReq.setAttribute("csrfPreventionSalt", salt);
chain.doFilter(httpReq, response);
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
}
另一个验证盐的过滤器
public class ValidateSalt implements Filter {
public Cache<String, Boolean> csrfPreventionSaltCache= null;
@SuppressWarnings("unchecked")
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// Assume its HTTP
HttpServletRequest httpReq = (HttpServletRequest) request;
HttpServletResponse httpResponse =(HttpServletResponse) response;
String salt =(String) httpReq.getAttribute("csrfPreventionSalt");
// Validate that the salt is in the cache
if(httpReq.getAttribute("csrfPreventionSaltCache")!=null)
{
csrfPreventionSaltCache = (Cache<String, Boolean>) httpReq.getAttribute("csrfPreventionSaltCache");
}
if(csrfPreventionSaltCache !=null && salt !=null && csrfPreventionSaltCache.getIfPresent(salt)!=null)
{
String metodName =httpReq.getMethod();
String saltFromJspPage = httpReq.getParameter("salt");
//String saltFromRequest =(String) httpReq.getAttribute("csrfPreventionSalt");
if(metodName.equalsIgnoreCase("POST"))
{
if(saltFromJspPage!=null && csrfPreventionSaltCache.getIfPresent(saltFromJspPage)!=null)
{
chain.doFilter(httpReq, response);
else
{
//throw new ServletException("Potential CSRF detected!! Please contact to system admin ASAP.");
httpResponse.sendRedirect("/myApp/pages/pageNotFound.jsp");
}
}
else
{
chain.doFilter(httpReq, response);
}
}
else
{
// Otherwise we throw an exception aborting the request flow
//throw new ServletException("Potential CSRF detected!! Inform a scary sysadmin ASAP.");
httpResponse.sendRedirect("/myApp/pages/pageNotFound.jsp");
}
}
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
}
web.xml 中的 servlet 过滤器映射
<filter>
<filter-name>loadSalt</filter-name>
<filter-class>com.mpApp.security.LoadSalt</filter-class>
</filter>
<filter-mapping>
<filter-name>loadSalt</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>validateSalt</filter-name>
<filter-class>com.mpApp.security.ValidateSalt</filter-class>
</filter>
<filter-mapping>
<filter-name>validateSalt</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
我的申请有什么问题?
为什么 servlet 过滤器不允许加载资源?虽然有时它可以工作,但有时它不能,
这是什么路径原因?
我是否以错误的方式实现 servlet 过滤器。
请帮忙。
【问题讨论】:
-
正如我在问题中提到的,有时它允许加载资源,但有时却不允许。我在新的浏览器选项卡中检查了各个资源的 URL,它们是可见的。你能帮我解决他的问题吗
-
服务器在我的情况下没有抛出异常,但我的大部分 jQuery 在实现过滤器后无法加载到页面上
-
你找到根本原因了吗?
标签: filter csrf servlet-filters csrf-protection