Soul网关(十六)---- 请求的拦截和重写

waf 插件和 rewrite 插件

    • waf 插件
      • 简介
      • 使用
        • 1)首先在 soul-admin 中开启 waf 插件
        • 2)soul-bootstrap 的 pom 文件中添加 waf 插件starter 的依赖
        • 3)然后在 soul-admin 的 waf 插件中添加 过滤器 和 规则 对非法请求/异常请求进行拒绝
      • 源码分析
        • waf 插件关键源码解读:
      • waf 插件总结
    • rewrite 插件
      • 简介
      • 使用
        • 1)首先在 soul-admin 中开启 rewrite 插件
        • 2)soul-bootstrap 的 pom 文件中添加 rewrite 插件starter 的依赖
        • 3) 然后在 soul-admin 的 rewrite 插件中添加 过滤器 和 规则 对请求 URI 进行重写
      • 源码分析
        • rewrite 插件关键源码解读:
      • rewrite 插件总结

waf 插件

简介

waf 插件是 soul 的前置插件,主要用来拦截非法请求,或者异常请求,并且给与相关的拒绝策略,是 soul 网关的用来对流量实现防火墙功能的核心实现。

使用

1)首先在 soul-admin 中开启 waf 插件

2)soul-bootstrap 的 pom 文件中添加 waf 插件starter 的依赖

<dependency>
    <groupId>org.dromaragroupId>
    <artifactId>soul-spring-boot-starter-plugin-wafartifactId>
    <version>${project.version}version>
dependency>

3)然后在 soul-admin 的 waf 插件中添加 过滤器 和 规则 对非法请求/异常请求进行拒绝

这里将 URL 为 /waf/test 的请求设置为拒绝,返回的状态码设置为 429:

Soul网关(十六)---- 请求的拦截和重写_第1张图片

请求 http://localhost:9195/waf/test 便会被直接拒绝:

{
     
  "code": 426,
  "message": " You are forbidden to visit",
  "data": null
}

源码分析

waf 插件关键源码解读:

protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
     
  	// 拿到流量防火墙配置,默认是黑名单模式
    WafConfig wafConfig = Singleton.INST.get(WafConfig.class);
  
    if (Objects.isNull(selector) && Objects.isNull(rule)) {
     
        // waf插件如果没有配置选择器和规则,而且是黑名单模式的话,请求会被放行到下一个插件
        if (WafModelEnum.BLACK.getName().equals(wafConfig.getModel())) {
     
            return chain.execute(exchange);
        }
        // 如果是混合模式,会返回 403
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        Object error = SoulResultWrap.error(403, Constants.REJECT_MSG, null);
        return WebFluxResultUtils.result(exchange, error);
    }
    // 拿到匹配的规则,如:{"permission":"reject","statusCode":"426"}
    String handle = rule.getHandle();
    // 将规则转换成 WafHandle 类型,如:WafHandle(permission=reject, statusCode=426)
    WafHandle wafHandle = GsonUtils.getInstance().fromJson(handle, WafHandle.class);
    if (Objects.isNull(wafHandle) || StringUtils.isBlank(wafHandle.getPermission())) {
     
        // 没有 WafHandle ,请求就直接放行
        log.error("waf handler can not configuration:{}", handle);
        return chain.execute(exchange);
    }
  
    // 如果当前规则配置的是:拒绝访问
    if (WafEnum.REJECT.getName().equals(wafHandle.getPermission())) {
     
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        // 从规则中拿出配置的状态码并返回
        Object error = SoulResultWrap.error(Integer.parseInt(wafHandle.getStatusCode()), Constants.REJECT_MSG, null);
        return WebFluxResultUtils.result(exchange, error);
    }
    // 当前请求被允许,则放行请求
    return chain.execute(exchange);
}

waf 插件总结

总的来说,waf 插件就相当于一个全局的请求拦截器,当请求属于黑名单的时候,会直接拒绝请求,反之,则放心请求到下一个插件。比较灵活的一点是:请求的黑白名单,可以在 soul-admin 中通过选择器和规则进行方便的配置。

rewrite 插件

简介

rewrite 插件用来对请求 URI 进行重新定义。当匹配到请求之后,如果设置了自定义路径,那么自定义的路径就会覆盖之前的请求路径。

使用

1)首先在 soul-admin 中开启 rewrite 插件

2)soul-bootstrap 的 pom 文件中添加 rewrite 插件starter 的依赖

<dependency>
    <groupId>org.dromaragroupId>
    <artifactId>soul-spring-boot-starter-plugin-rewriteartifactId>
    <version>${project.version}version>
dependency>

3) 然后在 soul-admin 的 rewrite 插件中添加 过滤器 和 规则 对请求 URI 进行重写

源码分析

rewrite 插件关键源码解读:

protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
     
    // 从匹配到的规则中获取 handle,如:{"rewriteURI":"/http/order/findById"}
    String handle = rule.getHandle();
    // 转换成 RewriteHandle,如:RewriteHandle(rewriteURI=/http/order/findById)
    final RewriteHandle rewriteHandle = GsonUtils.getInstance().fromJson(handle, RewriteHandle.class);
  
    if (Objects.isNull(rewriteHandle) || StringUtils.isBlank(rewriteHandle.getRewriteURI())) {
     
      	// 没有匹配到,则直接放行请求,不做重写处理
        log.error("uri rewrite rule can not configuration:{}", handle);
        return chain.execute(exchange);
    }
    // 设置 exchange 的 rewrite_uri 属性,实现请求URI 的重写
    exchange.getAttributes().put(Constants.REWRITE_URI, rewriteHandle.getRewriteURI());
 		// 将新的 URI 放行到下一个插件
    return chain.execute(exchange);
}

rewrite 插件总结

总的来说,rewrite 插件也相当于一个全局的请求拦截器,当请求经过 rewrite 插件时,如果匹配到了在 soul-admin 中配置的规则,那么会通过设置 exchange 的 rewrite_uri 属性,来实现对请求 URI 的重写。

你可能感兴趣的:(Soul,网关源码)