App-Token源码实现:spring-security-oauth2-password-jpa-implementation


这是一个基于 App-Token 的 Spring Security 6 Spring Authorization Server 的完全扩展和可扩展实现,用于 OAuth2密码授予(ROPC)和授权码授予。

什么是 App-Token?
App-Token 是同一个账号每次登录时生成的新访问令牌,如果令牌值相同,则共享同一个访问令牌。

与用户令牌的区别

  • App-Token
    • 标识的是应用程序或客户端,而不是特定用户。
    • 通常是长期有效或基于某种刷新机制(但有时也会设置有效期以防滥用)。
    • 适合 B2B 应用场景,或者需要在多个后端服务间通信时使用。
  • 用户令牌
    • 用于标识和授权某个具体用户。
    • 通常与用户的会话相关,具有较短的有效期。

什么是 OAuth2 密码授予(ROPC)?
密码授予(Resource Owner Password Credentials Grant,简称 ROPC) 是 OAuth 2.0 协议中的一种授权模式。它允许客户端直接向授权服务器提交用户的用户名和密码,以换取访问令牌(Access Token)。在这种模式下,客户端以用户身份执行操作。

ROPC 模式的典型流程如下:

  1. 用户提供凭据: 用户通过客户端(如一个应用程序)输入用户名和密码。
  2. 客户端发送请求: 客户端将用户凭据连同客户端的标识信息(如客户端 ID 和密钥)发送到授权服务器。
  3. 授权服务器验证凭据: 授权服务器验证用户的凭据和客户端的合法性。
  4. 返回访问令牌: 如果验证成功,授权服务器颁发访问令牌和可能的刷新令牌。

ROPC 的主要特点

  • 直接凭据暴露: 客户端需要知道用户的用户名和密码。
  • 无交互式授权: 不需要用户重定向到浏览器或授权页面,适用于无界面设备或命令行工具。
  • 对用户信任度要求高: 假设用户信任客户端,并愿意在客户端中输入凭据。

为什么 ROPC 应该消失?
ROPC 模式存在多个显著缺点,导致它逐渐被认为不安全,且在现代系统中不应鼓励使用:
1. 用户凭据暴露风险

  • 客户端需要直接存储或处理用户的用户名和密码,增加了泄漏的风险。
  • 如果客户端被攻破,攻击者可以直接获取用户凭据。
2. 难以实现多因素认证
  • 现代安全体系中,多因素认证(MFA)是基础,而 ROPC 模式难以支持这种机制,因为它依赖单一凭据。
3. 不符合最小权限原则
  • ROPC 让客户端承担了更多责任(管理用户凭据),而现代安全设计鼓励将身份验证交给更专业的身份提供者。
4. 缺乏用户交互保护
  • 其他授权模式(如授权码模式)通过浏览器重定向,利用授权服务器的用户界面保护用户隐私,而 ROPC 模式没有这种保障。
5. 与现代 OAuth2 最佳实践冲突
  • OAuth 2.1(即将发布的标准)明确建议避免使用密码授予模式,提倡使用授权码模式或设备授权模式。

ROPC 模式可以通过以下方式替代:

  1. 授权码模式(Authorization Code Grant):
    • 用户在授权服务器(通过浏览器)完成身份验证,客户端获取访问令牌。
    • 支持多因素认证和更复杂的安全策略。
  • 设备授权模式(Device Authorization Grant):
    • 适用于无界面设备,如 IoT 或智能设备,避免用户直接提供密码。
  • 客户端凭据模式(Client Credentials Grant):
    • 用于应用程序之间的后台通信,无需用户凭据。
  • PKCE(Proof Key for Code Exchange):
    • 授权码模式的增强版,解决公开客户端(如移动应用)在安全性上的弱点。

    该项目特点:

    • 完全分离库(API)和用于测试的客户端
    • 立即权限(权限)检查:不仅限于验证令牌本身,还确保实时验证数据库中任何权限更新。
    • 令牌自检器:启用 /oauth2/introspect 端点以允许多个资源服务器与授权服务器验证令牌的有效性和权限。
    • 基于用户名、客户端ID和App-Token组合的认证管理
    • 以管理员和客户角色的独立 UserDetails 实现为例。(可以通过实现根据需要进行扩展 UserDetailsServiceFactory)
    • 对于大于或等于v3的版本,包括最新版本(Spring Security 6),提供MySQL DDL,由 oauth2_authorization 和 组成oauth2_registered_client。

    快速入门

    <dependency>
        <groupId>io.github.patternknife.securityhelper.oauth2.api</groupId>
        <artifactId>spring-security-oauth2-password-jpa-implementation</artifactId>
        <version>3.4.0</version>
    </dependency>