最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot升級至2.4.0中出現(xiàn)的跨域問題分析及修改方案

 更新時間:2020年12月04日 17:04:05   作者:lcjasas  
這篇文章主要介紹了Springboot升級至2.4.0中出現(xiàn)的跨域問題分析及修改方案,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

問題

Springboot升級至2.4.0中出現(xiàn)的跨域問題。
在Springboot 2.4.0版本之前使用的是2.3.5.RELEASE,對應(yīng)的Spring版本為5.2.10.RELEASE。
升級至2.4.0后,對應(yīng)的Spring版本為5.3.1。
Springboot2.3.5.RELEASE時,我們可以使用CorsFilter設(shè)置跨域。

分析

版本2.3.5.RELEASE 設(shè)置跨域

設(shè)置代碼如下:

@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
  @Bean
  public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // 允許訪問的客戶端域名
    config.addAllowedOrigin("*");
    // 允許服務(wù)端訪問的客戶端請求頭
    config.addAllowedHeader("*");
    // 允許訪問的方法名,GET POST等
    config.addAllowedMethod("*");
    // 對接口配置跨域設(shè)置
    source.registerCorsConfiguration("/**" , config);
    return new CorsFilter(source);
  }
}

是允許使用*設(shè)置允許的Origin。
這里我們看一下類CorsFilter的源碼,5.3.x版本開始,針對CorsConfiguration新增了校驗(yàn)

5.3.x源碼分析 CorsFilter

/**
 * {@link javax.servlet.Filter} to handle CORS pre-flight requests and intercept
 * CORS simple and actual requests with a {@link CorsProcessor}, and to update
 * the response, e.g. with CORS response headers, based on the policy matched
 * through the provided {@link CorsConfigurationSource}.
 *
 * <p>This is an alternative to configuring CORS in the Spring MVC Java config
 * and the Spring MVC XML namespace. It is useful for applications depending
 * only on spring-web (not on spring-webmvc) or for security constraints that
 * require CORS checks to be performed at {@link javax.servlet.Filter} level.
 *
 * <p>This filter could be used in conjunction with {@link DelegatingFilterProxy}
 * in order to help with its initialization.
 *
 * @author Sebastien Deleuze
 * @since 4.2
 * @see <a  rel="external nofollow" >CORS W3C recommendation</a>
 * @see UrlBasedCorsConfigurationSource
 */
public class CorsFilter extends OncePerRequestFilter {

	private final CorsConfigurationSource configSource;

	private CorsProcessor processor = new DefaultCorsProcessor();


	/**
	 * Constructor accepting a {@link CorsConfigurationSource} used by the filter
	 * to find the {@link CorsConfiguration} to use for each incoming request.
	 * @see UrlBasedCorsConfigurationSource
	 */
	public CorsFilter(CorsConfigurationSource configSource) {
		Assert.notNull(configSource, "CorsConfigurationSource must not be null");
		this.configSource = configSource;
	}


	/**
	 * Configure a custom {@link CorsProcessor} to use to apply the matched
	 * {@link CorsConfiguration} for a request.
	 * <p>By default {@link DefaultCorsProcessor} is used.
	 */
	public void setCorsProcessor(CorsProcessor processor) {
		Assert.notNull(processor, "CorsProcessor must not be null");
		this.processor = processor;
	}


	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
			FilterChain filterChain) throws ServletException, IOException {

		CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
		boolean isValid = this.processor.processRequest(corsConfiguration, request, response);
		if (!isValid || CorsUtils.isPreFlightRequest(request)) {
			return;
		}
		filterChain.doFilter(request, response);
	}

}

CorsFilter繼承自OncePerRequestFilterdoFilterInternal方法會被執(zhí)行。類中還創(chuàng)建了一個默認(rèn)的處理類DefaultCorsProcessor,doFilterInternal調(diào)用this.processor.processRequest
往下

processRequest

@Override
	@SuppressWarnings("resource")
	public boolean processRequest(@Nullable CorsConfiguration config, HttpServletRequest request,
			HttpServletResponse response) throws IOException {

		Collection<String> varyHeaders = response.getHeaders(HttpHeaders.VARY);
		if (!varyHeaders.contains(HttpHeaders.ORIGIN)) {
			response.addHeader(HttpHeaders.VARY, HttpHeaders.ORIGIN);
		}
		if (!varyHeaders.contains(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD)) {
			response.addHeader(HttpHeaders.VARY, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD);
		}
		if (!varyHeaders.contains(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS)) {
			response.addHeader(HttpHeaders.VARY, HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
		}

		if (!CorsUtils.isCorsRequest(request)) {
			return true;
		}

		if (response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN) != null) {
			logger.trace("Skip: response already contains \"Access-Control-Allow-Origin\"");
			return true;
		}

		boolean preFlightRequest = CorsUtils.isPreFlightRequest(request);
		if (config == null) {
			if (preFlightRequest) {
				rejectRequest(new ServletServerHttpResponse(response));
				return false;
			}
			else {
				return true;
			}
		}

		return handleInternal(new ServletServerHttpRequest(request), new ServletServerHttpResponse(response), config, preFlightRequest);
	}

