OAuth 2:分离资源服务器和授权服务器

Posted

技术标签:

【中文标题】OAuth 2:分离资源服务器和授权服务器【英文标题】:OAuth 2: separating resource server and authorization server 【发布时间】:2013-04-20 03:23:12 【问题描述】:

OAuth 2 规范让我相信“资源服务器”和“授权服务器”不一定是同一个应用程序,但我很难弄清楚这在实践中是如何实现的。

例如,假设存在以下应用:

资源服务器 授权服务器 网络前端 第三方客户端应用

场景 #1:登录到 Web 前端

用户提交登录表单 Web 应用将凭据 POST 到身份验证服务器 (grant_type=password) 并接收 access_token 网络应用程序将 access_token 存储在会话中 在每个后续请求中: 从资源服务器获取资源(在 Authorization 标头中带有 access_token)并在 Web 前端呈现它 如果我们收到 401,则将用户注销(从会话中删除 access_token)

场景 #2:授权第三方应用

用户向身份验证服务请求授权 显示允许/拒绝表单 用户被重定向回客户端应用,授权码存在 客户端应用 POST 代码到身份验证服务 (grant_type=authorization_code) 并接收 access_token 客户端通过资源服务器获取资源(带 Auth 标头)

我无法理解的部分是如何在场景 #2 中显示允许/拒绝表单之前对用户进行身份验证。用户可能已登录到主 Web 应用程序,但身份验证服务对此一无所知,并且会以某种方式需要再次对用户进行身份验证。 auth 服务是否也需要支持登录/会话?

我想知道由网络应用负责显示允许/拒绝表单是否更有意义,原因有两个:

    它将所有 UI 保存在一个应用中 不会强制用户在已登录网络应用程序的情况下重新提交其凭据

这是场景 #2 的一种可能替代方案:

用户从网络应用请求授权 显示允许/拒绝表单 Web 应用 POST 到身份验证服务器创建新授权,返回授权代码 Web 应用重定向到存在授权码的客户端应用 客户端应用 POST 代码到身份验证服务并接收 access_token

处理此问题的最佳方法是什么?任何一般的 cmets、建议等都会很棒!

谢谢

【问题讨论】:

【参考方案1】:

[http://alexbilbie.com/guide-to-oauth-2-grants/][1] 尝试访问此以获得更清晰的信息。

正如前面的作者所说,只有当您属于 [SPA] 或移动应用属于第一方时,才会使用密码授权 就像直接登录到 gmail 一样。 GMAIL 是谷歌页面/应用的一部分,

ii) 从授权服务器获取代码 [granttype=code] 的令牌应该从后端发生,而不是从浏览器后端通道通信]

查看 OAUTH2 IN ACTION 书籍 - Manning 出版物,迄今为止关于 oauth2 的最佳文章之一

【讨论】:

alexbilbie.com/guide-to-oauth-2-grants的精彩解释【参考方案2】:

OAauth2 框架文档:https://www.rfc-editor.org/rfc/rfc6749

(A) 客户端通过身份验证请求访问令牌 授权服务器并提供授权。

(B) 授权服务器对客户端进行身份验证并验证 授权授予,如果有效,则颁发访问令牌 和一个刷新令牌。

(C) 客户端向资源发出受保护的资源请求 服务器通过提供访问令牌。

(D) 资源服务器验证访问令牌,如果有效, 处理请求。

(E) 重复步骤 (C) 和 (D) 直到访问令牌过期。如果 客户端知道访问令牌已过期,它跳到步骤(G); 否则,它会发出另一个受保护的资源请求。

(F) 由于访问令牌无效,资源服务器返回 无效令牌错误。

(G) 客户端通过身份验证请求新的访问令牌 授权服务器并提供刷新令牌。这 客户端身份验证要求基于客户端类型 以及授权服务器策略。

(H) 授权服务器对客户端进行身份验证并验证 刷新令牌,如果有效,则发出一个新的访问令牌(并且, (可选)一个新的刷新令牌)。

【讨论】:

【参考方案3】:

你的替代方案可能是你想要的:如果你真的想分离你的流,你可以尝试这样的事情:

    用户使用 grant_type=code 代表服务向 auth 服务请求授权 auth 服务实现用户未登录:重定向到带有请求参数的 Web 应用程序,要求 Web 服务器将用户发送回。 web 应用存储请求参数,然后询问用户名/密码 Web 应用将凭据 POST 到身份验证服务器 (grant_type=password) 并接收 access_token。 网络应用程序将 access_token 存储在会话中 Web 应用程序生成一个捕获用户 ID 的签名令牌,并使用签名令牌作为请求参数重定向回身份验证服务 身份验证服务解析签名令牌,提取用户 ID,显示允许/拒绝表单 用户被重定向回客户端应用,授权码存在 客户端应用 POST 代码到身份验证服务 (grant_type=authorization_code) 并接收 access_token 客户端通过资源服务器获取资源(带 Auth 标头)

【讨论】:

谢谢!这是一个有趣的方法。仍然不确定是否值得增加复杂性。 是的,有一个问题:如果您有很多不同的网络应用程序使用相同的身份验证后端(就像 Google 一样),您可能需要一个专用的身份验证服务器,上面有所有相关的登录屏幕.对于单个应用程序可能不值得工作。 密码授权类型只能用于由拥有授权服务的实体拥有和控制的应用程序。否则,它会打开严重的安全漏洞。用户只应将其凭据提供给颁发它们的应用程序。

以上是关于OAuth 2:分离资源服务器和授权服务器的主要内容,如果未能解决你的问题,请参考以下文章

Spring OAuth2 资源和授权服务器

springboot+spring security +oauth2.0 demo搭建(password模式)(认证授权端与资源服务端分离的形式)

OAuth 2.0 的四种授权模式

OAuth 2.0 授权介绍和使用

SpringBootSecurity学习(15)前后端分离版之 OAuth2.0简单示例

Django OAuth - 独立的资源和授权服务器