禁用Spring Security for OPTIONS Http Method

时间:2014-02-11 08:23:38

标签: java spring spring-mvc spring-security cors

是否可以针对某种HTTP方法禁用Spring Security?

我们有一个Spring REST应用程序,其服务需要在http请求的标头中附加授权令牌。我正在为它编写一个JS客户端并使用JQuery发送GET / POST请求。该应用程序使用此过滤器代码启用CORS。

doFilter(....) {

  HttpServletResponse httpResp = (HttpServletResponse) response;
  httpResp.setHeader("Access-Control-Allow-Origin", "*");
  httpResp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
  httpResp.setHeader("Access-Control-Max-Age", "3600");
  Enumeration<String> headersEnum = ((HttpServletRequest) request).getHeaders("Access-Control-Request-Headers");
  StringBuilder headers = new StringBuilder();
  String delim = "";
  while (headersEnum.hasMoreElements()) {
    headers.append(delim).append(headersEnum.nextElement());
    delim = ", ";
  }
  httpResp.setHeader("Access-Control-Allow-Headers", headers.toString());
}

但是当JQuery发送对CORS的OPTIONS请求时,服务器会使用Authorization Failed令牌进行响应。显然OPTIONS请求缺少授权令牌。那么可以让OPTIONS从Spring Security配置中逃脱安全层吗?

7 个答案:

答案 0 :(得分:121)

如果您使用的是基于注释的安全配置文件(@EnableWebSecurity&amp; @Configuration),您可以在configure()方法中执行以下操作,以允许{{1 Spring Security不允许对给定路径进行身份验证的请求:

OPTION

答案 1 :(得分:36)

在上下文中允许所有OPTIONS:

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
    }

答案 2 :(得分:11)

你试过这个吗?

  

您可以使用多个元素来定义不同的元素   访问不同URL集的要求,但它们将是   按列出的顺序评估,将使用第一个匹配。那么你   必须将最具体的匹配放在顶部。你也可以添加一个   method属性将匹配限制为特定的HTTP方法(GET,   POST,PUT等。)。

<http auto-config="true">
    <intercept-url pattern="/client/edit" access="isAuthenticated" method="GET" />
    <intercept-url pattern="/client/edit" access="hasRole('EDITOR')" method="POST" />
</http>

上述意味着您需要选择要截取的网址格式以及您想要的方法

答案 3 :(得分:2)

如果有人正在寻找使用Spring Boot的简单解决方案。只需添加一个额外的bean:

   @Bean
   public IgnoredRequestCustomizer optionsIgnoredRequestsCustomizer() {
      return configurer -> {
         List<RequestMatcher> matchers = new ArrayList<>();
         matchers.add(new AntPathRequestMatcher("/**", "OPTIONS"));
         configurer.requestMatchers(new OrRequestMatcher(matchers));
      };
   }

请注意,根据您的应用程序,可能会将其用于潜在的攻击。<​​/ p>

为更好的解决方案打开了问题:https://github.com/spring-projects/spring-security/issues/4448

答案 4 :(得分:1)

不建议接受已接受的答案,您也不应该这样做。
下面是Spring Security和jQuery的ajax的CORS设置的正确方法。

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
   
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(userAuthenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors() // <-- This let it use "corsConfigurationSource" bean.
                .and()
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            ...
    }

    @Bean
    protected CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();

        configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH"));

        // NOTE: setAllowCredentials(true) is important,
        // otherwise, the value of the 'Access-Control-Allow-Origin' header in the response
        // must not be the wildcard '*' when the request's credentials mode is 'include'.
        configuration.setAllowCredentials(true);

        // NOTE: setAllowedHeaders is important!
        // Without it, OPTIONS preflight request will fail with 403 Invalid CORS request
        configuration.setAllowedHeaders(Arrays.asList(
                "Authorization",
                "Accept",
                "Cache-Control",
                "Content-Type",
                "Origin",
                "ajax", // <-- This is needed for jQuery's ajax request.
                "x-csrf-token",
                "x-requested-with"
        ));

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

来自 jQuery 方面。

$.ajaxSetup({
    // NOTE: Necessary for CORS
    crossDomain: true,
    xhrFields: {
        withCredentials: true
    }
});

答案 5 :(得分:0)

如果您使用的是基于注释的安全性配置,则应通过在配置中调用CorsFilter将spring的.cors()添加到应用程序上下文中,如下所示:

@Override
protected void configure(HttpSecurity http) throws Exception
{
     http
    .csrf().disable()
    .authorizeRequests()
      .antMatchers("/resources/**").permitAll()
      .anyRequest().authenticated()
    .and()
    .formLogin()
    .and()
    .httpBasic()
    .and()
    .cors();
}

答案 6 :(得分:-1)

在某些情况下,使用self.add解决cors问题时,需要在const ar = [10, 20, 20, 10, 10, 30, 50, 10, 20]; function pairs(a) { var pairCount = 0; for (var i = 0; i < ar.length; i++) { for (var j = i + 1; j < ar.length; j++) { if (ar[i] === ar[j]) { pairCount++; } } } return pairCount; } console.log(pairs(ar));上添加configuration.setAllowedHeaders(Arrays.asList("Content-Type"));