Spring @CrossOrigin快速解决接口跨域问题(包含Springboot方式)

阅读: 评论:0

Spring @CrossOrigin快速解决接口跨域问题(包含Springboot方式)

Spring @CrossOrigin快速解决接口跨域问题(包含Springboot方式)

出于安全原因,浏览器禁止Ajax调用驻留在当前原点之外的资源。例如,当你在一个标签中检查你的银行账户时,你可以在另一个选项卡上拥有EVILL网站。来自EVILL的脚本不能够对你的银行API做出Ajax请求(从你的帐户中取出钱!)使用您的凭据。

跨源资源共享(CORS)是由大多数浏览器实现的W3C规范,允许您灵活地指定什么样的跨域请求被授权,而不是使用一些不太安全和不太强大的策略,如IFRAME或JSONP。

跨域是跨服务之间调用需要解决的问题,无论是Ajax还是后端接口,跨域问题都需要解决,无论是通过Nginx还是代码配置。

Spring @CrossOrigin注解源码

/** Copyright 2002-2019 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      .0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package org.springframework.web.bind.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;import annotation.AliasFor;
import org.s.CorsConfiguration;/*** Annotation for permitting cross-origin requests on specific handler classes* and/or handler methods. Processed if an appropriate {@code HandlerMapping}* is configured.** <p>Both Spring Web MVC and Spring WebFlux support this annotation through the* {@code RequestMappingHandlerMapping} in their respective modules. The values* from each type and method level pair of annotations are added to a* {@link CorsConfiguration} and then default values are applied via* {@link CorsConfiguration#applyPermitDefaultValues()}.** <p>The rules for combining global and local configuration are generally* additive -- e.g. all global and all local origins. For those attributes* where only a single value can be accepted such as {@code allowCredentials}* and {@code maxAge}, the local overrides the global value.* See {@link CorsConfiguration#combine(CorsConfiguration)} for more details.** @author Russell Allen* @author Sebastien Deleuze* @author Sam Brannen* @since 4.2*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */@DeprecatedString[] DEFAULT_ORIGINS = {"*"};/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */@DeprecatedString[] DEFAULT_ALLOWED_HEADERS = {"*"};/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */@Deprecatedboolean DEFAULT_ALLOW_CREDENTIALS = false;/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */@Deprecatedlong DEFAULT_MAX_AGE = 1800;/*** Alias for {@link #origins}.*/@AliasFor("origins")String[] value() default {};/*** The list of allowed origins that be specific origins, e.g.* {@code ""}, or {@code "*"} for all origins.* <p>A matched origin is listed in the {@code Access-Control-Allow-Origin}* response header of preflight actual CORS requests.* <p>By default all origins are allowed.* <p><strong>Note:</strong> CORS checks use values from "Forwarded"* (<a href="">RFC 7239</a>),* "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,* if present, in order to reflect the client-originated address.* Consider using the {@code ForwardedHeaderFilter} in order to choose from a* central place whether to extract and use, or to discard such headers.* See the Spring Framework reference for more on this filter.* @see #value*/@AliasFor("value")String[] origins() default {};/*** The list of request headers that are permitted in actual requests,* possibly {@code "*"}  to allow all headers.* <p>Allowed headers are listed in the {@code Access-Control-Allow-Headers}* response header of preflight requests.* <p>A header name is not required to be listed if it is one of:* {@code Cache-Control}, {@code Content-Language}, {@code Expires},* {@code Last-Modified}, or {@code Pragma} as per the CORS spec.* <p>By default all requested headers are allowed.*/String[] allowedHeaders() default {};/*** The List of response headers that the user-agent will allow the client* to access on an actual response, other than "simple" headers, i.e.* {@code Cache-Control}, {@code Content-Language}, {@code Content-Type},* {@code Expires}, {@code Last-Modified}, or {@code Pragma},* <p>Exposed headers are listed in the {@code Access-Control-Expose-Headers}* response header of actual CORS requests.* <p>By default no headers are listed as exposed.*/String[] exposedHeaders() default {};/*** The list of supported HTTP request methods.* <p>By default the supported methods are the same as the ones to which a* controller method is mapped.*/RequestMethod[] methods() default {};/*** Whether the browser should send credentials, such as cookies along with* cross domain requests, to the annotated endpoint. The configured value is* set on the {@code Access-Control-Allow-Credentials} response header of* preflight requests.* <p><strong>NOTE:</strong> Be aware that this option establishes a high* level of trust with the configured domains and also increases the surface* attack of the web application by exposing sensitive user-specific* information such as cookies and CSRF tokens.* <p>By default this is not set in which case the* {@code Access-Control-Allow-Credentials} header is also not set and* credentials are therefore not allowed.*/String allowCredentials() default "";/*** The maximum age (in seconds) of the cache duration for preflight responses.* <p>This property controls the value of the {@code Access-Control-Max-Age}* response header of preflight requests.* <p>Setting this to a reasonable value can reduce the number of preflight* request/response interactions required by the browser.* A negative value means <em>undefined</em>.* <p>By default this is set to {@code 1800} seconds (30 minutes).*/long maxAge() default -1;}

