目录
[1. 整体流程](#1. 整体流程)
[2. 具体技术实现(Spring Cloud Gateway 为例)](#2. 具体技术实现(Spring Cloud Gateway 为例))
[(1)业务服务:定义注解 + 扫描接口路由](#(1)业务服务:定义注解 + 扫描接口路由)
[(3)Gateway:拉取规则 + 全局过滤器统一鉴权](#(3)Gateway:拉取规则 + 全局过滤器统一鉴权)
这是微服务架构中最标准、最常用的鉴权方案 :Gateway 只做「鉴权执行」,业务服务只做「放行规则配置」,职责完全解耦。
本文直接给你讲企业落地的通用实现方案,清晰、可直接面试回答,也能直接开发用。
一、核心设计原则(一句话总结)
Gateway 不关心业务,只做 "校验 token 是否有效 + 是否需要放行"; 业务服务定义 "哪些接口公开、哪些需要权限",把规则告诉 Gateway。
二、具体实现方案(最主流、最推荐)
1. 整体流程
- 业务服务(如订单、用户服务) :在自己的接口上标注权限注解 (如
@Anonymous免鉴权、@RequireRole("ADMIN"))。 - 业务服务启动时 :把接口权限规则自动上报到配置中心 / 数据库。
- Gateway 实时拉取规则:知道哪些路径不需要登录、哪些需要什么角色 / 权限。
- 请求进入 Gateway :
- 匹配规则 → 公开接口:直接放行
- 私有接口:校验 Token → 无效直接拦截 → 有效则转发
2. 具体技术实现(Spring Cloud Gateway 为例)
(1)业务服务:定义注解 + 扫描接口路由
业务服务自己决定哪些接口不用登录:
// 免登录注解(业务服务定义)
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Anonymous {
}
// 控制器里使用
@RestController
@RequestMapping("/user")
public class UserController {
// 登录接口 → 业务决定免鉴权
@Anonymous
@PostMapping("/login")
public Result login() {}
// 获取用户信息 → 需要鉴权
@GetMapping("/info")
public Result info() {}
}
(2)业务服务:启动时自动上报路由权限规则
项目启动时,扫描所有 @Anonymous、@RequirePermission 注解, 把 URL + 是否需要鉴权 + 需要的权限 上报到:
- Nacos / Apollo(配置中心)
- 或 Redis / MySQL
示例上报格式(Gateway 能读懂):
[
{ "url": "/user/login", "auth": false },
{ "url": "/user/info", "auth": true, "roles": ["USER"] },
{ "url": "/order/**", "auth": true, "perms": ["order:query"] }
]
(3)Gateway:拉取规则 + 全局过滤器统一鉴权
Gateway 只做一件事: 拿请求路径 → 匹配规则 → 决定是否校验 Token
核心过滤器伪代码:
@Component
public class AuthFilter implements GlobalFilter {
@Autowired
private AuthRuleService authRuleService; // 拉取业务服务上报的规则
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1. 获取当前请求路径
String path = exchange.getRequest().getPath().toString();
// 2. 查询规则:是否需要鉴权(由业务服务决定!)
AuthRule rule = authRuleService.getRule(path);
// 3. 业务说不需要鉴权 → 直接放行
if (!rule.isAuth()) {
return chain.filter(exchange);
}
// 4. 需要鉴权 → Gateway 执行校验(Token、签名、过期等)
String token = exchange.getRequest().getHeader("token");
if (!JwtUtil.verify(token)) {
return unauthorizedResponse(exchange);
}
// 5. 校验通过 → 转发
return chain.filter(exchange);
}
}
三、更轻量的简化方案(中小型项目常用)
如果不想做「自动上报」,可以用配置文件模式 ,同样满足: 业务决定放行规则,Gateway 只执行。
-
每个业务服务提供一个
white-list.ymlanonymous: urls: - /user/login - /file/upload/** -
交给 Gateway 加载
-
Gateway 统一拦截、放行、鉴权
优点 :简单、稳定、无侵入。 缺点:不能自动扫描注解,需要手动维护(但很多公司就这样用)。
四、为什么要这么设计?(面试加分回答)
- 职责分离
- Gateway:只做通用安全拦截(无业务逻辑)
- 业务服务:只做自身接口权限定义
- 扩展性强 新增服务 → 只需要业务配置规则,Gateway 完全不用改
- 统一安全入口 所有鉴权收口在网关,避免业务服务漏写鉴权
- 性能更好 非法请求在网关层直接拦截,不会打到后端服务
五、面试标准回答(你可以直接背)
我们的方案是:Gateway 统一负责鉴权逻辑的执行,业务服务负责定义哪些接口需要鉴权、哪些不需要。
具体实现:
- 业务服务通过注解(如 @Anonymous)标记公开接口;
- 服务启动时自动扫描接口,把权限规则上报到配置中心或 Redis;
- Gateway 实时拉取所有服务的权限规则;
- 请求进入网关后,根据规则判断是否需要鉴权,需要则校验 Token,不需要直接放行。
这种模式做到了权限控制在业务,鉴权执行在网关,职责清晰、易于维护。
总结
- 控制权分离:Gateway 执行鉴权,业务服务定义规则
- 实现方式:注解 + 规则上报 + Gateway 全局过滤器
- 优点:解耦、统一入口、易扩展、安全
- 两种方案:自动上报(大型项目)、配置白名单(中小型项目)