【问题标题】:Request to preflight doesn't pass access control check tomcat 10预检请求未通过访问控制检查 tomcat 10
【发布时间】:2021-05-03 20:02:10
【问题描述】:

我正在尝试设置一个 tomcat 服务器来接收来自 angular webapp 的请求。在我开始尝试使用 DELETE 类型的请求之前,一切正常。通过调试,我意识到问题出在我拥有的过滤器中,该过滤器检查用户在尝试访问某些服务器资源时是否已经有会话并拒绝这些请求。

代码如下:

  • 后端会话过滤器:
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() {
    }
}
  • 登录 servlet(提供会话的那个)
@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);
   }
}
  • 一些执行删除请求的 servlet
@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 文件
<?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>

现在在前端,使用 Angular,我这样调用请求:

this.http.delete<string>(this.url, {
      params: new HttpParams().set('test', 'test'),
      withCredentials: true
    }).subscribe(result => {console.log(result);}, error => {console.log(error);});

每当删除请求到达服务器时,会话为空,并且我从会话过滤器中得到一个错误。据我了解,这是因为预检请求以及未在预检时设置标头的事实。有什么办法可以规避这个吗?除了 HTTP servlet 和过滤器,我不能使用任何东西。

另外,我可以做些什么来从会话过滤器重定向吗?在使用删除请求之前我能够做到这一点,但是自从我开始使用它以来,我只遇到了问题,因为与 get/post 请求一起使用的方法在 delete/put/ 中根本不起作用...

【问题讨论】:

    标签: tomcat servlets cors


    【解决方案1】:

    问题在于过滤器的顺序。如果您想在以下过滤器中访问 c​​ookie,则 cors 过滤器应始终放在首位。文档没有说任何类似的东西,所以我只是认为这无关紧要,但显然它确实如此。

    【讨论】:

      猜你喜欢
      • 2022-01-04
      • 2019-12-29
      • 2021-10-25
      • 2017-04-04
      • 2016-06-05
      相关资源
      最近更新 更多