提问人:georgebax 提问时间:11/2/2023 最后编辑:georgebax 更新时间:11/3/2023 访问量:36
Wildfly 为所有预检请求返回 405
Wildfly returns 405 for all preflight requests
问:
我在 Widfly (27.0.1) 上部署了一个 Web 应用程序,以及一个尝试在此应用程序中调用 REST 端点的 VueJS 客户端。因为我收到这个错误(,所以我按照本指南在启动时使用 .cli 脚本将 CORS 添加到 wildfly 配置中。请注意,这是一个 GET 请求,但我认为由于 Content-Type,它被认为是“复杂的”。Access to XMLHttpRequest at 'http://localhost:8899/my-services/rest-api/selection-data/all' from origin 'http://127.0.0.1:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
application/json
但是,这并没有解决任何问题,即使我现在在CORS预检请求的响应中获得了这些标头:
Access-Control-Allow-Credentials:
true
Access-Control-Allow-Headers:
accept, authorization, content-type, x-requested-with
Access-Control-Allow-Methods:
GET, POST, OPTIONS, PUT
Access-Control-Allow-Origin:
*
Access-Control-Max-Age:
1
...
我还尝试创建一个 resteasy 并将其添加到应用程序中,我可以看到它是在部署时添加的,但其中没有调用任何内容。我创建的注释也是如此,它创建了一个 ,尽管我不确定这个是否被 Wildfly 选中。org.jboss.resteasy.plugins.interceptors.CORSFilter
@Provider
Feature
CORSFilter
在阅读了更多内容后,我发现 servlet 过滤可能在 CORS 过滤器可以执行任何操作之前发生,因为 servlet 级别先于 JAX-RS 级别。但此时此刻,我不知道该怎么办。我有一个 servlet 过滤器类,如下所示:
@WebFilter(urlPatterns = { "/*" })
public class UserCredentialFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(UserCredentialFilter.class);
private final User user;
@Inject
public UserCredentialFilter(User user) {
this.user = user;
}
@Override
public void init(FilterConfig filterConfig) {
// nothing to do
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest httpServletRequest = ((HttpServletRequest) servletRequest);
// it doesn't enter this point in preflight requests
if (httpServletRequest.getMethod().equalsIgnoreCase("OPTIONS")) {
// below doesn't get called either
System.out.println("In a preflight request?");
return;
}
Principal userPrincipal = httpServletRequest.getUserPrincipal();
if (userPrincipal != null) {
///// user-related logic
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
// nothing to do
}
}
我应该在什么时候处理此印前检查请求?谁和代码的哪一部分返回不允许使用 OPTIONS 方法?
编辑:我刚刚发现,如果 Access-Control-Allow-Credentials 也设置为 true,则无法使用 ACAO 标头中的通配符 (*),但我认为不会返回 405 代码,根据规范,它将是“原因:如果 CORS 标头”Access-Control-Allow-Origin“为”*“,则不支持凭据 "
答:
显然,当 Postman 在没有先登录的情况下发送 OPTION 请求时,问题也出现了(我们有一个返回身份验证令牌的端点),但是登录后,OPTION 请求就可以正常工作 - 所以这实际上是一个授权问题,隐藏在这个 405 方法后面不允许”。解决方法是最终将此行添加到 web.xml,它绕过了 OPTION 请求的授权机制:
<security-constraint>
<display-name>SecurityConstraint</display-name>
<web-resource-collection>
<web-resource-name>Secured page</web-resource-name>
<url-pattern>/rest-api/*</url-pattern>
<http-method-omission>OPTIONS</http-method-omission> // this one
</web-resource-collection>
...
</security-constraint>
但这本身是不够的,因为 Wildfly 不会返回所需的 CORS 标头,因此还需要根据此配置 wildfly 映像,并修改 Access-Control-Allowed-Origin 标头返回域名而不是通配符。
评论