【问题标题】:Spring boot rest service options 401 on oauth/tokenoauth/token 上的 Spring Boot 休息服务选项 401
【发布时间】:2016-09-27 18:10:58
【问题描述】:

我正在使用 spring boot 来做一个简单的休息服务。为了在 Angular 2 中使用它,我在 oauth/token 端点上检索令牌时遇到了 CORS 问题。

Chrome 中的错误信息如下。

error message

zone.js:101 OPTIONS http://192.168.0.9:8080/api/oauth/token 
XMLHttpRequest cannot load http://192.168.0.9:8080/api/oauth/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 401.

相关文件如下。

MyConfig.java

@Configuration
public class MyConfig {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("**")
                        .allowedOrigins("*").allowedMethods("POST, GET, HEAD, OPTIONS")
                .allowCredentials(true)
                .allowedHeaders("Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers")
                .exposedHeaders("Access-Control-Allow-Origin,Access-Control-Allow-Credentials")
                .maxAge(10);
            }
        };
    }
}

OAuth2ResourceServerConfig.java

@Configuration
@EnableResourceServer
class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .anonymous()
            .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.OPTIONS,"**").permitAll()
                .antMatchers("/authenticated/**").authenticated()
                ;
    }

}

我是 java 和 spring 的新手。我发现了一些类似的问题,例如OAuth2 - Status 401 on OPTIONS request while retrieving TOKEN,但我真的不明白如何使它在spring boot中工作。

请注意正常的休息控制器端点工作正常。问题是oauth/token,options请求返回401状态。

请在 Spring Boot 中显示一些工作代码。谢谢!

【问题讨论】:

    标签: rest spring-boot oauth-2.0 cors options


    【解决方案1】:

    您可以将此 CORS 过滤器添加到您的项目中

        @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", "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() {
        }
    
     }
    

    【讨论】:

    • 我确实在其他帖子中找到了这个答案。但是在 Spring Boot 中,它建议使用我的代码中所示的 WebMvcConfigurerAdapter 而不是过滤器。你可以看到他们有类似的代码,除了“OPTIONS”部分。所以我想知道是否可以在我的文件中添加类似的“OPTIONS”代码?谢谢。
    • 非常感谢!!!!!!!在我解决这个问题大约 4 天后,你拯救了我的一天!!!
    • 这个解决方案有效,但没有回答为什么原来的问题不起作用。
    • 我遇到了一个问题,有时 cors 工作,而其他时候却没有。我认为 Spring 会动态更改顺序,所以我只需要添加 @Order(Ordered.HIGHEST_PRECEDENCE) 所以它始终是第一要务。
    【解决方案2】:

    这里是原生 Spring Framework 解决方案:

    @Bean
    public CorsFilter corsFilter(CorsConfiguration config) {
        log.debug("Registering CORS filter");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);
        source.registerCorsConfiguration("/v2/api-docs", config);
        source.registerCorsConfiguration("/oauth/**", config);
        return new CorsFilter(source);
    }
    

    【讨论】:

      【解决方案3】:

      如果你使用的是 spring boot + Spring OAuth 你必须添加

      @Order(Ordered.HIGHEST_PRECEDENCE)
      

      到您的 CORS 过滤器

      @Configuration
      @Order(Ordered.HIGHEST_PRECEDENCE)
      public class CORSFilter implements Filter {
      
          private FilterConfig config;
      
          public static final String CREDENTIALS_NAME = "Access-Control-Allow-Credentials";
          public static final String ORIGIN_NAME = "Access-Control-Allow-Origin";
          public static final String METHODS_NAME = "Access-Control-Allow-Methods";
          public static final String HEADERS_NAME = "Access-Control-Allow-Headers";
          public static final String MAX_AGE_NAME = "Access-Control-Max-Age";
      
          @Override
          public void destroy() {
      
          }
      
          @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", "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 init(FilterConfig filterConfig) throws ServletException {
              config = filterConfig;
          }
      }
      

      【讨论】:

        【解决方案4】:

        浏览器通过带有 OPTIONS 标头的请求检查 CORS 设置。如果您配置了授权,OPTIONS 请求将被视为未经授权而被阻止。

        您只需在 WebConfigurerAdapter 中添加 cors 支持即可。

        @EnableWebSecurity
        public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                // ...
                http.cors();
            }
        }
        

        查看此链接了解更多信息:https://www.baeldung.com/spring-security-cors-preflight

        【讨论】:

          猜你喜欢
          • 2018-04-26
          • 1970-01-01
          • 2021-02-11
          • 2018-12-09
          • 1970-01-01
          • 2012-10-13
          • 2017-10-22
          • 2017-08-31
          • 1970-01-01
          相关资源
          最近更新 更多