7

I have an API Server (Resource server) and multiple apps, Web GUI (SPA) and a Desktop client and maybe more coming. I'd like to use openid-connect besides http basic authentication for my API Server. It should be configurable which openid provider to use. My own, facebook, google... I only want to do authentication, I do not need their API. I only need some profile data like email or firstname.

Let's say I have configured google as my IdP and I'm currently using my Web GUI (SPA). I need to login, no problem, according to https://developers.google.com/identity/protocols/OpenIDConnect I redirect the user to google, get my authorization code and the Web Gui (SPA) gets an id_token and access_token from google.

No problem so far, but now the SPA has to work with my API Server and the API Server needs to authenticate every request (since it is a stateless rest api) coming from the Client (WebGui SPA) and needs to know which user actually did this.

A

So the access_token from google is meant to be used to access google api's right? But I also could just pass this access_token with every request to my api server and the api server calls https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=xxx to verify the access_token and get the account name (mail). But this doesn't sound right, does it?

B

I also have and id_token which I can verify without calling google server everytime. So could I also just pass the id_token as bearer with every request to my api server and the api server can verify the id_token? But according to openid-connect spec the access_token is actually the one which just get passed to the api server and the id_token must stay on the client. But then the id_token would be completely useless to me, the API server needs to know who the user is, the client (Web GUI) doesn't really care.

C

Or since it is my own API Server, does my API Server actually needs to implement the whole oauth2 system by itself, just not authentication but creating access_token and more. So I would have a /api/tokensign to which I can pass the id_token from google, the API verifies the id_token and creates an access_token for my WebGUI (SPA). And this new access_token can be passed as bearer to every api request. This actually sounds as the best solution according to specs, but do I really need to implement oauth2 by myself into my API? Sounds like a heavy addition since A and B could also be implemented.

My rest-api needs authentication with every request so is A, B, C the right approach? Please don't tell me this is opinion based, it is not. What is the right way using oauth2/openid-connect for authentication?

4

1 回答 1

2

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

场景- 两个系统S1 , S2

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

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

对建议的解决方案A , BC的解释

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

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

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

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

B - S1 为每次通话发行的信任代币

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

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

C - 联邦的包装器

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

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

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

于 2017-07-22T04:55:42.807 回答