背景
软件系统几乎都会遇到安全问题:漏洞、恶意代码、SQL 注入、XSS、跨站请求伪造、第三方组件风险,甚至是业务逻辑本身的缺陷。要把这些风险压下去,认证和权限控制就成了系统设计里绕不开的一环。
在实际项目里,权限管理通常会落到两类模型上:
- 基于角色的权限控制(RBAC):先定义角色,再把权限分配给角色,最后把用户映射到角色。
- 基于属性的权限控制(ABAC):根据用户属性、环境属性、资源属性等动态判断是否允许访问。
两者没有绝对的优劣。RBAC 更容易落地,ABAC 更灵活,很多系统会把它们结合起来用。
Web 场景里常见的安全问题
Web 应用最常见的风险,基本离不开这几类:
- XSS(跨站脚本攻击)
- SQL 注入
- 信息泄露
- 文件上传漏洞
- CSRF(跨站请求伪造)
除此之外,还有拒绝服务攻击、任意文件下载、恶意脚本传播等问题。真正做系统时,认证只是起点,权限控制、输入校验、审计和最小权限原则,往往要一起上。
核心概念
用户角色
角色是权限管理里最直观的一层抽象。比如管理员、普通用户、运营人员、审核员,不同角色拥有不同的操作范围。角色的好处是简单清晰,权限模型也容易维护。
用户属性
属性关注的是'这个用户是什么样的人',例如身份证号、手机号、邮箱、部门、职位、IP 地址、地理位置等。属性信息常常参与登录认证、风控判断和细粒度授权。
URL 访问控制
URL 访问控制通常通过访问控制列表(ACL)实现,用来限制某个 URL 是否允许访问。它适合做最基础的入口拦截,比如静态资源放行、管理后台限制访问、某些接口仅允许特定角色调用。
会话管理
会话管理解决的是'如何在多次请求之间保持同一个登录状态'。用户登录成功后,服务端需要保存或识别会话标识,这样后续请求才能继续确认用户身份,避免每次都重新登录。
漏洞扫描
漏洞扫描的作用是尽早发现系统里已知的安全风险,比如弱口令、过期依赖、配置错误、暴露接口等。发现问题之后,升级版本、收紧权限、修复配置,都是常规动作。
单点登录
单点登录(SSO)适合多应用协同场景。用户只登录一次,就能在多个系统间复用认证状态。对于企业内部系统来说,这种方式既省事,也能减少账号体系分裂带来的安全隐患。
API 调用权限管理
API 权限管理通常以密钥、Token 或签名机制为基础,用来控制谁能调用什么接口、调用频率是多少、能不能访问敏感资源。对开放平台、微服务和内部接口治理来说,这一层非常关键。
RBAC 与 ABAC 的基本思路
RBAC 的思路很直接:先建角色,再给角色赋权,最后把用户放进对应角色里。用户访问资源时,系统检查当前角色是否具备相应权限。这个模型的优点是直观、稳定、易维护,也最符合大多数业务系统的习惯。
它的执行路径通常是这样:
- 创建角色,并定义每个角色拥有的权限。
- 把用户分配到一个或多个角色中。
- 用户访问资源时,系统检查角色是否匹配。
- 根据角色决定页面展示和功能可见性。
RBAC 的问题也很现实:当业务复杂起来后,角色会越来越多,授权和回收权限都可能变得琐碎。
ABAC 则更灵活。它不会只看'你是谁',而是结合用户属性、资源属性和上下文条件一起判断。例如,同一个用户在公司内网可以访问某些接口,到了外网就不行;或者某个部门的员工只能访问自己部门的数据。
它的执行路径大致是:
- 定义属性类型及其取值范围。
- 将用户、资源、环境信息纳入规则。
- 请求到达时,按属性组合判断是否授权。
- 当属性或业务规则变化时,更新策略。
ABAC 的弹性更大,但规则也更复杂,维护成本通常高于 RBAC。很多企业内部系统会用 ABAC 做精细化控制,而面向公网的业务系统则常常以 RBAC 为主。
Spring Security 中的权限控制示例
Spring Security 提供了比较完整的认证与授权能力。对于 Web 项目来说,常见做法是先通过安全过滤器链拦截请求,再根据 URL、角色或方法注解完成访问控制。

