漫谈认证与授权

0 阅读7分钟

深入浅出认证与授权:从核心概念到 OAuth2 实战

一文打通认证授权知识体系,读懂 RBAC、JWT、OAuth2.与微服务安全架构

引言

逛淘宝时,你需要登录(认证),然后系统根据你是普通用户还是 VIP 决定能否查看专属优惠(授权)。小到一个 H5 页面,大到复杂的企业级应用,认证与授权都是不可或缺的模块。

在软件系统设计中,如何让应用在各种环境中安全、高效地访问资源,涉及一系列概念与细分领域:

  • 认证(Authentication) :系统识别合法用户,解决“你是谁”的问题。
  • 授权(Authorization) :用户认证通过后,系统判断“你能做什么”。
  • 凭证(Credential) :双方约定的身份证明,保证意图真实、完整、不可抵赖。
  • 保密(Secrecy) :安全持久化账户信息,防止窃取与滥用。
  • 会话(Session) :避免每次操作都重新认证,保持登录状态。

本文将围绕这些核心概念,从基础模型讲到微服务架构下的 OAuth2 + JWT 实践,助你构建完整的认证授权知识体系。


一、核心概念详解

1.1 认证(Authentication)

认证是识别合法用户的过程。常见方式:

  • 用户名 + 密码(最普遍)
  • 手机短信验证码
  • 二维码扫码登录(如微信)
  • CA 数字证书认证

一句话:认证回答“你是谁”。

1.2 授权(Authorization)

授权是用户通过认证后,系统根据其权限控制资源访问的过程。常见访问控制模型:

