Spring Boot项目如何根据登录用户所属企业过滤接口返回结果及校验操作
实现方案
1. Zuul层透传用户关联企业ID
你已经在Zuul集成了Spring Security做身份认证,首先需要在认证逻辑中扩展用户信息:
- 认证成功时,从用户表查询关联的
EnterpriseID,和用户名、权限信息一起存入Spring Security的Authentication对象的扩展字段中 - 编写一个pre类型Zuul过滤器,优先级高于路由转发过滤器,执行逻辑如下:
- 先移除外部请求传入的
X-User-Enterprise-Id请求头,防止伪造 - 从当前
SecurityContextHolder中取出认证信息里的企业ID,设置到X-User-Enterprise-Id请求头中透传给下游业务服务
- 先移除外部请求传入的
2. 列表查询结果自动过滤
根据你使用的持久层框架选择对应方案,无需修改业务接口代码即可实现自动过滤:
方案A:JPA场景
- 在
FooBar实体类上加过滤器注解:
@FilterDef(name = "enterpriseFilter", parameters = @ParamDef(name = "enterpriseId", type = "long")) @Filter(name = "enterpriseFilter", condition = "FK_ID = :enterpriseId") @Entity public class FooBar { // 原有实体字段 }
- 编写全局请求拦截器/AOP,在接口执行查询前,从请求头获取
X-User-Enterprise-Id,开启当前EntityManager的过滤器,传入企业ID参数,查询时会自动拼接过滤条件,只返回当前企业关联的FooBar数据
方案B:MyBatis场景
编写MyBatis全局拦截器,拦截Executor的query方法:
- 识别到查询的是
FooBar相关表时,自动给原SQL拼接AND FK_ID = ?条件,参数填入从请求头获取的企业ID即可
3. POST/PUT请求归属校验
用自定义注解+AOP实现统一校验,避免每个接口写重复逻辑:
- 首先定义自定义注解
@CheckEnterpriseOwnership,标记需要做归属校验的接口 - 编写切面拦截所有加了该注解的方法:
- 新增(POST)场景:直接校验请求参数中
FooBar的FK_ID是否等于当前请求头的企业ID,不一致直接抛出AccessDeniedException - 修改(PUT)场景:先根据请求参数的
FooBarID查询对应记录的FK_ID,和当前用户的企业ID比对,不一致直接返回403
- 新增(POST)场景:直接校验请求参数中
4. 可选补充
在业务服务中加全局异常处理器,统一捕获AccessDeniedException,封装为标准的403权限不足响应即可。
内容的提问来源于stack exchange,提问作者Erich Mönch
相关产品推荐
相关产品推荐

