文章目录ROPCResource Owner Password Credentials详解OAuth 2.0 中最具争议的授权模式引言OAuth 诞生前的问题OAuth 的核心思想什么是 ROPCROPC 请求示例ROPC 的优点1. 实现简单2. 用户体验简单3. 适合遗留系统改造ROPC 的致命问题1. 客户端必须知道用户密码2. 无法支持 MFA3. 无法支持 SSO4. 无法实现零信任认证OAuth 2.1 为什么删除了 ROPCROPC 与 Authorization Code 的比较Keycloak 中的 ROPC现在还有哪些场景会使用 ROPC企业内部系统遗留系统迁移CLI 工具历史方案总结ROPCResource Owner Password Credentials详解OAuth 2.0 中最具争议的授权模式引言在 OAuth 2.0 的各种授权模式中ROPCResource Owner Password Credentials一直是一个颇具争议的存在。一方面它实现简单、开发成本低在 OAuth 2.0 早期曾被广泛采用另一方面它要求用户直接将账号密码交给客户端应用违背了 OAuth 设计的核心理念因此如今已被大多数安全规范所淘汰。本文将介绍 ROPC 的工作原理、历史背景、优缺点以及为什么现代系统应避免使用它。OAuth 诞生前的问题在 OAuth 出现之前如果一个第三方应用需要访问用户资源通常只能让用户提供账号密码。例如邮件客户端获取 Gmail 邮件第三方网站读取社交媒体数据自动化工具访问企业系统典型流程用户 │ ├── 用户名 └── 密码 │ ▼ 第三方应用 │ ▼ 资源服务器这种方式存在明显问题用户必须将密码交给第三方应用第三方应用可能保存密码密码泄露风险极高无法限制权限范围无法单独撤销授权OAuth 的出现就是为了解决这些问题。OAuth 的核心思想OAuth 的核心原则是第三方应用不应该接触用户密码。正确的 OAuth 流程应该是用户 │ ▼ 授权服务器 │ ▼ Access Token │ ▼ 客户端应用 │ ▼ 资源服务器客户端拿到的是 Token而不是密码。这也是现代 OAuth 的基本设计理念。什么是 ROPCROPC 全称Resource Owner Password Credentials Grant中文通常翻译为资源所有者密码凭据模式在这种模式下用户直接把用户名和密码提供给客户端应用。客户端再使用这些凭据向授权服务器换取 Access Token。流程如下-------- | User | -------- | | Username Password v ----------- | Client | ----------- | | POST /token | grant_typepassword | v ------------------ | Authorization | | Server | ------------------ | | Access Token v ----------- | Client | -----------与其它 OAuth 模式相比ROPC 完全绕过了浏览器授权页面。ROPC 请求示例客户端向 Token Endpoint 发送请求POST /oauth/token grant_typepassword usernamealice password123456 client_idmy-client client_secretsecret授权服务器验证成功后返回{access_token:eyJhbGci...,token_type:Bearer,expires_in:3600,refresh_token:xyz...}之后客户端即可使用 Access Token 访问资源GET /api/profile Authorization: Bearer eyJhbGci...ROPC 的优点1. 实现简单无需浏览器跳转授权页面回调地址开发成本极低。对于早期系统来说非常方便。2. 用户体验简单用户只需要输入用户名 密码即可登录。不需要经历跳转 授权 确认 回调整个过程更加直接。3. 适合遗留系统改造很多企业内部系统原本就是用户名 密码认证模式。引入 ROPC 可以较低成本地升级到 OAuth 架构。ROPC 的致命问题虽然简单但它违背了 OAuth 最重要的设计原则。1. 客户端必须知道用户密码OAuth 的本意用户 → 授权服务器ROPC 变成用户 → 客户端 → 授权服务器客户端获得了用户密码。这意味着密码可能被记录密码可能被缓存密码可能被泄露2. 无法支持 MFA现代认证越来越依赖OTPOne-Time Password - 一次性密码每个密码只能使用一次通常每隔30或60秒生成新密码用于增强账户安全性的双因素认证技术TOTPTime-Based One-Time Password - 基于时间的一次性密码通过时间戳算法生成动态密码要求客户端和服务器时间同步是OTP的具体实现方式FIDO2Fast IDentity Online 2 - 开放式身份验证标准包含WebAuthn和CTAP两大核心组件旨在实现无密码安全认证提供防钓鱼保护Passkey通行密钥 - 基于FIDO2标准的无密码认证方式使用公钥/私钥加密技术支持生物识别或PIN码验证可跨设备同步使用WebAuthnWeb Authentication - W3C标准FIDO2的核心组件提供浏览器与认证器如安全密钥、生物识别设备之间的交互接口实现无密码网页认证例如用户名 密码 短信验证码ROPC 只能提交用户名和密码。无法很好支持这些现代认证机制。3. 无法支持 SSO现代企业普遍采用SAMLOAuthOpenID Connect进行统一身份认证。典型流程应用 ↓ Keycloak ↓ Azure ADROPC 绕过浏览器流程后无法展示登录页面无法进行身份联邦无法进行外部认证跳转因此与 SSO 天然冲突。4. 无法实现零信任认证现代安全架构越来越强调Device TrustConditional AccessRisk Based Authentication例如新设备登录 异地登录 高风险IP这些场景通常需要浏览器交互额外验证步骤ROPC 无法支持。OAuth 2.1 为什么删除了 ROPCOAuth 2.1 草案直接移除了 ROPC。原因非常明确ROPC encourages insecure handling of user credentials.即ROPC 会鼓励客户端处理用户密码从而带来安全风险。OAuth 社区认为现代系统已经有更好的替代方案。因此不再推荐继续使用。ROPC 与 Authorization Code 的比较项目ROPCAuthorization Code客户端获得密码是否支持 MFA差好支持 SSO差好支持身份联邦差好安全性低高实现复杂度低中OAuth 2.1 支持否是Keycloak 中的 ROPC在 Keycloak 中ROPC 对应Direct Access Grants开启位置Clients └── Client └── Capability Config └── Direct Access Grants Enabled启用后即可使用POST /realms/{realm}/protocol/openid-connect/token请求grant_typepassword usernamealice password123456 client_idmy-client获取 Access Token。不过 Keycloak 官方也建议除非必要否则优先使用Authorization Code FlowAuthorization Code PKCE而非 Direct Access Grants。现在还有哪些场景会使用 ROPC虽然已经过时但仍然存在于一些特殊场景企业内部系统完全可信环境员工客户端 ↓ 企业认证中心风险可控。遗留系统迁移从用户名 密码逐步迁移到OAuth 2.0过程中临时使用。CLI 工具历史方案早期命令行工具常使用username: password:获取 Token。如今越来越多工具改为Device Authorization Flow例如GitHub CLIAzure CLIGoogle Cloud CLI都已经基本放弃 ROPC。总结ROPC 是 OAuth 2.0 中最简单的一种授权模式其本质是使用用户名和密码直接换取 Access Token。它曾经帮助大量传统系统快速接入 OAuth但也因为要求客户端直接处理用户密码而带来了严重安全隐患。现代身份认证体系的发展方向已经十分明确Authorization Code FlowPKCEOpenID ConnectMFAPasskeyWebAuthn这些技术都建立在“客户端不接触用户密码”的原则之上。因此在新的系统设计中ROPC 更适合作为理解 OAuth 演进历史的一个阶段而不应作为首选方案。对于绝大多数场景Authorization Code PKCE 已经成为事实上的最佳实践。