Java 禁用Http方法选项的Spring安全性

Java 禁用Http方法选项的Spring安全性,java,spring,spring-mvc,spring-security,cors,Java,Spring,Spring Mvc,Spring Security,Cors,是否可以为一种HTTP方法禁用Spring安全性 我们有一个SpringREST应用程序,其中的服务要求在http请求的头中附加授权令牌。我正在为它编写一个JS客户端,并使用JQuery发送GET/POST请求。应用程序已使用此筛选代码启用CORS doFilter(....) { HttpServletResponse httpResp = (HttpServletResponse) response; httpResp.setHeader("Access-Control-Allow

是否可以为一种HTTP方法禁用Spring安全性

我们有一个SpringREST应用程序,其中的服务要求在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());
}
doFilter(…){
HttpServletResponse httpResp=(HttpServletResponse)响应;
httpResp.setHeader(“访问控制允许源代码”、“*”);
setHeader(“访问控制允许方法”、“POST、GET、OPTIONS、DELETE”);
httpResp.setHeader(“访问控制最大年龄”,“3600”);
枚举头枚举=((HttpServletRequest)请求).getHeaders(“访问控制请求头”);
StringBuilder标头=新的StringBuilder();
字符串delim=“”;
while(headersEnum.hasMoreElements()){
headers.append(delim.append(headersEnum.nextElement());
delim=“,”;
}
setHeader(“访问控制允许头”,Headers.toString());
}
但是,当JQuery为CORS发送选项请求时,服务器会使用授权失败令牌进行响应。显然,选项请求缺少授权令牌。那么,是否可以让选项从Spring安全配置中脱离安全层呢?

您尝试过这个吗

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



上面的意思是,您需要选择要截取的url模式以及所需的方法如果您使用的是基于注释的安全配置文件(
@EnableWebSecurity
&
@Configuration
),您可以在
配置()中执行以下操作
允许Spring Security在不验证给定路径的情况下允许
选项
请求的方法:

@Override
protected void configure(HttpSecurity http) throws Exception
{
     http
    .csrf().disable()
    .authorizeRequests()
      .antMatchers(HttpMethod.OPTIONS,"/path/to/allow").permitAll()//allow CORS option calls
      .antMatchers("/resources/**").permitAll()
      .anyRequest().authenticated()
    .and()
    .formLogin()
    .and()
    .httpBasic();
}

允许上下文中的所有选项:

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

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

   @Bean
   public IgnoredRequestCustomizer optionsIgnoredRequestsCustomizer() {
      return configurer -> {
         List<RequestMatcher> matchers = new ArrayList<>();
         matchers.add(new AntPathRequestMatcher("/**", "OPTIONS"));
         configurer.requestMatchers(new OrRequestMatcher(matchers));
      };
   }
@Bean
公共IgnoredRequestCustomizer选项ignoredRequestsCustomizer(){
返回配置器->{
列表匹配器=新的ArrayList();
添加(新的AntPathRequestMatcher(“/**”,“选项”);
配置器。请求匹配器(新的或请求匹配器(匹配器));
};
}
请注意,根据您的应用程序,这可能会打开它进行潜在的利用


打开问题以获得更好的解决方案:

在某些情况下,需要添加
配置.setAllowedHeaders(Arrays.asList(“内容类型”)websecurityConfigureAdapter
解决cors问题时,将code>添加到
corscoConfiguration Source()

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

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

不推荐接受的答案,您不应该这样做。
下面是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;
    }
}

但是我想我们不能有像
这样的东西。是吗?根据,我不认为@PreAuthorize注释的情况下该如何工作,我希望Put方法具有管理员访问权限,Post方法具有用户访问权限在java配置中是等效的。请查看我的问题+1正是我们为启用CORS选项请求所做的。它工作正常,感谢您的提示我搜索和调试了很多,但无法修复现在我已修复它使用此tipsI在研究类似问题时找到了您的答案,该问题尚未以当前形式响应您的解决方案。你愿意看一看吗?以下是链接:这可能有助于一般理解:我自己不是JavaSpring用户,我在后端使用不同的语言时遇到了相同的问题。Java/Spring是否在安全性方面带来了任何额外的抽象,或者忽略所有选项请求的身份验证中间件方法基本上是安全的?这似乎是允许选项请求而不需要auhorization的唯一方法。如果您随后创建了一个要保护的选项端点,您将忘记配置中的排除,每个人都可以访问它。您应该考虑使用过滤器来允许CORS选项请求从Spring Security中排除:HtpSecurity是http.AuthigeRealStices()。“如果您随后创建了一个要保护的选项端点”@Tim为什么会有人需要它?
IgnoredRequestCustomizer
自spring boot 2以来已被弃用。
@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;
    }
}
$.ajaxSetup({
    // NOTE: Necessary for CORS
    crossDomain: true,
    xhrFields: {
        withCredentials: true
    }
});