2216 字
约 7 分钟
0
OAuth2 入门

OAuth2 入门

1. 一句话简介

OAuth2 是一个开放授权(Authorization)协议,核心解决的问题是:让第三方应用在不接触用户明文密码的前提下,获得访问用户受保护资源的受限授权。它把「认证(你是谁)」和「授权(你能访问什么)」分离,通过授权服务器(Authorization Server)、资源服务器(Resource Server)、客户端(Client)三方协作完成令牌的分发、验证与资源访问控制。

本 demo 模块(demo-oauth)用 Spring Security OAuth2 落地了完整的授权体系:oauth-authorization-server 负责用 JWT(私钥签名、非对称加密)签发 Access Token,oauth-resource-server 用公钥验签,通过 @EnableAuthorizationServer / @EnableResourceServer 两个注解配合 AuthorizationServerConfigurerAdapter / ResourceServerConfigurerAdapter 实现,并演示了授权码(Authorizaton Code)与密码(Password)两种授权模式,用户与客户端信息均从 MySQL 数据库加载。

2. 什么时候使用

✅ 适用场景

  • 第三方应用授权:需要让不信任的第三方 App 访问用户的资源(如用微信/QQ 登录某网站、授权某 App 读取你的相册),且不能把密码交给第三方,OAuth2 的授权码模式是最佳方案。
  • 多系统统一认证与授权:在微服务或前后端分离架构中,把认证和授权职责集中到授权服务器统一签发 Token,各资源服务器只负责验签鉴权,避免每服务各自实现登录逻辑(本 demo 即演示了授权服务器与资源服务器分离部署)。
  • 无状态鉴权、服务间调用:使用 JWT 作为令牌时,资源服务器只需持有公钥即可本地验签,无需回授权服务器查库,适合水平扩展、跨服务传递身份信息(本 demo 的 OauthResourceTokenConfig 即用公钥实现本地验签)。
  • 细粒度权限控制:基于角色(hasRole('ADMIN'))与 Scope(#oauth2.hasScope('READ'))双重维度控制资源访问,实现「能看数据 vs 能改数据」的精细授权(见本 demo 的 TestController)。
  • 令牌生命周期管理:需要令牌可过期(access_token_validity_seconds)、可刷新(Refresh Token)、可注销(自定义退出处理)的完整生命周期管控。

❌ 不适用 / 需谨慎

  • 自身封闭系统的简单登录:仅同一系统内部、无第三方接入需求时,用 OAuth2 反而带来更多复杂性,Session + CSRF 的经典认证足以胜任,属于过度设计。
  • 对实现与配置熟悉度要求高:OAuth2(尤其授权服务器那一侧)配置复杂度高,权限模型、授权模式、Token 存储选择不当容易埋下安全漏洞,学习与调试成本不低,需充分理解协议后再引入。
  • 默认 Token 存储有局限:本 demo 的 Oauth2AuthorizationTokenConfig 使用 InMemoryTokenStore,服务重启后令牌即失效、无法水平扩展;生产环境若用非 JWT 形式令牌必须换用 Redis 等共享存储,否则集群下多实例无法互相校验。
  • JWT 一旦签发难立即吊销:JWT 无状态意味着令牌在有效期内即使被泄露也无法即时作废(除非维护黑名单),对高安全要求、需要强管控撤销的场景需谨慎设计黑名单或改用短时效。
  • 令牌自认证不依赖授权服务器在线:若资源服务器本地用公钥验签,授权服务器短暂宕机不会立刻影响已签发令牌的校验,但新的令牌获取会失败,需权衡容错与一致性。

3. 常见业务场景

第三方登录(账号打通):网站允许用户用微信、GitHub、Google 等第三方账号登录。用户点击登录后跳转到第三方授权服务器,第三方确认授权后回调返回授权码,网站用授权码换取令牌并访问用户基本信息。这正是 OAuth2 授权码模式,用户密码始终留在第三方,网站无法获取明文,安全可控。

微服务网关统一鉴权:在一个微服务体系中,独立的授权服务器集中负责登录与签名 Token(本 demo 的 :8080),各个微服务作为资源服务器(本 demo 的 :8081)只持公钥验签。新增服务无需重写认证代码,只需配置公钥与资源 ID 即可接入受保护 API,实现了认证能力复用与横切统一。

基于角色与 Scope 的 API 授权:一个客户端申请了 READ,WRITE 两个 Scope,不同用户又拥有不同角色。资源服务器的 TestController 通过 @PreAuthorize("hasRole('ADMIN')") 限制角色、@PreAuthorize("#oauth2.hasScope('READ')") 限制操作范围,实现「谁(角色)能做什么(Scope)」的双重开关,适合权限分层、读写分离的资源系统。

多客户端分别授权:同一用户授权给多个应用,各自持有不同的 client_id / client_secret 与配置的回调地址、授权类型、Token 时效(见数据库 sys_client_details 表)。OAuth2 允许每个客户端独立管理授权,也支持 autoApproveScopes 自动授权避免重复弹窗确认,同时 updateClientSecret 可对单个客户端单独重置密钥,适合面向多应用开放平台的场景。

令牌生命周期与刷新:Access Token 时效较短(本 demo 默认 6000 秒),过期后客户端可用 refresh_token_validity_seconds 对应的 Refresh Token 静默续期,避免频繁重新登录。配合自定义授权确认页(authorization.html)、登录页与退出处理,形成从登录、授权、获牌、访问到登出的完整闭环,适合需要持续在线的移动端 / 长连接应用。

4. 同类技术对比

维度 Spring Security OAuth2(本 demo) Spring Security + JWT 自研认证 Spring Authorization Server 第三方平台 OAuth/OpenID(如微信、GitHub)
定位 协议级授权框架,可自建授权/资源服务器 应用内认证方案,非协议标准 Spring 官方新一代授权服务器 托管云端认证/授权服务
授权能力 支持授权码/密码/客户端/刷新等完整授权模式与多种 TokenStore 通常只做登录态签发,无标准授权流程 遵循 OAuth2.1/OpenID Connect 标准 提供标准授权,由平台托管
实现复杂度 较高(需理解端点/服务/Token 配置) 低至中(自己维护令牌校验) 中高 最低(对接即用)
无状态/JWT 支撑 支持(JWT 非对称公私钥) 支持(自签自验) 支持(JWT/JWS 默认) 支持(由平台签发)
扩展/定制性 强(可换 TokenStore、自定义页面、接入 DB) 强(完全自研) 强(官方演进) 弱(受平台能力与限制约束)
运维/依赖 需自建并维护授权+资源服务 需自行保证鉴权安全性 需自建 零运维,受平台 SLA 约束
演进趋势 Spring Security OAuth2 旧版已进入维护期 官方主推、替代旧 OAuth2 组件 需要外部账号体系时首选
适用规模 中大型自建统一授权体系 中小型单体/内部系统 新项目自建授权服务器 纳入外部生态 / 快速上线

选型建议

  • 自建、需要完整协议级授权与高可控性:若需要同时掌控授权服务器与资源服务器、定制令牌存储与页面,且愿意承担配置复杂度,选 Spring Security OAuth2(本 demo 的模式);但涉及新项目应优先用官方新一代 Spring Authorization Server,因为旧版 spring-security-oauth2-autoconfigure 已进入维护期。
  • 内部系统、只需要简单登录态:若仅同一个封闭系统内做认证鉴权、无第三方与多客户端授权需求,用 Spring Security + Session 或自己签发 JWT 即可,无需引入完整 OAuth2,更轻量、更易维护。
  • 需接入外部账号生态 / 快速上线:要支持微信、GitHub 等平台账号登录或借助成熟云认证时,直接对接第三方 OAuth2 / OpenID Connect 最省成本,遵循 T-领域标准且零运维。
  • 统一的实践组合:许多生产系统采用「第三方 OAuth2 做外部打点 + 自建授权服务器(新一代 Spring Authorization Server)/ JWT 做内部服务间鉴权」,各取所长,兼顾安全与落地成本。
OAuth2 入门
http://www.clxhxhhr.top/posts/498/
作者
clxstart
发布于
2026-09-07
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。