OAuth 说明
OAuth clarification
不久前,我参加了 Go 培训,介绍了微服务架构。回到这个项目,我意识到我需要更多的上下文,因为我们当时一直在快速挖掘实施的细节......
我绘制了 2 个简单用例的简化序列图:
- 用户登录
- 用户已经登录并进行购买
(您可以在方便的时候评论/修改图表)
https://drive.google.com/file/d/1gWgkhJipUvWrVidkl7YFt_xlDmZYn_CX/view?usp=sharing
以下是我的问题:
这里我们处理的是用户身份验证,但客户端身份验证呢?在 Web 前端客户端的情况下,我可以想象在将托管此客户端的服务器的环境变量中存储 api_key 和 api_secret 吗?因为有些用例用户未登录但某些服务仍然需要可用,但与此同时我只希望我的已知客户端(Web 前台和移动应用程序)能够访问这些服务(暂且不谈 API 网关解决方案,也许还有其他 API 盾牌,可能会增加另一个针对 DOS 等的安全层)
如果客户端使用 Google/Facebook 登录,前端应用程序将收到一个 id_token
需要传递给后端,然后后端将验证令牌( https://developers.google.com/identity/sign-in/web/backend-auth)。在这种特殊情况下,我的 OAuth API 不会被使用。您能否确认这是应该处理的方式?
非常感谢。
编辑 2022 年 2 月 5 日
简介/背景
首先,Authorization is not Authentication。
Authentication is the process of verifying who a user is,
while authorization is the process of verifying what they have access to.
正如@Max 所说,OAuth 旨在管理授权,而 Open ID Connect (OIDC) 是 OAuth 的扩展,用于在其之上管理身份验证。
我在问题中公开的图表在 OAuth 世界中被称为 密码授予 ,并且 from the official documentation :
Because the client application has to collect the user's password and
send it to the authorization server, it is not recommended that this
grant be used at all anymore.
我的应用程序授权(以访问我的 APIs)
从 API 的角度来看,我们只想确保传入的请求来自托管应用程序的服务器。所以,在我的例子中,它是从后端服务器到后端服务器的简单的机器-2-机器通信,不需要用户采取任何行动。所以,我必须实施 Client Credentials Flow
...这将引导我进入此流程:
https://drive.google.com/file/d/1qE9JpWRSRPa8z5iNxm7ocGkeT0E149Sv/view?usp=sharing(欢迎评论/指正)
用户身份验证
因为 OAuth 对身份验证一无所知,所以我需要一个 OIDC 流程。最简单的一个是基于下面 OAuth 的 Authorization Code Flow with PKCE(仅关于授权)...
...但不同之处在于,当应用程序对 token endpoint
(步骤 7),除了 [ 之外,auth 服务器 returns 一个 ID 令牌 (这是一个在有效载荷中包含用户信息的 JWT -> 身份验证) =115=](不包含用户信息,仅包含“随机字符串”)。根据具体情况,还有其他 OIDC 流程及其优缺点,但这本身就是另一个话题 (https://openid.net/specs/openid-connect-core-1_0.html)
用户已被 Google/Facebook
识别
如果客户端使用 Google 登录,前端应用程序将收到 id_token。此令牌可以发送到应用服务器,然后应用服务器向 API 网关发出请求,网关随后调用 Auth api,后者将负责通过调用第 3 方身份验证服务器来验证令牌( https://developers.google.com/identity/sign-in/web/backend-auth ).
如果是 Facebook,我们会取回访问令牌,所以我不知道如何处理它...
https://developers.facebook.com/docs/facebook-login/web
https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow
使用 Firebase,有一个 onAuthStateChanged 回调,所以从 App 的角度来看,它会阻止用户未登录的请求,但从 API 的角度来看,它不保证请求来自登录用户...
https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user
Warning: the answer below is not complete, it only serves to give a rough idea
简介
OAuth2 是用于授权的协议。
资助类型
通过 OAuth2 协议,您可以使用其中一种“授权类型”或“流程”,其中一种流程在您 post 的图片中进行了说明并命名为 password grant。
这些流程中的每一个都是针对不同的场景实现的,您正确地将注意力集中在如何安全地将密码存储在网络应用程序上。
例如,对于 front-end 身份验证 (javascript / wasm),您可以使用 PKCE Flow,其中 secret_id未使用。
端点
在 OAuth2 上有两个主要的 enpoints
- 授权端点 - 获取授权码的地方
- 令牌端点 - 您在其中交换 令牌
的授权代码
代币
OAuth2 上有两种令牌
- 访问令牌
- 刷新令牌
OAuth2对token的定义是“一个不透明的字符串”,你不需要阅读它。
访问令牌用于 API,此令牌有一个到期日期,当它过期时,系统使用刷新令牌获取另一个 access_token 而无需用户交互,当 refresh_token 到期时用户必须再次re-authenticate。
您可以从 JWT.io
中读取 access_token 的内容(这是一个 JWT 令牌)
范围
访问令牌在其主体上具有范围(即阅读电子邮件、阅读姓名等)。
范围是 OAuth 2.0 中的一种机制,用于限制应用程序对用户帐户的访问。
身份
OAuth2 的顶部 正在构建其他协议 OIDC aka IdToken aka Open Id Connect 是其中之一,换句话说 OIDC 协议使用 OAuth2 建立身份验证.
对于 OIDC,还有另一个令牌 id_token,此令牌随用户信息一起提供且未使用 授权前面API.
还有 OIDC flows 可以用来获取 id_token and/or access_token.
结论
我建议您从下面的参考资料中阅读有关 OAuth2 的信息,并使用 playground
尝试不同的流程
参考资料
我的建议是从数据入手,这是OAuth更深层次的领域。
使用授权服务器
这将使您的代码保持简单。它还将处理 Google / Facebook,并且 many other forms of authentication for you, with zero impact on your code. The Curity Community Edition 是一个免费且对开发人员友好的选项,尽管还有其他选项。例如 Keycloak、Ory Hydra。
保护数据
OAuth 主要为您提供保护数据的现代方法。使用 scopes and claims to protect data across multiple microservices in a zero trust manner while securely maintaining user context. You will also need to manage joining identity and business data.
实施UI 正确流动
移动应用程序使用 AppAuth pattern. The current best practice for browser based apps is a Backend for Frontend 方法。这两个都很棘手。
保持基于代码标准
以上Curity资源均基于OAuth相关标准。如果遵循,您的应用程序将保持简单,带有可移植代码,也可以与其他提供商一起使用。
虽然 OAuth 非常具有架构性,最好的设计需要时间来学习,但是您可以逐渐了解其中的复杂性。我们的 IAM Primer 是一个很好的起点。
不久前,我参加了 Go 培训,介绍了微服务架构。回到这个项目,我意识到我需要更多的上下文,因为我们当时一直在快速挖掘实施的细节......
我绘制了 2 个简单用例的简化序列图:
- 用户登录
- 用户已经登录并进行购买
(您可以在方便的时候评论/修改图表) https://drive.google.com/file/d/1gWgkhJipUvWrVidkl7YFt_xlDmZYn_CX/view?usp=sharing
以下是我的问题:
这里我们处理的是用户身份验证,但客户端身份验证呢?在 Web 前端客户端的情况下,我可以想象在将托管此客户端的服务器的环境变量中存储 api_key 和 api_secret 吗?因为有些用例用户未登录但某些服务仍然需要可用,但与此同时我只希望我的已知客户端(Web 前台和移动应用程序)能够访问这些服务(暂且不谈 API 网关解决方案,也许还有其他 API 盾牌,可能会增加另一个针对 DOS 等的安全层)
如果客户端使用 Google/Facebook 登录,前端应用程序将收到一个
id_token
需要传递给后端,然后后端将验证令牌( https://developers.google.com/identity/sign-in/web/backend-auth)。在这种特殊情况下,我的 OAuth API 不会被使用。您能否确认这是应该处理的方式?
非常感谢。
编辑 2022 年 2 月 5 日
简介/背景
首先,Authorization is not Authentication。
Authentication is the process of verifying who a user is, while authorization is the process of verifying what they have access to.
正如@Max 所说,OAuth 旨在管理授权,而 Open ID Connect (OIDC) 是 OAuth 的扩展,用于在其之上管理身份验证。
我在问题中公开的图表在 OAuth 世界中被称为 密码授予 ,并且 from the official documentation :
Because the client application has to collect the user's password and send it to the authorization server, it is not recommended that this grant be used at all anymore.
我的应用程序授权(以访问我的 APIs)
从 API 的角度来看,我们只想确保传入的请求来自托管应用程序的服务器。所以,在我的例子中,它是从后端服务器到后端服务器的简单的机器-2-机器通信,不需要用户采取任何行动。所以,我必须实施 Client Credentials Flow
...这将引导我进入此流程:
https://drive.google.com/file/d/1qE9JpWRSRPa8z5iNxm7ocGkeT0E149Sv/view?usp=sharing(欢迎评论/指正)
用户身份验证
因为 OAuth 对身份验证一无所知,所以我需要一个 OIDC 流程。最简单的一个是基于下面 OAuth 的 Authorization Code Flow with PKCE(仅关于授权)...
...但不同之处在于,当应用程序对 token endpoint
(步骤 7),除了 [ 之外,auth 服务器 returns 一个 ID 令牌 (这是一个在有效载荷中包含用户信息的 JWT -> 身份验证) =115=](不包含用户信息,仅包含“随机字符串”)。根据具体情况,还有其他 OIDC 流程及其优缺点,但这本身就是另一个话题 (https://openid.net/specs/openid-connect-core-1_0.html)
用户已被 Google/Facebook
识别如果客户端使用 Google 登录,前端应用程序将收到 id_token。此令牌可以发送到应用服务器,然后应用服务器向 API 网关发出请求,网关随后调用 Auth api,后者将负责通过调用第 3 方身份验证服务器来验证令牌( https://developers.google.com/identity/sign-in/web/backend-auth ).
如果是 Facebook,我们会取回访问令牌,所以我不知道如何处理它...
https://developers.facebook.com/docs/facebook-login/web https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow
使用 Firebase,有一个 onAuthStateChanged 回调,所以从 App 的角度来看,它会阻止用户未登录的请求,但从 API 的角度来看,它不保证请求来自登录用户...
https://firebase.google.com/docs/auth/web/manage-users#get_the_currently_signed-in_user
Warning: the answer below is not complete, it only serves to give a rough idea
简介
OAuth2 是用于授权的协议。
资助类型
通过 OAuth2 协议,您可以使用其中一种“授权类型”或“流程”,其中一种流程在您 post 的图片中进行了说明并命名为 password grant。
这些流程中的每一个都是针对不同的场景实现的,您正确地将注意力集中在如何安全地将密码存储在网络应用程序上。
例如,对于 front-end 身份验证 (javascript / wasm),您可以使用 PKCE Flow,其中 secret_id未使用。
端点
在 OAuth2 上有两个主要的 enpoints
- 授权端点 - 获取授权码的地方
- 令牌端点 - 您在其中交换 令牌 的授权代码
代币
OAuth2 上有两种令牌
- 访问令牌
- 刷新令牌
OAuth2对token的定义是“一个不透明的字符串”,你不需要阅读它。 访问令牌用于 API,此令牌有一个到期日期,当它过期时,系统使用刷新令牌获取另一个 access_token 而无需用户交互,当 refresh_token 到期时用户必须再次re-authenticate。
您可以从 JWT.io
中读取 access_token 的内容(这是一个 JWT 令牌)范围
访问令牌在其主体上具有范围(即阅读电子邮件、阅读姓名等)。 范围是 OAuth 2.0 中的一种机制,用于限制应用程序对用户帐户的访问。
身份
OAuth2 的顶部 正在构建其他协议 OIDC aka IdToken aka Open Id Connect 是其中之一,换句话说 OIDC 协议使用 OAuth2 建立身份验证.
对于 OIDC,还有另一个令牌 id_token,此令牌随用户信息一起提供且未使用 授权前面API.
还有 OIDC flows 可以用来获取 id_token and/or access_token.
结论
我建议您从下面的参考资料中阅读有关 OAuth2 的信息,并使用 playground
尝试不同的流程参考资料
我的建议是从数据入手,这是OAuth更深层次的领域。
使用授权服务器
这将使您的代码保持简单。它还将处理 Google / Facebook,并且 many other forms of authentication for you, with zero impact on your code. The Curity Community Edition 是一个免费且对开发人员友好的选项,尽管还有其他选项。例如 Keycloak、Ory Hydra。
保护数据
OAuth 主要为您提供保护数据的现代方法。使用 scopes and claims to protect data across multiple microservices in a zero trust manner while securely maintaining user context. You will also need to manage joining identity and business data.
实施UI 正确流动
移动应用程序使用 AppAuth pattern. The current best practice for browser based apps is a Backend for Frontend 方法。这两个都很棘手。
保持基于代码标准
以上Curity资源均基于OAuth相关标准。如果遵循,您的应用程序将保持简单,带有可移植代码,也可以与其他提供商一起使用。
虽然 OAuth 非常具有架构性,最好的设计需要时间来学习,但是您可以逐渐了解其中的复杂性。我们的 IAM Primer 是一个很好的起点。