Spring Security OAuth2:CORS 预检通道未成功

Posted

技术标签:

【中文标题】Spring Security OAuth2:CORS 预检通道未成功【英文标题】:Spring Security OAuth2: CORS preflight channel did not succeed 【发布时间】:2015-11-22 17:07:42 【问题描述】:

当我对在我自己的系统上运行的服务器实例进行 HTTP 调用时,我在调用“/oauth/token”时收到此错误。我通过创建这样的过滤器来解决这个问题:

@Component
public class SimpleCORSFilter implements Filter 

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
    HttpServletRequest httpServletRequest = (HttpServletRequest) req;
    if (httpServletRequest.getMethod() != "OPTIONS") 
      chain.doFilter(req, res);
     else 
        // In case of HTTP OPTIONS method, just return the response
    

我已将其添加为 WebConfigurer 中的过滤器:

private void initCORSFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) 
    log.debug("Registering CORS Filter");
    FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", new SimpleCORSFilter());
    Map<String, String> parameters = new HashMap<>();
    corsFilter.setInitParameters(parameters);
    corsFilter.addMappingForUrlPatterns(disps, true, "/*");
    corsFilter.setAsyncSupported(true);

我在 FireFox 中遇到此错误:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://182.176.221.94:9091/ams/oauth/token. (Reason: CORS preflight channel did not succeed).

简而言之,我确保预检 OPTIONS 调用始终得到响应以继续进行。这是在我自己的系统上运行的,但是现在服务器实例部署在 Linux 服务器上,我又遇到了这个问题。而且我只有在调用“oauth/token”时才得到这个,其他所有调用都工作正常。

我能做些什么来摆脱这个。有什么帮助吗?

【问题讨论】:

【参考方案1】:

您的过滤器不需要使用 @Component 进行注释,并且应该在 WebConfigurer 类中使用适当的 url 模式进行映射,就像 JHipster 中使用的其他过滤器一样。

您的过滤器也不应该像 OPTIONS 那样破坏过滤器链。如果您正在处理 OPTIONS 请求,则允许在标头中使用 OPTIONS 方法然后不返回标头是不一致的。

【讨论】:

我已经更新了这个问题。请看一下。我已经在 WebConfigurer 中添加了过滤器。删除 @Component 属性使其即使在我的本地机器上也停止工作。 它在没有 @Component 的情况下对我有用,所以你的项目有问题 我在您的 OPTIONS 过滤器中添加了更多关于不一致的详细信息 您不需要@Compoenent 的原因是您已经在WebConfigurer.initCORSFilter() 中使用新的SimpleCORSFilter() 实例化了它。如果您在调试器中放置断点,您应该会看到过滤器构造函数被调用了两次,如果不是,那么是您在 webConfigurer 中的应用程序初始化失败。 我发现了问题并将其发布为答案。我非常感谢您的帮助和反馈,并将遵循您的建议来改进我做错的事情。谢谢!【参考方案2】:

问题是我使用 != 比较 if (httpServletRequest.getMethod() != "OPTIONS"。我改为将其更改为 if (!httpServletRequest.getMethod().equalsIgnoreCase("OPTIONS")) 并且它起作用了。这可能与我在运行代码库时在本地机器上进行测试但从中创建了一个 WAR 文件并部署在它不起作用的服务器上这一事实有关。我不确定到底是什么原因,但这解决了问题。

【讨论】:

以上是关于Spring Security OAuth2:CORS 预检通道未成功的主要内容,如果未能解决你的问题,请参考以下文章

Spring-Security OAuth2 设置 - 无法找到 oauth2 命名空间处理程序

Spring Security OAuth2 v5:NoSuchBeanDefinitionException:'org.springframework.security.oauth2.jwt.Jwt

针对授权标头的Spring Security OAuth2 CORS问题

OAuth2.0学习(4-1)Spring Security OAuth2.0 - 代码分析

Spring Security---Oauth2详解

如何使用spring-security,oauth2调整实体的正确登录?