微服务架构 | 服务之间跨域问题怎么解决?

Posted 码农架构

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务架构 | 服务之间跨域问题怎么解决?相关的知识,希望对你有一定的参考价值。

导读:跨域资源共享(cors)可以放宽浏览器的同源策略,可以通过浏览器让不同的网站和不同的服务器之间通信。

一、背景


当前微服务拆分已经成为趋势,大部分公司都对其软件产品做微服务架构调整。对产品先进行业务、模块拆分,大部分也进行前后端分离的业务调整。

服务拆分不能避免的问题那就是:请求跨域问题,针对跨域问题,先前专门做了资料整理

  • 什么是跨域?

  • 请求跨域会影响?

  • 跨域资源共享(cors)到底解决了什么?

针对这些问题可以查看 《SpringCloud 中跨域资源共享(cors)到底解决了什么?》

还有解决跨域问题开启跨域资源共享(cors)后。

  • 会有哪些影响?

  • 会不会被攻击?

  • 如果被攻击会有哪几种方式?

针对这系列问题可查看《微服务开启跨域资源共享(cors)后,真的会被攻击么?》

二、实战分享


▐  定义配置

阅读CorsConfiguration源码可以发现在CORS 配置中定义

  • allowedOrigins 允许访问域名列表
  • allowedMethods 允许方法列表
  • resolvedMethods 允许头访问列表
  • allowedHeaders 允许的请求头
  • exposedHeaders 拓展请求头
  • allowCredentials  允许凭据

基础CorsConfiguration的定义可自定义跨域配置信息CorsConfig 实现 CorsConfigurationSource

## Csrf 安全拦截
kmss.security.referers       = http:xxx.com.cn
## 跨域配置
## 允许访问的origin 列表
kmss.security.allowedOrigins = http://www.baidu.com,http://www.google.com
## 允许方法的方法列表
kmss.security.allowedMethods = GET,POST,HEAD,TRACE,OPTION
## 允许的请求头,一般不开启
kmss.security.allowedHeaders =

注意在配置时候引用注解@ConfigurationProperties为什么这里使用单一注解并没有直接注入到Bean容器中?针对这问题的分析可阅读《@EnableConfigurationProperties 的工作原理》

▐ 实现getCorsConfiguration方法

配置信息CorsConfig基础信息后实现getCorsConfiguration方法

@Override
public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
    CorsConfiguration configuration = null;
    
    // 根据配置结合业务写入CORS 配置
    /**
     *  allowedOrigins 允许访问域名列表
     *  allowedMethods 允许方法列表
     *  resolvedMethods 允许头访问列表
     *  allowedHeaders 允许的请求头
     *  exposedHeaders 拓展请求头
     *  allowCredentials  允许凭据
    **/
    return configuration;
}

 ▐ 定义 CorsSecurityFilter 拦截器

/**
 * cors安全
 */
public class CorsSecurityFilter extends CorsFilter {

    /**
     * 构造函数
     */
    public CorsSecurityFilter(CorsConfigurationSource configSource) {
        super(configSource);
    }

    /**
     * 避免类不被执行
     */
    @Override
    protected String getFilterName() {
        return null;
    }
}

 ▐ Web线程拦截器

定义Web线程拦截器为了,用于统一处理线程变量!同一个服务肯定不会出现跨域问题。只有不同服务之间调用才会出现此类问题。记得先前在分析 《怎样在输出日志中加入traceId 进行链路追踪》和 如何保证各个微服务之间调用的安全性?对个服务之间RPC调用请求线程变量传递问题。

/**
 * Web线程拦截器,用于统一处理线程变量
 *
 * 该过滤器执行顺序早于springsecurity的过滤器
 */
public class WebThreadFilter extends CompositeFilterProxy {
    /**
     * 应用上下文
     */
    private ApplicationContext applicationContext;
    
    /**
    * 跨站安全配置
    */
    private CorsConfig corsConfig;

   /**
    * http相关配置
    */
   private HttpConfig httpConfig;

  public WebThreadFilter(List<IWebFilterDef> filterDefs,
      List<SystemTag> systemTags) {
    super(filterDefs, systemTags);
    }

    @Override
    protected void initFilterBean() throws ServletException {
        applicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        corsConfig = applicationContext.getBean(CorsConfig.class);
    //...
        super.initFilterBean();
    }

    @Override
    protected void handleInnerFilters(List<Filter> innerFilters) {
        super.handleInnerFilters(innerFilters);
    //...
    innerFilters.add(0, new CorsSecurityFilter(corsConfig));
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {
    request = new ValidatorHttpServletRequestWrapper((HttpServletRequest) request,httpConfig);
    compositeFilter.doFilter(request, response, chain);
    }
}

三、总结


本文主要微服务之间跨域问题的解决方案,至于为什么会存在跨域问题和跨域问题开启后会有哪些攻击模式

在上几篇文章中已逐步分析,解决微服务跨域问题主要分三步走

  • 基于Spring-web 中 CorsConfiguration  重新定义CorsConfig 配置信息

  • 基于Spring-web 中 CorsFilter 重新实现拦截器 CorsSecurityFilter

  • 实现线程变量拦截与传递问题

 专注于高质量 技术文章原创分享与交流,拒绝水文、软文。

首发:微服务架构 | 服务之间跨域问题怎么解决?

以上是关于微服务架构 | 服务之间跨域问题怎么解决?的主要内容,如果未能解决你的问题,请参考以下文章

springcloud01-微服务和微服务架构

SpringCloud01:回顾微服务和微服务架构

微服务架构图

怎么解决服务器间的跨域问题

怎么理解微服务架构

微服务入门|微服务架构怎么设计