Spring+Angular分布式系统动态API路由防护优化咨询
动态API权限控制方案优化咨询
系统现状与痛点
我们现有系统后端基于Spring、前端基于Angular,页面按功能分组,管理员可基于角色动态分配功能访问权限。当前通过ResourceServerConfigurerAdapter的.antMatchers("url").hasAnyAuthority(access1, access2)方法管理控制器级API访问,但删除功能时需手动更新配置并重新部署,容易遗漏导致废弃API仍对部分角色开放。
为实现仅对在用功能开放API的动态权限控制,我们尝试了一套方案,但该方案繁琐、易出错且耗时,现寻求替代方案或优化建议。
当前方案详情
数据库配置
- 功能与API映射表:
FeatureID | FeatureName | Code | URLS | APIS ----------|------------------|-------|----------------------------|------------------------------ 1 | UserManagement | UM | /user/create,/user/update | /api/user/create,/api/user/update 2 | ProductCatalog | PC | /product/view,/product/edit| /api/product/view,/api/product/edit
缓存结构
缓存中存储的映射关系如下:
{ "Admin": [ { "code": "UM", "urls": ["/user/create", "/user/update"], "apis": ["/api/user/create", "/api/user/update"] }, { "code": "PC", "urls": ["/product/view", "/product/edit"], "apis": ["/api/product/view", "/api/product/edit"] } ], "User": [ { "code": "PC", "urls": ["/product/view"], "apis": ["/api/product/view"] } ] }
前端逻辑
- 用户登录后,系统根据其角色(如"Admin")获取对应功能及URL,实现动态路由防护。
后端逻辑
当请求/api/user/create且请求头中携带/user/create时:
- 后端从会话中提取角色(如"Admin");
- 从缓存中获取该角色对应的
FeatureApisUrlsDto列表; - 遍历列表匹配URL
/user/create所属功能,并校验API/api/user/create是否授权。
问题现状
- 为避免每次API请求查询数据库,在各服务器本地缓存API映射关系;
- 因处于无集中缓存的分布式环境,每5分钟更新一次缓存;
- 方案存在以下局限:
- 缓存更新频率导致权限变更无法即时生效;
- API数量庞大时存在扩展性问题。
咨询问题
- 是否存在对现有架构改动极小的、更优的动态API权限控制方案?
- 若继续使用现有方案:
- API端点存储在数据库还是系统JSON文件中更合适?
- 暂不使用集中缓存时,如何保证分布式服务器间的缓存同步?
约束条件
- 系统存在大量API与功能;
- 需最小化现有系统改动;
- 暂无法实现集中缓存。
解决方案建议
1. 低改动的替代方案
基于Spring Security自定义动态权限过滤器,几乎无需修改原有代码:
- 实现一个
DynamicPermissionFilter,继承OncePerRequestFilter; - 在过滤器中直接提取当前请求的API路径、用户角色;
- 从本地缓存或数据库查询该角色是否拥有此API的访问权限,无需依赖前端传递URL;
- 校验不通过时直接返回无权限响应,逻辑更简洁,避免原有方案中遍历匹配的性能问题。
2. 现有方案优化建议
API端点存储选择
优先存在数据库:
- 支持管理员在后台直接配置、修改API与功能的映射,无需改动代码或文件;
- 可与角色权限分配模块联动,实现全流程动态配置;
- 性能方面可通过本地缓存+版本校验优化,减少数据库查询次数。
分布式缓存同步(无集中缓存)
- 数据库版本号校验:新增
permission_version表,每次权限变更时更新版本号;后端实例每次请求前校验本地缓存版本与数据库版本,不一致则全量更新缓存; - 增量定时拉取:将固定5分钟全量更新改为拉取上次更新时间后的增量变更,减少数据传输量,同时可缩短拉取间隔(如1分钟),提升权限生效速度;
- 手动触发刷新:提供缓存刷新接口,管理员修改权限后可调用该接口批量通知所有后端实例刷新缓存,实现权限即时生效。
内容的提问来源于stack exchange,提问作者Charmi Chavda
相关产品推荐
相关产品推荐