Spring @CrossOrigin解决跨域

以下内容来自:.html

跨域(CORS)支持

  Spring Framework 4.2 GA为CORS提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它。所以springMVC的版本要在4.2或以上版本才支持@CrossOrigin

使用方法

1、controller配置CORS

1.1、controller方法的CORS配置,您可以向@RequestMapping注解处理程序方法添加一个@CrossOrigin注解,以便启用CORS(默认情况下,@CrossOrigin允许在@RequestMapping注解中指定的所有源和HTTP方法):

@RestController
@RequestMapping("/account") public class AccountController {@CrossOrigin@GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ...}@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ...}
}

其中@CrossOrigin中的2个参数:

origins : 允许可访问的域列表

maxAge:准备响应前的缓存持续的最大时间(以秒为单位)。

1.2、为整个controller启用@CrossOrigin

@CrossOrigin(origins = "", maxAge = 3600)
@RestController
@RequestMapping("/account") public class AccountController {@GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ...}@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ...}
}

在这个例子中,对于retrieve()和remove()处理方法都启用了跨域支持,还可以看到如何使用@CrossOrigin属性定制CORS配置。

1.3、同时使用controller和方法级别的CORS配置,Spring将合并两个注释属性以创建合并的CORS配置。

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account") public class AccountController {@CrossOrigin(origins = "")@GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ...}@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ...}
}

1.4、如果您正在使用Spring Security,请确保在Spring安全级别启用CORS,并允许它利用Spring MVC级别定义的配置。

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

2、全局CORS配置

  除了细粒度、基于注释的配置之外,您还可能需要定义一些全局CORS配置。这类似于使用筛选器,但可以声明为Spring MVC并结合细粒度@CrossOrigin配置。默认情况下,所有origins and GET, HEAD and POST methods是允许的。

JavaConfig

使整个应用程序的CORS简化为:

@Configuration
@EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter {@Override public void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**");}
}

如果您正在使用Spring Boot,建议将WebMvcConfigurer bean声明如下:

