在文件上传到 Jetty 之前验证文件上传请求

问题描述 投票:0回答:1

我们有一个带有接收文件上传请求的端点的 REST 服务。所有请求都使用具有 5 分钟超时时间的身份验证令牌。

问题是 Jetty 似乎在调用我们的任何代码之前加载了整个文件。这意味着我们要等到完整上传完成后才能检查身份验证令牌,这会导致大文件因身份验证超时而失败。

我们假设增加身份验证超时不是一个选项。 (文书工作、繁文缛节、客户签字等)。

最初我们使用 JAX-RS 来上传文件,如下所示:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response fileUpload (MultipartFormDataInput input) {
    ...
}

在过滤器中检查身份验证:

@Priority(Priorities.AUTHENTICATION)
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        <check token>
        chain.doFilter(request, response);
    }
}

我们一直在使用带有速率限制的 CURL 进行本地测试:

curl -v --cookie $TOKEN -F "[email protected]" http://localhost:8080/file --limit-rate 10k

我们的所有代码中都有日志消息。 CURL 命令挂起一段时间,直到最后(令牌过期很久之后)才打印任何日志。

我们还尝试了

ContainerRequestFilter
并得到了完全相同的结果。即使有
PreMatching
注释。

@Priority(Priorities.AUTHENTICATION)
@PreMatching
public class AuthFilter implements ContainerRequestFilter {
    @Override
    public void filter(ContainerRequestContext requestContext) {
        <check token>
    }
}

我们尝试重写端点以使用 Servlet 和 Apache Commons FileUpload 库,根据我在此处阅读的内容,这应该可以解决此问题。

import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("file")
public class UploadServlet extends HttpServlet {    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
        print("Upload started");
        
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);

       print("Upload finished");
    }
}

但是,我仍然得到相同的结果。直到 CURL 命令完成上传文件后,才会打印来自 servlet 的日志消息。

任何指点表示赞赏。

java apache jetty
1个回答
0
投票

我可以回答 Jetty 行为,但不能回答您特定的 REST 库。

Jetty 正在按照 REST 库的指示进行操作。

您已在 REST 库中声明...

@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response fileUpload (MultipartFormDataInput input) {

这就是告诉 Jetty 将整个

multipart/form-data
请求正文加载到名为
MultipartFormDataInput
的对象中,然后在完全发送后,将该对象提供给您的端点。

问题是,REST 库调用 Servlet API 来访问该 MultiPart 信息(例如:

HttpServletRequest.getParameter
HttpServletRequest.getPart/getParts
),这导致基于
javax.servlet.MultipartConfigElement
的 REST 库配置读取整个多部分表单。

至于为什么您的 REST 身份验证未触发,这超出了我的帮助范围。

最后,commons-fileupload 不应该在现代 Servlet 容器中使用。

查看过去的答案:

© www.soinside.com 2019 - 2024. All rights reserved.