使用 openid-connect 进行身份验证 spa 和 rest api

Using openid-connect for authentication spa and rest api

我有一个 API 服务器(资源服务器)和多个应用程序、Web GUI (SPA) 和桌面客户端,也许还会有更多。 除了 http 基本身份验证之外,我还想为我的 API 服务器使用 openid-connect。 使用哪个 openid 提供程序应该是可配置的。我自己的,facebook,google... 我只想做认证,我不需要他们API。我只需要一些个人资料数据,例如电子邮件或名字。

假设我已将 google 配置为我的 IdP,并且我目前正在使用我的 Web GUI (SPA)。我需要登录,没问题,根据 https://developers.google.com/identity/protocols/OpenIDConnect 我将用户重定向到 google,获取我的授权码,Web Gui (SPA) 获取 id_token 和 access_token来自 google.

到目前为止没有问题,但现在 SPA 必须与我的 API 服务器一起工作,并且 API 服务器需要对每个请求进行身份验证(因为它是无状态的休息 api ) 来自客户端 (WebGui SPA),需要知道哪个用户实际执行了此操作。

A

所以 google 中的 access_token 是用来访问 google api 的,对吗?但我也可以将此 access_token 与每个请求一起传递到我的 api 服务器,并且 api 服务器调用 https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=xxx 来验证 access_token 并获取帐户名称(邮件)。但这听起来不对吧?

B

我也有 id_token 可以验证,而无需每次都调用 google 服务器。那么我是否也可以将 id_token 作为每个请求的承载传递给我的 api 服务器,并且 api 服务器可以验证 id_token?但是根据 openid-connect 规范,access_token 实际上是刚刚传递给 api 服务器的那个,而 id_token 必须留在客户端。 但是 id_token 对我来说完全没用,API 服务器需要知道用户是谁,客户端(Web GUI)并不关心。

C

或者因为它是我自己的 API 服务器,我的 API 服务器实际上是否需要自己实现整个 oauth2 系统,只是不是身份验证而是创建 access_token 等等。所以我会有一个 /api/tokensign,我可以将 google 的 id_token 传递给它,API 验证 id_token 并创建一个 access_token我的 WebGUI (SPA)。并且这个新的 access_token 可以作为承载传递给每个 api 请求。根据规范,这实际上听起来是最好的解决方案,但我真的需要自己在 API 中实现 oauth2 吗?听起来像是一个沉重的补充,因为 A 和 B 也可以实现。

我的其余部分-api 需要对每个请求进行身份验证,那么 A、B、C 是正确的方法吗?请不要告诉我这是基于意见的,它不是。 使用 oauth2/openid-connect 进行身份验证的正确方法是什么?

你上面提到的三种方法都可以用,但确实要有一些注意事项。我将根据可用规格对其进行解释。

场景 - 两个系统S1, S2

  • S1 - 身份提供商
  • S2 - API 端点

你需要什么 - 信任并使用S1发布的'Tokens'来访问S2

对建议解决方案的解释 ABC

A - 验证S1为每次调用颁发的令牌

这可以使用 RFC7662 - OAuth 2.0 令牌自检端点来完成。此验证符合规范,因此您可以使用令牌验证端点。

这种方法的优点是,如果令牌被撤销,效果是即时的。下一个 API 调用将失败。但确实对性能有影响。您需要额外的验证服务电话。

请注意,您不需要从此验证响应中获取帐户名。它可以从 ID 令牌中获取,并可用于验证以提供额外保护。

B - S1为每次调用颁发的信任令牌

现在这种方法是从 RFC6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage. You can indeed use ID toke to authenticate and authorise an end user. This link 扩展而来的,包含对 ID 令牌用作不记名令牌的很好解释。

您确实可以使用MAC甚至加密来验证令牌的有效性。但请注意使用短期令牌并始终使用 TLS。并注意刷新令牌。!因为根据openID connect规范,ID token不是refresh token请求的必填项。

C - 联邦的包装器

为此,您可以编写自己的解决方案或使用现有解决方案(例如:- WSO2 identity server)。此身份服务器将配置为在您的应用程序(桌面应用程序或 Web 应用程序等客户端)上选择身份提供者。身份服务器将进行必要的重定向并为您提供所需的令牌。但实际上您需要使用内省端点来验证令牌有效性。

如果你比这个解决方案更进一步,你可以尝试实现一种代码交换机制。您可以将令牌携带从外部交换为您的系统之一在内部发布的令牌(例如:- Google 访问令牌到您的内部访问令牌)。这种方法的优点是您可以控制验证。此外,由于后续令牌验证是在内部完成的,因此应该会提高性能。

希望这能解释你的一些疑惑。