@Configuration public class MyConfiguration {@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() {@Override public void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**");}};}
}

您可以轻松地更改任何属性,以及仅将此CORS配置应用到特定的路径模式:

@Override public void addCorsMappings(CorsRegistry registry) {registry.addMapping("/api/**").allowedOrigins("").allowedMethods("PUT", "DELETE").allowedHeaders("header1", "header2", "header3").exposedHeaders("header1", "header2").allowCredentials(false).maxAge(3600);
}

如果您正在使用Spring Security,请确保在Spring安全级别启用CORS,并允许它利用Spring MVC级别定义的配置。

3、XML命名空间

还可以将CORS与MVC XML命名空间配置。

a、如果整个项目所有方法都可以访问,则可以这样配置;此最小XML配置使CORS在/**路径模式具有与JavaConfig相同的缺省属性:

<mvc:cors><mvc:mapping path="/**" />
</mvc:cors>

其中 表示匹配到下一层;***** 表示后面不管有多少层,都能匹配。**

如:

<mvc:cors>  <mvc:mapping path="/api/*"/>  
</mvc:cors>  

这个可以匹配到的路径有:

/api/aaa/api/bbbb

不能匹配的:

/api/aaa/bbb

因为* 只能匹配到下一层路径,如果想后面不管多少层都可以匹配,配置如下:

<mvc:cors>  <mvc:mapping path="/api/**"/>  
</mvc:cors>  

注:其实就是一个(*)变成两个(**)

b、也可以用定制属性声明几个CORS映射:

<mvc:cors><mvc:mapping path="/api/**" allowed-origins=", " allowed-methods="GET, PUT" allowed-headers="header1, header2, header3" exposed-headers="header1, header2" allow-credentials="false" max-age="123" /><mvc:mapping path="/resources/**" allowed-origins="" /></mvc:cors>

请求路径有/api/,方法示例如下:

@RequestMapping("/api/crossDomain")  
@ResponseBody public String crossDomain(HttpServletRequest req, HttpServletResponse res, String name){  ……  ……  
} 

c、如果使用Spring Security,不要忘记在Spring安全级别启用CORS:

<http><!-- Default to Spring MVC's CORS configuration --><cors /> ... </http>

4、How does it work?

  CORS请求(包括预选的带有选项方法)被自动发送到注册的各种HandlerMapping 。它们处理CORS准备请求并拦截CORS简单和实际请求,这得益于CorsProcessor实现(默认情况下默认DefaultCorsProcessor处理器),以便添加相关的CORS响应头(如Access-Control-Allow-Origin)。 CorsConfiguration 允许您指定CORS请求应该如何处理:允许origins, headers, methods等。

a、AbstractHandlerMapping#setCorsConfiguration() 允许指定一个映射,其中有几个CorsConfiguration 映射在路径模式上,比如/api/**。

b、子类可以通过重写AbstractHandlerMapping类的getCorsConfiguration(Object, HttpServletRequest)方法来提供自己的CorsConfiguration。

c、处理程序可以实现 CorsConfigurationSource接口(如ResourceHttpRequestHandler),以便为每个请求提供一个CorsConfiguration。

5、基于过滤器的CORS支持

  作为上述其他方法的替代,Spring框架还提供了CorsFilter。在这种情况下,不用使用@CrossOrigin或 WebMvcConfigurer#addCorsMappings(CorsRegistry),例如,可以在Spring Boot应用程序中声明如下的过滤器:

@Configuration public class MyConfiguration {@Bean public FilterRegistrationBean corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);config.addAllowedOrigin("");config.addAllowedHeader("*");config.addAllowedMethod("*");isterCorsConfiguration("/**", config);FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));bean.setOrder(0); return bean;}
}

Spring注解@CrossOrigin不起作用的原因

1、是springMVC的版本要在4.2或以上版本才支持@CrossOrigin

2、非@CrossOrigin没有解决跨域请求问题,而是不正确的请求导致无法得到预期的响应,导致浏览器端提示跨域问题。

3、在Controller注解上方添加@CrossOrigin注解后,仍然出现跨域问题,解决方案之一就是:

在@RequestMapping注解中没有指定Get、Post方式,具体指定后,问题解决。

类似代码如下:

@CrossOrigin
@RestController public class person{@RequestMapping(method = RequestMethod.GET) public String add() { // 若干代码}
}

参考文章

1、官方文档

2、

2、

3、

 


标题:注解@CrossOrigin解决跨域问题
作者:mmzsblog
地址:.html

 

本文发布于:2024-02-02 02:20:07,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170681463040762.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:接口   快速   方式   Spring   CrossOrigin
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23