HeaderWriterFilter - Spring Security 在响应标头中添加默认内容类型 ISO-8859-1,导致无转换器异常

HeaderWriterFilter - Spring Security adding default Content-type ISO-8859-1 in response header resulting in No converter exception

提问人:Hernan Petringa 提问时间:6/8/2023 更新时间:6/10/2023 访问量:106

问:

我有和端点在数据库中查找设备并使用 PageWrapper 返回响应。内容类型应为 application/json。目前为止,一切都好。 接下来,我添加带有 vanilla 配置的 Spring Security,端点开始失败。它说访问被拒绝(即使使用 permitAll()),原因是它在创建响应时失败了。为什么?因为Spring从AbstractMessageConverterMethodProcessor.class调用“createOutputMessage(NativeWebRequest webRequest)”的那一刻,响应是使用默认的内容类型ISO-8859-1创建的。然后,几步后,当找到合适的 Converter 来处理响应类型时,它会找到 MappingJackson2HttpMessageConverter,并且 application/json 没问题,但它需要内容类型 UTF-8。由于标头中的 content-type 是 ISO-8859-1,因此它会抛出一个异常,指出未找到转换器。

删除 Spring Security 时,将使用 Content-type null 创建响应。这很好,稍后如果 content-type 为 null,它会用 UTF-8 填充它。 为什么安全部门将 ISO-8859-1 添加为默认值?我怎样才能强制它使用 UTF-8? 提前致谢

Spring Security UTF-8 接头 ISO-8859-1

评论


答:

0赞 Hernan Petringa 6/10/2023 #1

发现问题:

@Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
      throws IOException, ServletException {
        try {
            Authentication authentication = getAuthentication.execute((HttpServletRequest) request);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } catch (Exception exp) {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            httpResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
            PrintWriter writer = httpResponse.getWriter();
            writer.print(exp.getMessage());
            writer.flush();
            writer.close();
        }

        filterChain.doFilter(request, response);
    }

在我的自定义过滤器中,如果用户未获得身份验证,我会捕获异常,但是如果我点击受“permitAll()”影响的 URL,这段代码仍会执行。由于 permitAll() 不需要对请求进行身份验证,但仍命中“doFilterInternal”代码,因此引发了异常。 在捕获中,有一行说 httpResponse.getWriter()。该代码打算返回 Writer 的实例,以便写入响应的正文。此外,它还检查内容类型和字符集,并且由于 chartset 为 null,因此它使用默认字符集 ISO-8859-1。一旦执行了该代码,相同的“响应”就会转发到控制器,并且与将在 Jackson 转换器中使用的响应相同。然后,转换器期望字符集是有效的字符集 (UTF-8),以便将其与 json 响应类型匹配或为 null,以便使用 UTF-8 自动完成它,但它已设置为 ISO-8859-1,从而使转换器抛出 No Converter found 异常。 只需删除捕获并且不过早调用“getWriter()”即可解决问题。