Last active
August 29, 2015 13:55
-
-
Save shimarin/8731533 to your computer and use it in GitHub Desktop.
A servlet filter which provides functionality supports AngularJS's XSRF protection scheme.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.walbrix.servlet; | |
import java.io.IOException; | |
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.Cookie; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import javax.servlet.http.HttpSession; | |
public class AntiXSRFFilter implements Filter { | |
private String[] methodsToBeProtected = new String[] {"POST","DELETE","PUT"}; | |
private boolean isMethodToBeProtected(String method) | |
{ | |
for (String m:this.methodsToBeProtected) { | |
if (m.equals(method)) return true; | |
} | |
return false; | |
} | |
@Override | |
public void init(FilterConfig filterConfig) throws ServletException { | |
String methodsToBeProtected = filterConfig.getInitParameter("methodsToBeProtected"); | |
if (methodsToBeProtected != null) { | |
this.methodsToBeProtected = methodsToBeProtected.split("\\s*,\\s*"); | |
} | |
} | |
@Override | |
public void doFilter(ServletRequest _request, ServletResponse _response, | |
FilterChain chain) throws IOException, ServletException { | |
HttpServletRequest request = (HttpServletRequest) _request; | |
HttpServletResponse response = (HttpServletResponse) _response; | |
if (isMethodToBeProtected(request.getMethod())) { | |
HttpSession session = request.getSession(false); | |
String header = request.getHeader("X-XSRF-TOKEN"); | |
if (session == null || header == null || !header.equals(session.getId())) { | |
// It's possibly a cross site request | |
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Token mismatch"); | |
return; | |
} | |
} | |
response.addHeader("X-Content-Type-Options", "nosniff"); | |
Cookie cookie = new Cookie("XSRF-TOKEN",request.getSession(true).getId()); | |
cookie.setPath(request.getContextPath()); | |
response.addCookie(cookie); | |
chain.doFilter(request, response); | |
} | |
@Override | |
public void destroy() { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> | |
<filter> | |
<filter-name>AntiXSRFFilter</filter-name> | |
<filter-class>com.walbrix.servlet.AntiXSRFFilter</filter-class> | |
</filter> | |
<filter-mapping> | |
<filter-name>AntiXSRFFilter</filter-name> | |
<url-pattern>/api/*</url-pattern> | |
</filter-mapping> | |
</web-app> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You're simply using the session ID as the token here, right? Shouldn't there be some extra randomness to it at least, or better, it changes on each request?
Also, the token won't be there yet on the first POST, DELETE or PUT, if I'm reading this right.