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

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

分享技术,用心生活

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

先说思路:

  1. 配置网关白名单列表
  2. 编写鉴权过滤器
  3. 过滤器中读取白名单
  4. 业务处理

简单的时序图

用户过滤器业务系统发起请求校验白名单通过不通过success用户过滤器业务系统

注: 如果使用的是网关过滤器,在校验后应该再次过滤器,也就是经过2次;注意区别(网关过滤器具有前置pre、后置post两次过滤,细节不在此处详细探讨)。

过滤器普遍用于处理拦截,校验,改写,日志等场景;通过白名单来控制鉴权,正契合过滤器的作用。

1. 配置网关白名单

在你的本地的配置文件或者是nacos的配置文件中新增以下配置

可以配置url全路径,也可以配置前缀路径

yml复制代码gateway:

 whitelist:

   - /user/api/userInfo/query

   - /open/oss/upload

   - /open/vod/api

2. 过滤器配置

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

2.1. WebFilter实现

java复制代码@Component@RequiredArgsConstructorpublic 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实现

java复制代码@Component@RequiredArgsConstructorpublic 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要和配置文件中的名称保持一致

java复制代码@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

分享技术,用心生活

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

先说思路:

  1. 配置网关白名单列表
  2. 编写鉴权过滤器
  3. 过滤器中读取白名单
  4. 业务处理

简单的时序图

用户过滤器业务系统发起请求校验白名单通过不通过success用户过滤器业务系统

注: 如果使用的是网关过滤器,在校验后应该再次过滤器,也就是经过2次;注意区别(网关过滤器具有前置pre、后置post两次过滤,细节不在此处详细探讨)。

过滤器普遍用于处理拦截,校验,改写,日志等场景;通过白名单来控制鉴权,正契合过滤器的作用。

1. 配置网关白名单

在你的本地的配置文件或者是nacos的配置文件中新增以下配置

可以配置url全路径,也可以配置前缀路径

yml复制代码gateway:

 whitelist:

   - /user/api/userInfo/query

   - /open/oss/upload

   - /open/vod/api

2. 过滤器配置

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

2.1. WebFilter实现

java复制代码@Component@RequiredArgsConstructorpublic 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实现

java复制代码@Component@RequiredArgsConstructorpublic 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要和配置文件中的名称保持一致

java复制代码@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


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

作者:临时工

链接:
https://juejin.cn/post/7260506612971683896


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


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

作者:临时工

链接:
https://juejin.cn/post/7260506612971683896

相关文章
|
4月前
|
DataWorks 安全 API
在DataWorks中创建的接口如果要使用API网关进行鉴权
【4月更文挑战第3天】在DataWorks中创建的接口如果要使用API网关进行鉴权
51 2
|
10月前
|
负载均衡 应用服务中间件 API
微服务技术系列教程(25) - SpringCloud- 接口网关服务Zuul
微服务技术系列教程(25) - SpringCloud- 接口网关服务Zuul
147 0
|
11月前
|
存储 安全 PHP
【100天精通Python】Day48:Python Web开发_WSGI网络服务器网关接口与使用
【100天精通Python】Day48:Python Web开发_WSGI网络服务器网关接口与使用
92 0
|
10月前
|
域名解析 监控 安全
接口开放太麻烦?试试阿里云API网关吧
我在[多方合作时,系统间的交互是怎么做的?](https://www.cnblogs.com/wlovet/p/17466812.html)这篇文章中写过一些多方合作时接口的调用规则和例子,然而,接口开放所涉及的安全、权限、监控、流量控制等问题,可不是简简单单就可以解决的,这一般需要专业的开放平台来支撑。但为了开放几个接口就要做一个开放平台,实在是不合算。为此阿里云为了解决这类需求推出了一款强大的工具——API网关。本文将介绍阿里云API网关的特点和优势,以及如何使用API网关来简化接口开放的过程。
363 0
接口开放太麻烦?试试阿里云API网关吧
|
4月前
|
机器学习/深度学习 XML 数据格式
CGI通用网关接口
CGI通用网关接口
|
4月前
|
网络虚拟化 网络架构
配置基于接口划分VLAN示例(汇聚层设备作为网关)
划分VLAN的方式有:基于接口、基于MAC地址、基于IP子网、基于协议、基于策略(MAC地址、IP地址、接口)。其中基于接口划分VLAN,是最简单,最常见的划分方式。 基于接口划分VLAN指的是根据交换机的接口来划分VLAN。网络管理员预先给交换机的每个接口配置不同的PVID,当一个数据帧进入交换机时,如果没有带VLAN标签,该数据帧就会被打上接口指定PVID的Tag,然后数据帧将在指定PVID中传输。 在典型的分层组网中,当接入交换机是二层交换机时,可以使用汇聚交换机作为用户的网关。另外使用汇聚交换机作为用户的网关还可以简化接入交换机的配置,使用户通过一个出接口访问外部网络,便于维护和管
213 0
|
JavaScript 安全 小程序
Spring Cloud实战 | 第十一篇:Spring Cloud Gateway网关实现对RESTful接口权限和按钮权限细粒度控制
Spring Cloud实战 | 第十一篇:Spring Cloud Gateway网关实现对RESTful接口权限和按钮权限细粒度控制
Spring Cloud实战 | 第十一篇:Spring Cloud Gateway网关实现对RESTful接口权限和按钮权限细粒度控制
|
存储 SpringCloudAlibaba API
SpringCloud Alibaba二十五 | 网关Restful接口拦截
SpringCloud Alibaba二十五 | 网关Restful接口拦截
242 0
|
canal 监控 安全
谷粒学院——Day17【数据同步工具、SpringCloud【GateWay网关】、权限管理功能(接口)】
谷粒学院——Day17【数据同步工具、SpringCloud【GateWay网关】、权限管理功能(接口)】
298 0
谷粒学院——Day17【数据同步工具、SpringCloud【GateWay网关】、权限管理功能(接口)】
|
消息中间件 移动开发 负载均衡