【问题标题】:Spring Security CORS doesn't work for Http PUT methodSpring Security CORS 不适用于 Http PUT 方法
【发布时间】:2018-08-26 06:56:34
【问题描述】:

当我尝试在 Postman 中使用我的 API 的 PutMapping 时,我收到“无效的 CORS 请求”。但它适用于“POST”和“GET”映射。

为什么它不适用于“PUT”操作?

我的 Spring Boot 版本:2.0

这是我的配置:

@Override
protected void configure(HttpSecurity http) throws Exception {




    http.cors().and().csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/h2-console/**/**").permitAll()
            .antMatchers(HttpMethod.GET,"/user/get-request").permitAll()
            .antMatchers(HttpMethod.POST,"/user/post-request").permitAll()
            .antMatchers(HttpMethod.PUT,"/user/put-request").permitAll()
            .and()
            .exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
            .and()
            .addFilter(new JwtAuthenticationFilter(authenticationManager()))
            .addFilter(new JwtAuthorizationFilter(authenticationManager(), jwtUserDetailService));




}


@Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("*").allowedHeaders("*").exposedHeaders("Authorization");

            }
        };
    }

这是我的控制器:

@RestController
@RequestMapping("/user")
public class UserController {

@PutMapping("/put-request")
public void doResetPassword(@RequestBody String password) {
    System.out.println("PUT MAPPING");


}

@PostMapping("/post-request")
public void doResetPassword(@RequestBody String password) {
    System.out.println("POST MAPPING");


}

@GetMapping("/get-request")
public void doResetPassword() {
    System.out.println("GET MAPPING");


}

}

【问题讨论】:

  • 对于忽略请求方法检查,您可以添加:.allowedMethods("*")

标签: spring security spring-boot cors put


【解决方案1】:

它比公认的解决方案简单得多。

@Configuration
public class CrossOriginConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry
                        .addMapping("/**")
                        .allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS");
            }
        };
    }

}

【讨论】:

  • 这行得通!并且比公认的解决方案更简单。谢谢!
  • 感谢您提供更简单的解决方案,请接受此作为答案!
【解决方案2】:
@Bean
public CorsConfigurationSource corsConfigurationSource() {
    final CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(ImmutableList.of("*"));
    configuration.setAllowedMethods(ImmutableList.of("HEAD",
            "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
    configuration.setAllowCredentials(true);
    configuration.setAllowedHeaders(ImmutableList.of("*"));
    configuration.setExposedHeaders(ImmutableList.of("X-Auth-Token","Authorization","Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));
    final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

我设法通过添加这个 bean 来允许 cors 请求。您可以根据需要配置 setAllowedHeaders() 和 setExposedHeaders()。

另外,我将这一行添加到我的控制器中;

@RequestMapping(value = "/auth")
@RestController
@CrossOrigin(origins = "*") //this line
public class AuthenticationController {..}

如果您的控制器需要处理即时 OPTION 请求,您可以将此方法添加到您的控制器。您可以通过端点配置值。

@RequestMapping(value = "/**/**",method = RequestMethod.OPTIONS)
public ResponseEntity handle() {
    return new ResponseEntity(HttpStatus.OK);
}

【讨论】:

  • hanks,这个注释解决了问题 '@CrossOrigin(origins = "*")' ,但我很困惑为什么我们需要它,我们已经在配置中指定了来源类。
  • 我对这个注释还有一个问题:'@RequestMapping(value = "/**/**",method = RequestMethod.OPTIONS)'**,它适用于什么样的场景?
  • 我不是专家,但我认为我们需要映射哪些端点允许跨域请求。所以,这就是为什么我们需要将@CrossOrigin 注解放在控制器上。希望有相关知识的人能解释一下。
  • 第二个问题,看看这个stackoverflow.com/questions/12569308/…
  • 我知道它会处理所有 Option 请求,但在哪些情况下我们需要它?
【解决方案3】:

如果您使用的是 IIS 服务器 这是 WebDAVModule 的问题,它似乎默认阻止 PUT 和 DELETE 方法!

<system.webServer>
  <modules runAllManagedModulesForAllRequests="false">
    <remove name="WebDAVModule" />
  </modules>
</system.webServer>

我真的希望没有其他人因此而痛苦! =]

字体:https://mozartec.com/asp-net-core-error-405-methods-not-allowed-for-put-and-delete-requests-when-hosted-on-iis/

【讨论】:

    【解决方案4】:

    在使用 Kotlin 的 Spring 中,我做了以下事情:

    @Bean
    fun corsConfigurationSource(): CorsConfigurationSource? {
        val source = UrlBasedCorsConfigurationSource()
    
        val corsConfig = CorsConfiguration()
            .applyPermitDefaultValues()
            .setAllowedOriginPatterns(listOf("*"))
        corsConfig.addAllowedMethod(HttpMethod.PUT)
        source.registerCorsConfiguration("/**", corsConfig)
    
        return source
    }
    

    【讨论】:

      【解决方案5】:

      我只想添加 3 件事。

      1. 接受的答案和下面的答案是错误的 CORS 方法。 如果您尝试配置 CORS,这意味着您正在尝试使您的 API 只能由您认识的许多客户端访问。线条

        configuration.setAllowedOrigins(ImmutableList.of("*")); // from the first answer
        
        .addMapping("/**") // from the second answer
        

        让任何客户端都可以访问 API。如果这是您想要的,您可以执行以下操作而无需配置另一个 bean

        http.cors().disable()
        
      2. 当您使用http 允许来源并使用https 执行您的请求时,可能会出现问题中的问题。所以请注意,这两个是不同的。

      3. 下面是一个工作配置

        // In the import section
        import static org.springframework.security.config.Customizer.withDefaults;
        
        // In the HttpSecurity configuration
        http.cors(withDefaults())
        
         @Bean
         public CorsConfigurationSource corsConfigurationSource() {
           final CorsConfiguration configuration = new CorsConfiguration();
           configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200", "https://localhost:4200"));
           configuration.setAllowedMethods(Arrays.asList("HEAD",
                 "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
           configuration.setAllowCredentials(true);
           configuration.setAllowedHeaders(Arrays.asList("Content-Type", "X-Auth-Token","Authorization","Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));
           configuration.setExposedHeaders(Arrays.asList("Content-Type", "X-Auth-Token","Authorization","Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));
           final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
           source.registerCorsConfiguration("/**", configuration);
           return source;
         }
        

      【讨论】:

        【解决方案6】:

        我正在使用 Spring SecuritySpring Boot 2.1.2。在我的具体情况下,PUT 调用在我从 CorsConfigurationSource bean 的 setAllowedMethods() 中显式声明“PUT”方法之后起作用。可以根据应用程序行为选择标头。

        @Bean
        CorsConfigurationSource corsConfigurationSource() {
            final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            final String headers =  "Authorization, Access-Control-Allow-Headers, "+
                                    "Origin, Accept, X-Requested-With, Content-Type, " + 
                                    "Access-Control-Request-Method, Custom-Filter-Header";
            
            CorsConfiguration config = new CorsConfiguration();
        
            config.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE")); // Required for PUT method
            config.addExposedHeader(headers);
            config.setAllowCredentials(true);
            config.applyPermitDefaultValues();
            
            source.registerCorsConfiguration("/**", config);
            
            return source;
        }
        

        【讨论】:

          猜你喜欢
          • 2016-03-13
          • 2020-10-27
          • 2013-10-29
          • 1970-01-01
          • 1970-01-01
          • 2017-10-30
          • 1970-01-01
          • 2021-03-25
          • 1970-01-01
          相关资源
          最近更新 更多