進(jìn)入最后一行

handleInternal

/**
	 * Handle the given request.
	 */
	protected boolean handleInternal(ServerHttpRequest request, ServerHttpResponse response,
			CorsConfiguration config, boolean preFlightRequest) throws IOException {

		String requestOrigin = request.getHeaders().getOrigin();
		String allowOrigin = checkOrigin(config, requestOrigin);
		(省略...)
		response.flush();
		return true;
	}

查看方法checkOrigin

checkOrigin

@Nullable
	protected String checkOrigin(CorsConfiguration config, @Nullable String requestOrigin) {
		return config.checkOrigin(requestOrigin);
	}

Go on

checkOrigin

/**
	 * Check the origin of the request against the configured allowed origins.
	 * @param requestOrigin the origin to check
	 * @return the origin to use for the response, or {@code null} which
	 * means the request origin is not allowed
	 */
	@Nullable
	public String checkOrigin(@Nullable String requestOrigin) {
		if (!StringUtils.hasText(requestOrigin)) {
			return null;
		}
		if (!ObjectUtils.isEmpty(this.allowedOrigins)) {
			if (this.allowedOrigins.contains(ALL)) {
				validateAllowCredentials();
				return ALL;
			}
			for (String allowedOrigin : this.allowedOrigins) {
				if (requestOrigin.equalsIgnoreCase(allowedOrigin)) {
					return requestOrigin;
				}
			}
		}
		if (!ObjectUtils.isEmpty(this.allowedOriginPatterns)) {
			for (OriginPattern p : this.allowedOriginPatterns) {
				if (p.getDeclaredPattern().equals(ALL) || p.getPattern().matcher(requestOrigin).matches()) {
					return requestOrigin;
				}
			}
		}
		return null;
	}

方法validateAllowCredentials

validateAllowCredentials

/**
	 * Validate that when {@link #setAllowCredentials allowCredentials} is true,
	 * {@link #setAllowedOrigins allowedOrigins} does not contain the special
	 * value {@code "*"} since in that case the "Access-Control-Allow-Origin"
	 * cannot be set to {@code "*"}.
	 * @throws IllegalArgumentException if the validation fails
	 * @since 5.3
	 */
	public void validateAllowCredentials() {
		if (this.allowCredentials == Boolean.TRUE &&
				this.allowedOrigins != null && this.allowedOrigins.contains(ALL)) {

			throw new IllegalArgumentException(
					"When allowCredentials is true, allowedOrigins cannot contain the special value \"*\"" +
							"since that cannot be set on the \"Access-Control-Allow-Origin\" response header. " +
							"To allow credentials to a set of origins, list them explicitly " +
							"or consider using \"allowedOriginPatterns\" instead.");
		}

看一下ALL是什么

/** Wildcard representing <em>all</em> origins, methods, or headers. */
	public static final String ALL = "*";

所以如果使用2.4.0版本,還是設(shè)置*的話,訪問API接口就會報錯:

異常

java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*"since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.
	at org.springframework.web.cors.CorsConfiguration.validateAllowCredentials(CorsConfiguration.java:457)
	at org.springframework.web.cors.CorsConfiguration.checkOrigin(CorsConfiguration.java:561)
	at org.springframework.web.cors.DefaultCorsProcessor.checkOrigin(DefaultCorsProcessor.java:174)
	at org.springframework.web.cors.DefaultCorsProcessor.handleInternal(DefaultCorsProcessor.java:116)
	at org.springframework.web.cors.DefaultCorsProcessor.processRequest(DefaultCorsProcessor.java:95)
	at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:87)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

修改方式

方式1

不使用CorsFilter,直接重寫方法addCorsMappings

@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
  /**
   * 跨域配置
   */
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    //對那些請求路徑進(jìn)行跨域處理
    registry.addMapping("/**")
        // 允許的請求頭,默認(rèn)允許所有的請求頭
        .allowedHeaders("*")
        // 允許的方法,默認(rèn)允許GET、POST、HEAD
        .allowedMethods("*")
        // 探測請求有效時間,單位秒
        .maxAge(1800)
        // 支持的域
        .allowedOrigins("*");
  }
}

方式2

