Spring 安全 CORS 不适用于 Http PUT 方法
Spring Security CORS doesn't work for Http PUT method
当我尝试在 Postman 中 API 的 PutMapping
时,我得到了 'Invalid CORS request'。但它适用于 'POST' 和 'GET' 映射。
为什么它对 'PUT' 操作不起作用?
我的Spring引导版本: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");
}
}
@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 {..}
如果您的控制器需要处理 on-the-fly OPTION 请求,您可以将此方法添加到您的控制器。您可以通过端点配置值。
@RequestMapping(value = "/**/**",method = RequestMethod.OPTIONS)
public ResponseEntity handle() {
return new ResponseEntity(HttpStatus.OK);
}
它比公认的解决方案简单得多。
@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");
}
};
}
}
如果您使用的是 IIS 服务器这是 WebDAVModule 的问题,它似乎默认阻止 PUT 和 DELETE 方法!
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
</system.webServer>
我真的希望没有人因此而痛苦! =]
在 Spring 中,我使用 Kotlin 执行了以下操作:
@Bean
fun corsConfigurationSource(): CorsConfigurationSource? {
val source = UrlBasedCorsConfigurationSource()
val corsConfig = CorsConfiguration()
.applyPermitDefaultValues()
.setAllowedOriginPatterns(listOf("*"))
corsConfig.addAllowedMethod(HttpMethod.PUT)
source.registerCorsConfiguration("/**", corsConfig)
return source
}
我只想补充三点。
接受的答案和下面的答案是错误的 CORS 方法。
如果您正在尝试配置 CORS,这意味着您正在尝试让您的 API 只能由您认识的一些客户端访问。行数
configuration.setAllowedOrigins(ImmutableList.of("*")); // from the first answer
.addMapping("/**") // from the second answer
使任何客户端都可以访问 API。如果那是你想要的,你只需执行以下操作而无需配置另一个 bean
http.cors().disable()
当您允许 http
的来源并使用 https
进行请求时,问题中的问题可能会发生。所以请注意这两个是不同的。
以下是工作配置
// 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;
}
我正在使用 Spring 安全 和 Spring Boot 2.1.2。在我的特定情况下,在我从 CorsConfigurationSource bean 的 setAllowedMethods() 中显式声明“PUT”方法后,PUT 调用起作用。 headers 可以根据应用程序行为进行选择。
@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;
}
当我尝试在 Postman 中 API 的 PutMapping
时,我得到了 'Invalid CORS request'。但它适用于 'POST' 和 'GET' 映射。
为什么它对 'PUT' 操作不起作用?
我的Spring引导版本: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");
}
}
@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 {..}
如果您的控制器需要处理 on-the-fly OPTION 请求,您可以将此方法添加到您的控制器。您可以通过端点配置值。
@RequestMapping(value = "/**/**",method = RequestMethod.OPTIONS)
public ResponseEntity handle() {
return new ResponseEntity(HttpStatus.OK);
}
它比公认的解决方案简单得多。
@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");
}
};
}
}
如果您使用的是 IIS 服务器这是 WebDAVModule 的问题,它似乎默认阻止 PUT 和 DELETE 方法!
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<remove name="WebDAVModule" />
</modules>
</system.webServer>
我真的希望没有人因此而痛苦! =]
在 Spring 中,我使用 Kotlin 执行了以下操作:
@Bean
fun corsConfigurationSource(): CorsConfigurationSource? {
val source = UrlBasedCorsConfigurationSource()
val corsConfig = CorsConfiguration()
.applyPermitDefaultValues()
.setAllowedOriginPatterns(listOf("*"))
corsConfig.addAllowedMethod(HttpMethod.PUT)
source.registerCorsConfiguration("/**", corsConfig)
return source
}
我只想补充三点。
接受的答案和下面的答案是错误的 CORS 方法。 如果您正在尝试配置 CORS,这意味着您正在尝试让您的 API 只能由您认识的一些客户端访问。行数
configuration.setAllowedOrigins(ImmutableList.of("*")); // from the first answer .addMapping("/**") // from the second answer
使任何客户端都可以访问 API。如果那是你想要的,你只需执行以下操作而无需配置另一个 bean
http.cors().disable()
当您允许
http
的来源并使用https
进行请求时,问题中的问题可能会发生。所以请注意这两个是不同的。以下是工作配置
// 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; }
我正在使用 Spring 安全 和 Spring Boot 2.1.2。在我的特定情况下,在我从 CorsConfigurationSource bean 的 setAllowedMethods() 中显式声明“PUT”方法后,PUT 调用起作用。 headers 可以根据应用程序行为进行选择。
@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;
}