Issue
I am trying to set up a tomcat server to receive requests from an angular webapp. Everything works fine until I start trying to use the DELETE type of request. From my debugging, i have realised that the problem arises in a filter i have, that checks whether the user has already a session when he is trying to access some server resources and denies those requests.
The code is as follows:
- Backend session filter:
public class SessionFilter extends HttpFilter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
var out = response.getWriter();
ObjectMapper mapper = new ObjectMapper();
response.setContentType("application/json");
if (request.getSession(false) == null && !request.getRequestURI().equals("/login")) {
response.setStatus(401);
out.println(mapper.writerFor(ServletResponse.class).writeValueAsString(new ServletResponse("User must be logged in first!")));
return;
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
- Login servlet (the one that provides the session)
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
sess = req.getSession(true);
sess.setMaxInactiveInterval(3600);
}
}
- Some servlet that does a delete request
@WebServlet(urlPatterns = "/test")
public class TravelServlet extends HttpServlet {
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println(req.getParameter("test"));
}
}
- web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>web.lab9.servlets.filters.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:4200</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,DELETE,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
And now on the frontend, using Angular, i call the request as such:
this.http.delete<string>(this.url, {
params: new HttpParams().set('test', 'test'),
withCredentials: true
}).subscribe(result => {console.log(result);}, error => {console.log(error);});
Whenever the delete request arrives on the server, the session is null, and i get an error thrown from the session filter. From what i understood, this is because of preflight requests and the fact that headers are not set on preflight. Is there any way i can circumvent this? I am not allowed to use anything besides HTTP servlets and filters.
Also, can i do something to redirect as well from the session filter? I was able to do it before using the delete request, but since i started using it I've only encountered problems, because what worked with get/post requests didn't work at all with delete/put/...
Solution
The problem was the order of the filters. The cors filter should always be first if you want to have access to cookies in the following filters. The documentation didn't say anything of the sort, so I just assumed it doesn't matter, but apparently, it does.
Answered By - Ghosty Frosty
Answer Checked By - Robin (JavaFixing Admin)