繼續(xù)使用CorsFilter,使用官方推薦的allowedOriginPatterns
application.yml中新增配置:
(注:這里只是舉個栗子…Origin的處理)

# 項(xiàng)目相關(guān)配置
project:
 uiPort: 8082
 basePath: http://localhost:${project.uiPort}
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
	@Value("${project.basePath}")
  private String basePath;

  @Bean
  public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // 允許訪問的客戶端域名
    List<String> allowedOriginPatterns = new ArrayList<>();
    allowedOriginPatterns.add(basePath);
    config.setAllowedOriginPatterns(allowedOriginPatterns);
//    config.addAllowedOrigin(serverPort);
    // 允許服務(wù)端訪問的客戶端請求頭
    config.addAllowedHeader("*");
    // 允許訪問的方法名,GET POST等
    config.addAllowedMethod("*");
    // 對接口配置跨域設(shè)置
    source.registerCorsConfiguration("/**" , config);
    return new CorsFilter(source);
  }
}

到此這篇關(guān)于Springboot升級至2.4.0中出現(xiàn)的跨域問題分析及修改方案的文章就介紹到這了,更多相關(guān)Springboot2.4.0跨域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • idea中service或者mapper引入報紅的問題及解決

    idea中service或者mapper引入報紅的問題及解決

    在使用IntelliJ IDEA開發(fā)SpringBoot項(xiàng)目時,有時會遇到Service或Mapper接口引入時報紅但不影響項(xiàng)目運(yùn)行的情況,這主要是因?yàn)镮DEA的檢查級別設(shè)置問題,解決方法是將有問題的Error級別改為編譯通過的安全級別,即可消除報紅
    2024-09-09
  • Spark Streaming編程初級實(shí)踐詳解

    Spark Streaming編程初級實(shí)踐詳解

    這篇文章主要為大家介紹了Spark Streaming編程初級實(shí)踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Eclipse可視化插件WindowBuilder的安裝方法

    Eclipse可視化插件WindowBuilder的安裝方法

    這篇文章主要介紹了Eclipse可視化插件WindowBuilder的安裝方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • DolphinScheduler容錯Master源碼分析

    DolphinScheduler容錯Master源碼分析

    這篇文章主要為大家介紹了DolphinScheduler容錯Master源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • kafka分布式消息系統(tǒng)基本架構(gòu)及功能詳解

    kafka分布式消息系統(tǒng)基本架構(gòu)及功能詳解

    這篇文章主要為大家介紹了kafka分布式消息系統(tǒng)基本架構(gòu)及功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Java 生成任意長度的驗(yàn)證碼過程解析

    Java 生成任意長度的驗(yàn)證碼過程解析

    這篇文章主要介紹了Java 生成任意長度的驗(yàn)證碼過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • Java如何獲取真實(shí)請求IP

    Java如何獲取真實(shí)請求IP

    這篇文章主要介紹了Java如何獲取真實(shí)請求IP問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • SpringBoot訪問windows共享文件的方法

    SpringBoot訪問windows共享文件的方法

    這篇文章主要介紹了SpringBoot訪問windows共享文件,項(xiàng)目使用minio存儲且不在同一臺服務(wù)器上,為了優(yōu)化速度決定使用windows共享功能進(jìn)行文件傳輸,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • 最新JVM垃圾回收算法詳解

    最新JVM垃圾回收算法詳解

    ? 垃圾收集器對堆進(jìn)行回收前,首先要確定堆中的對象哪些還"存活",哪些已經(jīng)"死去"。有兩種算法,分別是引用計(jì)數(shù)算法(Recference?Counting)和可達(dá)性分析算法(Reachability?Analysis),這篇文章主要介紹了JVM垃圾回收算法,需要的朋友可以參考下
    2022-05-05
  • java進(jìn)行遠(yuǎn)程部署與調(diào)試及原理詳解

    java進(jìn)行遠(yuǎn)程部署與調(diào)試及原理詳解

    這篇文章主要介紹了java進(jìn)行遠(yuǎn)程部署與調(diào)試及原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12

最新評論

金塔县| 宣城市| 孝感市| 平江县| 临城县| 射洪县| 马尔康县| 五大连池市| 轮台县| 太保市| 韩城市| 蒲江县| 马关县| 新邵县| 景谷| 汝州市| 蛟河市| 新野县| 潜江市| 吉水县| 积石山| 虎林市| 常德市| 墨竹工卡县| 阳城县| 南溪县| 新昌县| 盐边县| 沧源| 邢台市| 抚顺县| 屏东县| 万荣县| 彰化市| 天津市| 阿勒泰市| 平江县| 松滋市| 莫力| 福海县| 东乡|