Spring Oauth2 中的 CORS 错误

Posted

技术标签:

【中文标题】Spring Oauth2 中的 CORS 错误【英文标题】:CORS error in Spring Oauth2 【发布时间】:2015-04-04 07:47:59 【问题描述】:

我正在使用 Spring 安全性和 Oauth2。但是我是 Spring Oauth2 的新手,当前端访问资源时出现 CORS 错误。

我正在使用以下过滤器来允许其他域访问该资源:

@Component
@Order(Integer.MAX_VALUE)
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-Credentials", "True");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
        chain.doFilter(req, res);
    


    public void init(FilterConfig filterConfig) 
    public void destroy() 


我编写了以下代码以允许在我的 SecurityConfiguration.java 中使用公共资源。

@Override
protected void configure(HttpSecurity http) throws Exception 
             http
        .authorizeRequests().antMatchers("/social/facebook/**","/register/**","/public/**").permitAll().and()
        .authorizeRequests().antMatchers("/user/**").hasRole("USER").and()           
        .exceptionHandling()
            .accessDeniedPage("/login.jsp?authorization_error=true")
            .and()
        .csrf()
            .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")).disable();


对于 Oauth2,以下代码用于保护我的 OAuth2ServerConfig.java 中的用户资源。

@Override
    public void configure(HttpSecurity http) throws Exception 
        http

            .requestMatchers().antMatchers("/user/**")
        .and()
            .authorizeRequests()
            .antMatchers("/user/**").access("#oauth2.hasScope('read')")
                .regexMatchers(HttpMethod.DELETE, "/oauth/users/([^/].*?)/tokens/.*")
                    .access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')")
                .regexMatchers(HttpMethod.GET, "/oauth/clients/([^/].*?)/users/.*")
                    .access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('read')")
                .regexMatchers(HttpMethod.GET, "/oauth/clients/.*")
                    .access("#oauth2.clientHasRole('ROLE_CLIENT') and #oauth2.isClient() and #oauth2.hasScope('read')");
    

当我在浏览器中打开 index.html 文件时,如下所示:(对不起,我没有至少 10 个声望来发布图片,所以我在这里粘贴链接)

http://i.stack.imgur.com/yQKJM.png

成功获取公共数据,即允许其他域访问“/public/**”数据。

但它无法获取“/user/**”数据(受 Oauth2 保护)。它给了我下面的错误说“跨源请求被阻止”。

http://i.stack.imgur.com/XIVx1.png

当我将前端文件移动到 Spring 服务器的同一个域时。它可以很好地获取“公共”和“用户”数据,如下所示:

http://i.stack.imgur.com/Q2n7F.png

前端和后端应该分开。但是 CORS 被阻止访问预计数据。谁能给我一些建议?非常感谢。我猜过滤器在 Oauth2 上不起作用?仍然花费大量时间寻找解决方案。

【问题讨论】:

你可以在这里参考我的答案,***.com/questions/40418441/… 【参考方案1】:

首先调用了 OAuth 过滤器并抛出一个异常,该异常已被阻止运行您的 CORS 过滤器。

你必须添加这个注释

@Order(Ordered.HIGHEST_PRECEDENCE)

到您的 CORS 过滤器。

【讨论】:

【参考方案2】:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)

public class SimpleCORSFilter implements Filter 

    @Override
    public void init(FilterConfig fc) throws ServletException 
    

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp,
                         FilterChain chain) throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) resp;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "PATCH,POST,GET,OPTIONS,DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");

        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) 
            response.setStatus(HttpServletResponse.SC_OK);
         else 
            chain.doFilter(req, resp);
        

    

    @Override
    public void destroy() 
    


【讨论】:

这对我有用。你介意看看at this吗?因为出于某种原因,它对我不起作用,但使用您的过滤器却可以。但是,我想知道为什么它现在有效,并了解它的含义。【参考方案3】:

我将标头添加到端点

@Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints)
            throws Exception 

        endpoints.addInterceptor(new HandlerInterceptorAdapter() 
            @Override
            public boolean preHandle(HttpServletRequest hsr, HttpServletResponse rs, Object o) throws Exception 
                rs.setHeader("Access-Control-Allow-Origin", "*");
                rs.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
                rs.setHeader("Access-Control-Max-Age", "3600");
                rs.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
                return true;
            
        );


    

【讨论】:

以上是关于Spring Oauth2 中的 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章

Spring Oauth2 CORS

Spring Boot 和 OAuth2 CORS

Spring Boot 和 OAuth2 CORS

CORS 干扰 Spring Security oauth2

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

Spring boot Oauth2 + Angular CORS问题