专栏首页算法之名spring cloud zuul网关的作用

spring cloud zuul网关的作用

zuul一般有两大作用,1是类似于Nginx的网址重定向,但zuul的重定向的一般是整个spring cloud里在Eureka注册中心的模块.

zuul:
  ignored-services: '*'
  sensitiveHeaders: Access-Control-Allow-Origin
  ignored-headers: Access-Control-Allow-Credentials,Access-Control-Allow-Origin,Vary,X-Frame-Options,token
  routes:
    oauth:
      path: /api-o/**
      serviceId: oauth-center
    api-u:
      path: /api-u/**
      serviceId: user-center
    backend:
      path: /api-b/**
      serviceId: manage-backend
    log:
      path: /api-l/**
      serviceId: log-center
    file:
      path: /api-f/**
      serviceId: file-center
    sms:
      path: /api-n/**
      serviceId: notification-center

**的意思是可以匹配任何多级目录的意思.

*为单级目录

sensitiveHeaders过滤客户端附带的headers,如:

sensitiveHeaders: X-ABC 如果在发请求时带了X-ABC,那么X-ABC不会往下游服务传递。此处为禁止跨域请求头向下传递

ignored-headers会过滤服务之间通信附带的headers

附带服务的跨域配置

/**
 * 跨域配置
 */
@Configuration
public class CrossDomainConfig {

    /**
     * 跨域支持
     *
     * @return
     */
    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许cookies跨域
        config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许
        config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
        config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
        config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

2、zuul更重要的功能为过滤请求.

public class AccessFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return null;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return false;
    }

    @Override
    public Object run() throws ZuulException {
        return null;
    }
}

我们自定义一个过滤类,继承于ZuulFilter,一般要实现上面四个方法.

filterType:过滤器的类型.

  • pre:可以在请求被路由之前调用
  • route:在路由请求时候被调用
  • post:在route和error过滤器之后被调用
  • error:处理请求时发生错误时被调用

org.springframework.cloud.netflix.zuul.filters.support.FilterConstants

中有这四种对应

public static final String ERROR_TYPE = "error";
public static final String POST_TYPE = "post";
public static final String PRE_TYPE = "pre";
public static final String ROUTE_TYPE = "route";

filterOrder:过滤器的执行顺序.当请求在一个阶段存在多个过滤器时,需要根据该方法返回的值来依次执行.

shouldFilter:判断该过滤器是否需要执行.

比如我们需要一个过滤条件,当包含"*-anon/internal*"的uri不允许外网通过网关调用,只允许微服务间在内网调用.我们可以这么写.

@Override
public boolean shouldFilter() {
   RequestContext requestContext = RequestContext.getCurrentContext();
   HttpServletRequest request = requestContext.getRequest();

   return PatternMatchUtils.simpleMatch("*-anon/internal*", request.getRequestURI());
}

最后就是run:过滤器的具体逻辑.

@Override
public Object run() {
   RequestContext requestContext = RequestContext.getCurrentContext();
   requestContext.setResponseStatusCode(HttpStatus.FORBIDDEN.value());
   requestContext.setResponseBody(HttpStatus.FORBIDDEN.getReasonPhrase());
   requestContext.setSendZuulResponse(false);

   return null;
}

返回403 Forbidden错误,通过requestContext.setSendZuulResponse(false)不进行路由.

请注意以上是只防外网的,内网的调用可以使用feign.比如说

@FeignClient("manage-backend")
public interface BackendClient {

   @GetMapping("/backend-anon/internal/blackIPs")
   Set<String> findAllBlackIPs(@RequestParam("params") Map<String, Object> params);
}

它是指向manage-backend模块的,而且@GetMapping("/backend-anon/internal/blackIPs")包含了"*-anon/internal*",即外网无法访问这个接口.具体实现为

@RestController
public class BlackIPController {

   @Autowired
   private BlackIPService blackIPService;

   /**
    * 添加黑名单ip
    * 
    * @param ip
    */
   @LogAnnotation(module = LogModule.ADD_BLACK_IP)
   @PreAuthorize("hasAuthority('ip:black:save')")
   @PostMapping("/blackIPs")
   public void save(@RequestBody BlackIP blackIP) {
      blackIP.setCreateTime(new Date());

      blackIPService.save(blackIP);
   }

