ASP.NET Web API场景下如何防止已认证用户越权访问其他用户数据
无全局userid字段场景下的资源越权访问问题解决方案
核心前提
你当前遇到的是典型的水平权限越权问题,这类权限校验必须在后端全链路落地,前端的限制仅可作为体验优化手段,无法保障数据安全。
最佳落地方案(按优先级排序)
1. 分批次补充业务表的资源归属关联
这是长期可维护性最高的方案,改造成本远低于后续维护复杂校验逻辑的成本:
- 优先给存储私有用户数据的核心业务表(如文档表、用户私有配置表)增加
owner_user_id字段,写入数据时同步绑定当前登录用户ID - 若业务数据通过
relationid/applicationid等字段已经关联到了带用户归属的上层表,无需重复加字段,直接通过关联查询获取对应归属用户ID即可
2. 用接口粒度的自定义校验过滤器替代全局中间件
全局中间件适配性差,很容易误伤公开接口、公共资源接口,更适合用ASP.NET Web API原生的过滤器机制实现:
- 自定义
[ResourceOwnerAuthorize]特性,继承IActionFilter或者IAsyncActionFilter,仅给需要做私有资源校验的接口标注该特性 - 过滤器逻辑步骤:
- 从已验签的JWT令牌中解析出当前登录用户的
user_id,禁止直接读取请求参数中的用户ID - 从路由参数/请求参数中获取当前请求的资源ID(如
documentid) - 调用对应资源的归属校验逻辑,比对资源归属ID和当前登录用户ID
- 匹配失败直接返回
403 Forbidden,匹配成功则放行请求
- 从已验签的JWT令牌中解析出当前登录用户的
- 封装统一的
IResourceOwnerValidator公共服务,不同资源类型的归属查询逻辑统一收口,避免每个接口重复写校验代码
3. 短期过渡方案(仅适用于暂时无法改表的场景)
如果短期内无法完成表结构改造,可先给高危接口加一层权限范围校验:
- 每次用户请求私有资源详情前,先通过列表接口拉取当前用户有权限访问的所有资源ID集合,缓存到Redis或者服务端内存中
- 详情接口收到请求时,先判断请求的资源ID是否在当前用户的权限集合内,不存在则直接拒绝访问
- 注意该方案仅作为临时过渡使用,数据量大时缓存和查询性能都会下降,最终还是要回归到表结构补全的方案
避坑提醒
- 不要尝试用硬编码接口参数映射的方式做全局中间件校验,后续接口迭代很容易出现校验遗漏,反而会带来安全隐患
- 所有JWT必须经过服务端验签后再解析用户信息,避免令牌被篡改导致校验失效
内容的提问来源于stack exchange,提问作者Raghul Raman
相关产品推荐
相关产品推荐