模型全称核心思想适用场景
ACL访问控制列表直接为每个用户或资源设置权限列表文件系统、网络设备(如 Linux getfacl
RBAC基于角色的访问控制引入“角色”,将权限赋予角色,再把角色赋予用户大部分业务系统,如管理后台、CRM
ABAC基于属性的访问控制通过用户属性、资源属性、环境属性动态计算权限复杂场景,如:仅允许在工作时间访问敏感数据
OAuth2开放授权框架第三方应用获取用户授权令牌,无需用户密码接入微信/QQ登录、开放平台 API

RBAC 示意图

用户(User) → 角色(Role) → 权限(Permission) → 资源(Resource)

本质:所有模型都解决“谁(User)拥有什么权限(Authority)操作哪些资源(Resource)”。

在 Spring Security 中,权限控制模型通常如下:

UserDetails  → GrantedAuthority  →  @PreAuthorize("hasAuthority('ROLE_ADMIN')")

1.3 凭证(Credential)与会话(Session)

HTTP 是无状态的,认证后需要维持会话,避免每次请求都重新登录。

传统方案:Cookie-Session

  • 服务端存储 Session(通常内存或 Redis),客户端存储 SessionId(Cookie)。
  • 优点:成熟、简单。
  • 缺点:分布式环境下 Session 共享困难。

集群环境下的三种 Session 处理方式

方式原理优缺点
中心化存储Session 存入 Redis 等中间件性能好,但须保证中间件高可用
会话复制节点间广播复制 Session网络开销大,不推荐大规模集群
会话粘滞负载均衡将同一用户始终路由到同一节点节点宕机会丢失会话

Token 机制(无状态)

  • 客户端存储 Token(如 LocalStorage),服务端不保存会话。
  • 常用 JWT(JSON Web Token)。
  • 优点:天然适合分布式、可扩展。
  • 缺点:无法主动失效(除非借助黑名单缓存)。

JWT 结构Header.Payload.Signature 在这里插入图片描述

  • Header:令牌类型(JWT)和签名算法(如 HS256、RS256)。
  • Payload:声明数据(用户 ID、过期时间等)。
  • Signature:对前两部分签名,防篡改。

示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

二、认证与授权方案的发展与迭代

2.1 单体应用时代

  • 使用 Session-Cookie,依赖应用服务器内存。
  • 权限校验通常在 Filter/Interceptor 中完成。
  • 优点:简单、低延迟。缺点:无法水平扩展。

2.2 负载均衡 / 集群架构

  • 引入 Redis 中心化存储 Session。
  • 或采用 JWT 无状态 Token。
  • Spring Session 等项目简化了集成。

2.3 微服务架构

  • 每个服务独立,且可能有不同的认证授权需求。
  • 典型方案:OAuth2 + JWT + 网关统一认证
  • 认证中心(Authorization Server)颁发 Token,资源服务校验 Token。
  • 网关层可集中进行 Token 解析和权限校验,减少重复代码。

三、OAuth 2.0 详解

OAuth 2.0 是一个授权框架,允许第三方应用获取用户授权后访问其资源,而无需用户提供密码。它不是向后兼容 OAuth 1.0 的升级,而是一个全新设计。

核心角色

  • Resource Owner:资源所有者,即用户。
  • Client:第三方应用(如网站 A 要访问用户存储在网站 B 的照片)。
  • Authorization Server:认证服务器,负责颁发令牌。
  • Resource Server:资源服务器,持有用户资源(可与认证服务器同一,也可分离)。

OAuth 2.0 定义了四种授权方式,信任度由低到高

模式适用场景特点
授权码模式有后端的 Web 应用最安全、最常用
简化模式(Implicit)纯前端应用(如 SPA)无中间代码交换,直接返回令牌(已不推荐)
密码模式高度信任的客户端(如官方 App)用户提供用户名密码给客户端,换取令牌
客户端模式客户端以自己的名义访问资源无需用户参与,适用于服务器间调用

3.1 授权码模式(Authorization Code)

这是最完整、最安全的模式,流程如下:

1. 客户端重定向用户到认证服务器:
   https://b.com/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

2. 用户同意授权后,认证服务器重定向回客户端,并附带授权码:
   https://a.com/callback?code=AUTHORIZATION_CODE

3. 客户端使用授权码向认证服务器换取令牌:
   POST https://b.com/oauth/token
   grant_type=authorization_code&code=AUTHORIZATION_CODE&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

4. 认证服务器返回 access_token(和可选的 refresh_token)

3.2 简化模式(Implicit)

省略授权码步骤,直接返回令牌(常用于纯前端应用)。现已因安全原因被 OAuth 2.1 废弃,建议改用授权码 + PKCE。

3.3 密码模式(Resource Owner Password Credentials)

用户直接在客户端输入用户名密码,客户端用这些凭证换取令牌。只适用于客户端和资源所有者高度信任的场景(如官方移动 App)。

请求示例:

POST https://oauth.b.com/token
grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

响应直接返回令牌。

3.4 客户端模式(Client Credentials)

客户端以自己的名义申请令牌,没有用户参与。通常用于后端服务之间的授权。

请求示例:

POST https://oauth.b.com/token
grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

四、Spring Security OAuth2 + 网关实践

在微服务架构中,通常使用 Spring Security OAuth2(现已迁移到 Spring Authorization Server)实现认证中心,配合 Spring Cloud Gateway 实现统一认证。

4.1 两种主流架构思路

思路描述优点缺点
网关只做转发网关将请求直接转发到各资源服务,每个资源服务单独验证 Token(远程调用认证服务器)隔离性好每次请求都需远程调用 UAA,认证服务器压力大
网关统一验证网关集中验证 Token(如本地解析 JWT),并转发请求,资源服务不再验证性能高,减少网络开销网关成为关键节点,需高可用

在这里插入图片描述 在这里插入图片描述

4.2 JWT + 网关模式推荐

  • 认证服务器生成 JWT 令牌(使用 RSA 私钥签名)。
  • 网关配置公钥,解析并验证 JWT 签名,同时可将用户信息注入请求头(如 X-User-Id)。
  • 资源服务接收请求,直接从请求头获取用户信息,无需再次验证。

优点

  • 无状态,水平扩展容易。
  • 网关性能瓶颈可控(仅做签名验证,无远程调用)。
  • Token 中可携带用户角色信息,实现细粒度权限控制。

缺点

  • JWT 一旦签发,无法主动失效(除非引入黑名单缓存)。
  • Token 体积较大,若携带过多 Claim 会增大网络开销。

五、总结与最佳实践

场景推荐方案
单体应用Session-Cookie + RBAC
集群/分布式JWT 无状态 Token 或 Redis 会话
开放 API 给第三方OAuth2 授权码模式
微服务内部服务间调用OAuth2 客户端模式 或 JWT + 网关验证
前后端分离 SPAOAuth2 授权码 + PKCE(替代简化模式)

安全提醒

  • 永远不要在客户端存储敏感凭证(如用户密码)。
  • JWT 尽量设置较短有效期,搭配 refresh_token 使用。
  • 敏感接口应使用 HTTPS,防止中间人攻击。

参考文档


如果本文对您有帮助,欢迎点赞、收藏、转发,让更多人了解认证与授权的精髓。