Gateway+Security+oauth2跨域配置失效
首先贴上的默认Gateway的跨域配置
@ConfigurationpublicclassGatewayCrosConfiguration{@BeanpublicCorsWebFiltercorsWebFilter(){CorsConfiguration corsConfiguration=newCorsConfiguration();
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);UrlBasedCorsConfigurationSource source=newUrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);returnnewCorsWebFilter(source);}}
先说明一点,如果没有配置别的过滤器,这样的跨域配置是没有问题的,也可以在yml或者propertits文件里面配置这个Bean,通过spi机制,SpringBoot会自动加载进过滤器链
我的问题是由于配置了Security+oauth2,首先明确一点sceurtiy底层就是通过过滤器来处理权限的判断的可能是过滤器的优先级的问题,可能是过滤器优先级的问题,个人这部分没有理解到,因为配置的SecurityWebFilterChain里面的
Flux 字段,明明上面的配置类corsWebFilter是WebFilter的接口实现类,按理来说会自动把跨域的过滤器加入到SecurityWebFilterChain里面,经过打断点发现并没有
后面发现了SecurityWebFilterChain是ServerHttpSecurity类来创建的,这个类里面可以有个方法如下
/**
* Adds a {@link WebFilter} before specific position.
* @param webFilter the {@link WebFilter} to add
* @param order the place before which to insert the {@link WebFilter}
* @return the {@link ServerHttpSecurity} to continue configuring
* @since 5.2.0
* @author Ankur Pathak
*/publicServerHttpSecurityaddFilterBefore(WebFilter webFilter,SecurityWebFiltersOrder order){this.webFilters.add(newOrderedWebFilter(webFilter, order.getOrder()-1));returnthis;}
大致意思是添加在Security过滤器之前就执行的webFilter,第一个参数就是webFilter,我们就可以把自己定义的跨域过滤器的加入进去,后面是这指定这个过滤器的等级,是个枚举类,进去发现惊喜,有个CORS常量
到此就完结了,在这里面把跨域处理加入就ok
贴上最终配置,主要看重点对跨域的配置,别的都是scetiry的 相关东西
@BeanpublicSecurityWebFilterChainspringSecurityFilterChain(ServerHttpSecurity http){
http.oauth2ResourceServer().jwt().jwtAuthenticationConverter(jwtAuthenticationConverter());// 1、自定义处理JWT请求头过期或签名错误的结果
http.oauth2ResourceServer().authenticationEntryPoint(restAuthenticationEntryPoint);// 2、添加跨域的过滤器
http.addFilterBefore(corsWebFilter,SecurityWebFiltersOrder.CORS);// 3、对白名单路径,直接移除JWT请求头
http.addFilterBefore(ignoreUrlsRemoveJwtFilter,SecurityWebFiltersOrder.AUTHENTICATION);
http.authorizeExchange().pathMatchers(ArrayUtil.toArray(ignoreUrlsConfig.getUrls(),String.class)).permitAll()// 白名单配置.anyExchange().access(authorizationManager)// 鉴权管理器配置.and().exceptionHandling().accessDeniedHandler(restfulAccessDeniedHandler)// 处理未授权.authenticationEntryPoint(restAuthenticationEntryPoint)// 处理未认证.and().csrf().disable();return http.build();}