呼延含玉 发表于 2025-6-5 20:05:15

巧用网关白名单实现接口免鉴权

分享技术,用心生活

场景描述:一般系统中提供的接口都是经过统一配置鉴权的,比如不登录不能访问。但是,一些接口是需要开放给客户用的,我称作open API。那么这时候你不能要求客户先登录你的接口再去调用吧。那么,这时候就可以通过网关白名单来实现免鉴权
先说思路:

[*]配置网关白名单列表
[*]编写鉴权过滤器
[*]过滤器中读取白名单
[*]业务处理
简单的时序图

注: 如果使用的是网关过滤器,在校验后应该再次过滤器,也就是经过2次;注意区别(网关过滤器具有前置pre、后置post两次过滤,细节不在此处详细探讨)。
过滤器普遍用于处理拦截,校验,改写,日志等场景;通过白名单来控制鉴权,正契合过滤器的作用。
1. 配置网关白名单

在你的本地的配置文件或者是nacos的配置文件中新增以下配置
可以配置url全路径,也可以配置前缀路径
gateway:
whitelist:
    - /user/api/userInfo/query
    - /open/oss/upload
    - /open/vod/api2. 过滤器配置

过滤器你可以选择用spring的WebFilter,如果你的系统集成了gateway也可以使用网关过滤器,然后自定义过滤器实现GlobalFilter
2.1. WebFilter实现

@Component
@RequiredArgsConstructor
public class AuthFilter implements WebFilter, Ordered {

    private final GateWayProperties gateWayProperties;

    private static final AntPathMatcher pathMatcher = new AntPathMatcher();

    @Override
    public int getOrder() {
      return 1;
    }

    @Override
    protected Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
      ServerHttpRequest request = exchange.getRequest();
      String urlMethod = request.getURI().getPath();

      // 白名单匹配,直接放行
      for (String pattern : gateWayProperties.getWhitelist()) {
            if (pathMatcher.matchStart(pattern, urlMethod)) {
                return chain.filter(exchange);
            }
      }
       // 未匹配到
       // 鉴权逻辑,此处省略....
    }

}2.2. 网关GlobalFilter实现

@Component
@RequiredArgsConstructor
public class AuthFilter implements GlobalFilter, Ordered {

    private final GateWayProperties gateWayProperties;

    private static final AntPathMatcher pathMatcher = new AntPathMatcher();


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
      ServerHttpRequest request = exchange.getRequest();
      String urlMethod = request.getURI().getPath();

      // 白名单匹配,直接放行
      for (String pattern : gateWayProperties.getWhitelist()) {
            if (pathMatcher.matchStart(pattern, urlMethod)) {
                return chain.filter(exchange);
            }
      }
      // 未匹配到,忽略鉴权逻辑,直接设置401
      exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
      return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
      return 0;
    }
}2.3. 读取白名单配置

GateWayProperties中的prefix和配置文件中的名称一致
@Getter
@Setter
@ToString
@ConfigurationProperties(prefix = "gateway")
public class GateWayProperties implements Serializable {

    private static final long serialVersionUID = 1L;

    private List<String> whitelist;

}3. 演示效果

使用上面配置的查询用户信息接口/user/api/userInfo/query做演示
3.1. 在白名单内


[*]WebFilter效果
查看断点gateWayProperties中白名单列表已获取到,且比对结果为true


[*]GlobalFilter效果
查看断点gateWayProperties中白名单列表也已获取到,且比对结果为true

查询结果:已获取到用户信息

3.2. 不在白名单内

我们把接口/user/api/userInfo/query从白名单中删除,用网关过滤器演示。
查看断点gateWayProperties中白名单列表已没有查询用户接口,且返回了401

查询结果:http状态码是我们设置的401

当然,使用白名单也不仅仅局限于对外开放接口这个场景,也不仅仅局限于使用在鉴权过滤器上。这里只是一个抛砖引玉。实际需求可以结合自己的业务场景,使用不同的过滤器。

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

松菊 发表于 2025-10-14 07:55:59

鼓励转贴优秀软件安全工具和文档!

吟氅 发表于 2025-11-1 11:21:06

东西不错很实用谢谢分享

丘娅楠 发表于 2025-12-18 02:14:25

分享、互助 让互联网精神温暖你我

搁胱 发表于 2025-12-21 08:36:18

热心回复!

科元料 发表于 2026-1-7 19:37:44

谢谢分享,辛苦了

邹语彤 发表于 2026-1-9 02:34:44

谢谢楼主提供!

赫连如冰 发表于 2026-1-10 23:25:48

感谢分享

习和璧 发表于 2026-1-13 21:40:09

感谢,下载保存了

明思义 发表于 2026-1-14 22:23:44

谢谢分享,试用一下

骆贵 发表于 2026-1-23 09:26:10

这个好,看起来很实用

痕伯 发表于 2026-1-24 02:19:09

鼓励转贴优秀软件安全工具和文档!

茅香馨 发表于 2026-1-24 08:02:12

热心回复!

尹心菱 发表于 2026-1-24 12:39:43

懂技术并乐意极积无私分享的人越来越少。珍惜

阜逐忍 发表于 2026-1-25 03:20:06

感谢分享

连热 发表于 2026-1-27 04:12:42

感谢发布原创作品,程序园因你更精彩

芮梦月 发表于 2026-1-28 08:28:40

感谢分享

厌外 发表于 2026-1-29 03:38:00

谢谢分享,辛苦了

富账慕 发表于 2026-1-30 07:56:02

不错,里面软件多更新就更好了

嗳歉楞 发表于 2026-2-2 03:37:59

感谢分享,学习下。
页: [1] 2
查看完整版本: 巧用网关白名单实现接口免鉴权