我们最近为我们的一个 REST 平台实现了这一点,我们结合了您提到的两点,即授权标头和 JWT 令牌。虽然,JWT 仅用于身份验证和获取 access_token(oauth 令牌),稍后用于调用实际资源 API。我将讨论我们如何处理这种情况,您可以决定如何实施它。
1) 认证
客户端将 JWT 发送到您的身份验证服务 (/api/oauth2/auth)。(如果您想了解更多有关 JWT 的信息,可以阅读此处和此处谷歌如何实现 JWT 以及如何使用 spring-security-jwt 库来处理所有签名和加密/解密)。在解密和验证签名之后,您从 JWT 中获取“clientId”,并且在服务器完成所有身份验证之后,您会返回一个“refresh_token”和一个“access_token”。服务器也会保存 access_token 并将其映射到 clientId 以便当客户端使用 access_token 发出请求时,您可以知道哪个客户端发出请求。access_token 会在某个时间(最好是一个小时)过期,当它过期时,客户端使用“refresh_token”通过将 refresh_token 发布到某个刷新令牌 url (/api/oauth2/auth/token) 来获取新的访问令牌
2) 授权
客户端获取“access_token”并使用访问令牌在所有其他 api (/api/*) 上发出所有后续请求。理想情况下,access_token 作为“授权”标头的一部分发送。服务器使用请求过滤器(如果您使用 JAX-RS,您可以使用 ContainerFilterRequest 之类的东西将过滤器添加到特定的 url 模式并拦截它们)来过滤每个请求并解析出 Authorization 标头值。您将从标头中获取 access_token,并从 access_token 中获取您在步骤 1) 中映射的 clientId。您可以在安全过滤器中执行其他授权逻辑,如果一切顺利,您可以使用此信息记录该 clientId 和客户端发出的请求。
这样你就可以用一块石头杀死 2 只鸟:实施安全层并记录有关客户的信息(他们打什么电话,多少时间等)。如果您还不想实现安全过滤器(正如您提到的那样,它可能会在将来实现),现在,客户端可以将“clientId”(是否为 base64 编码,由您决定)作为一部分传递“授权”标头。如果所有呼叫都来自“受信任”网络,则应该没问题,尽管没有那么安全。这样,当您实际实现基于 JWT 和 Oauth 的安全层时,您所要做的就是更改 ContainerFilterRequest 逻辑以解析 access_token 而不是客户端 ID(如步骤 2 中所述)。
我希望这有帮助 !有关安全过滤器的更多信息,您可以查看以下答案:Dropwizard 中资源的基本身份验证。它说的是 dropwizard,但它主要谈论的是 JAX-RS。