   /**
    * 删除黑名单ip
    * 
    * @param ip
    */
   @LogAnnotation(module = LogModule.DELETE_BLACK_IP)
   @PreAuthorize("hasAuthority('ip:black:delete')")
   @DeleteMapping("/blackIPs/{ip}")
   public void delete(@PathVariable String ip) {
      blackIPService.delete(ip);
   }

   /**
    * 查询黑名单
    * 
    * @param params
    * @return
    */
   @PreAuthorize("hasAuthority('ip:black:query')")
   @GetMapping("/blackIPs")
   public Page<BlackIP> findBlackIPs(@RequestParam Map<String, Object> params) {
      return blackIPService.findBlackIPs(params);
   }

   /**
    * 查询黑名单<br>
    * 可内网匿名访问
    * 
    * @param params
    * @return
    */
   @GetMapping("/backend-anon/internal/blackIPs")
   public Set<String> findAllBlackIPs(@RequestParam Map<String, Object> params) {
      Page<BlackIP> page = blackIPService.findBlackIPs(params);
      if (page.getTotal() > 0) {
         return page.getData().stream().map(BlackIP::getIp).collect(Collectors.toSet());
      }
      return Collections.emptySet();
   }
}

中的

@GetMapping("/backend-anon/internal/blackIPs")
public Set<String> findAllBlackIPs(@RequestParam Map<String, Object> params) {
   Page<BlackIP> page = blackIPService.findBlackIPs(params);
   if (page.getTotal() > 0) {
      return page.getData().stream().map(BlackIP::getIp).collect(Collectors.toSet());
   }
   return Collections.emptySet();
}

当然它是属于manage-backend模块.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Springboot 2.0+FastDFS开发配置

    因为我们项目用的是Springboot 2.0以上的,所以跟Springboot 1.x的会有一些不同。

    算法之名
  • 用netty 3的channelbuffer来重写序列化类

    我们都知道用java来序列化一个对象,需要用到ObjectOutputSteam来把对象写进一个字节流ByteOutputStream,然后把字节流转成字节数组...

    算法之名
  • 设计模式整理 顶

    Iterator模式可以帮助我们分离具体的集合跟遍历,就是在代码中更换了集合,也可以不需要重新调用新集合的方法。

    算法之名
  • 设计模式(一) 支付策略模式

    公司最近在做直播功能,底层原来有一套直播API,现在新增一套网宿直播API。 考虑以后的扩展性,需要将两套API进行统一管理。现在以网上的支付方式演示我对策略模...

    用户1518699
  • 设计模式(一) 支付策略模式

    公司最近在做直播功能,底层原来有一套直播API,现在新增一套网宿直播API。 考虑以后的扩展性,需要将两套API进行统一管理。现在以网上的支付方式演示我对策略模...

    用户1518699
  • JAVA开发规范常用的技巧总结(共12个)

    例如:UserService,但是以下情景例外:DO / BO / PO / DTO / VO。

    牛油果
  • Spring Boot使用Shiro实现登录授权认证

    1、Shiro是Apache下的一个开源项目,我们称之为Apache Shiro。它是一个很易用与Java项目的的安全框架,提供了认证、授权、加密、会话管理,与...

    朝雨忆轻尘
  • SpringBoot 中 mongo多数据源配置新姿势

    SpringBoot对常用的数据库支持外,对NoSQL 数据库也进行了封装自动化。这一篇主要讲springboot与mongo多数据源相关的配置

    码农小胖哥
  • 阅读开源框架,总结Java类的定义

    即使我们明白Java的类,也未必清楚该如何正确地定义一个Java类。阅读一些开源框架的源代码,会启发我们灵感,并给出好代码的规范,提炼设计原则与模式。

    张逸
  • 自己动手写Android插件化框架

    本文旨在通过两个实例直观的说明插件的实现原理以加深对插件内开发的理解,因此不会深入探讨背景和原理,代码也尽量专注于核心逻辑。

    达文西

扫码关注云+社区

领取腾讯云代金券