Gateway 鉴权场景:网关统一鉴权 + 业务应用决定放行规则

目录

一、核心设计原则(一句话总结)

二、具体实现方案(最主流、最推荐)

[1. 整体流程](#1. 整体流程)

[2. 具体技术实现(Spring Cloud Gateway 为例)](#2. 具体技术实现(Spring Cloud Gateway 为例))

[(1)业务服务:定义注解 + 扫描接口路由](#(1)业务服务:定义注解 + 扫描接口路由)

(2)业务服务:启动时自动上报路由权限规则

[(3)Gateway:拉取规则 + 全局过滤器统一鉴权](#(3)Gateway:拉取规则 + 全局过滤器统一鉴权)

三、更轻量的简化方案(中小型项目常用)

四、为什么要这么设计?(面试加分回答)

五、面试标准回答(你可以直接背)

总结


这是微服务架构中最标准、最常用的鉴权方案Gateway 只做「鉴权执行」,业务服务只做「放行规则配置」,职责完全解耦

本文直接给你讲企业落地的通用实现方案,清晰、可直接面试回答,也能直接开发用。


一、核心设计原则(一句话总结)

Gateway 不关心业务,只做 "校验 token 是否有效 + 是否需要放行"; 业务服务定义 "哪些接口公开、哪些需要权限",把规则告诉 Gateway。


二、具体实现方案(最主流、最推荐)

1. 整体流程

  1. 业务服务(如订单、用户服务) :在自己的接口上标注权限注解 (如 @Anonymous 免鉴权、@RequireRole("ADMIN"))。
  2. 业务服务启动时 :把接口权限规则自动上报到配置中心 / 数据库。
  3. Gateway 实时拉取规则:知道哪些路径不需要登录、哪些需要什么角色 / 权限。
  4. 请求进入 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 只执行

  1. 每个业务服务提供一个 white-list.yml

    复制代码
    anonymous:
      urls:
        - /user/login
        - /file/upload/**
  2. 交给 Gateway 加载

  3. Gateway 统一拦截、放行、鉴权

优点 :简单、稳定、无侵入。 缺点:不能自动扫描注解,需要手动维护(但很多公司就这样用)。


四、为什么要这么设计?(面试加分回答)

  1. 职责分离
    • Gateway:只做通用安全拦截(无业务逻辑)
    • 业务服务:只做自身接口权限定义
  2. 扩展性强 新增服务 → 只需要业务配置规则,Gateway 完全不用改
  3. 统一安全入口 所有鉴权收口在网关,避免业务服务漏写鉴权
  4. 性能更好 非法请求在网关层直接拦截,不会打到后端服务

五、面试标准回答(你可以直接背)

我们的方案是:Gateway 统一负责鉴权逻辑的执行,业务服务负责定义哪些接口需要鉴权、哪些不需要。

具体实现:

  1. 业务服务通过注解(如 @Anonymous)标记公开接口;
  2. 服务启动时自动扫描接口,把权限规则上报到配置中心或 Redis;
  3. Gateway 实时拉取所有服务的权限规则;
  4. 请求进入网关后,根据规则判断是否需要鉴权,需要则校验 Token,不需要直接放行。

这种模式做到了权限控制在业务,鉴权执行在网关,职责清晰、易于维护。


总结

  1. 控制权分离:Gateway 执行鉴权,业务服务定义规则
  2. 实现方式:注解 + 规则上报 + Gateway 全局过滤器
  3. 优点:解耦、统一入口、易扩展、安全
  4. 两种方案:自动上报(大型项目)、配置白名单(中小型项目)
相关推荐
Advancer-12 小时前
点评plus---异步消费之后可靠的生成订单
java·spring·kafka
此生决int12 小时前
C++快速上手java备战期末考——运算符,输入输出和数组
java·c++·期末复习
bandaoyu12 小时前
【AMD】HDP(Host Data Path)是什么
java·后端·spring
蝈蝈噶蝈蝈噶12 小时前
poi-tl填充柱状图折线图无法指定y坐标轴导致重复数据
java·word
一 乐13 小时前
个人博客系统|基于Springboot的个人博客系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·个人博客系统
xier_ran13 小时前
【C++】堆(Heap)与栈(Stack)内存详解
java·开发语言·c++
tang74516396213 小时前
Huawei Cloud EulerOS 2.0(x8664)安装 Jenkins
java·servlet·jenkins
白宇横流学长13 小时前
基于Spring Boot的社区生鲜团购系统设计与实现
java·spring boot·后端
兰令水13 小时前
leecodecode【二分查找】【2026.5.28打卡-java版本】
java·算法·leetcode