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

raf*_*fis 7 api oauth-2.0 single-page-application openid-connect google-openidconnect

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

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

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

一种

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

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

C

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

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

Kav*_*uwa 2

您可以使用上面提到的所有三种方法,但确实需要考虑一些因素。我将根据可用规格对其进行解释。

场景- 两个系统S1S2

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

您需要什么- 信任并使用S1颁发的“令牌”来访问S2

对建议解决方案ABC的解释

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

这可以使用RFC7662 - OAuth 2.0 令牌自省端点来完成。此验证根据规范是有效的,因此您可以使用令牌验证端点。

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

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

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

现在,这种方法是从RFC6750 - OAuth 2.0 授权框架:承载令牌使用扩展而来的。您确实可以使用 ID 令牌来对最终用户进行身份验证和授权。此链接包含有关 ID 令牌用作不记名令牌的很好的解释。

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

C - 联合的包装器

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

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

希望这可以解释您的一些疑问。