使用OpenID Connect作为多个应用程序的单点登录

4
我正在尝试使用OpenID Connect为我的应用程序创建SSO。基本上,我们有一个API层,不同的应用程序(客户端)将消耗此层的服务。首先,我们为每个不同的应用程序添加了OAuth2.0进行授权;对于身份验证,我们目前使用自己的数据库(IDP)。我们希望最终用户在这个流程中有一个单一的登录体验。为了实现这一点,我们在我们已经构建的OAuth流程之上添加了OpenID。Web服务器具有标准的OAuth + OpenID实现,并具有以下功能:显式流、隐式流和密码授权。在添加OpenID Connect之后,服务器现在可以根据范围和请求类型发送id_token(jwt)。注册了两个客户端(C1和C2)。步骤1:C1遵循显式流并使用响应类型作为代码,因此当用户(U1)访问C1时,它会被重定向到认证服务器,其中U1输入凭据。步骤2:授权服务器验证凭据并提示用户同意,确认后将代码发送到C1的redirect_uri。
步骤3:C1请求令牌,服务器发放access_token和id_token;access_token存储在数据库中。
步骤4:现在U1需要访问C2。
问题:
- C2从api服务器获取access_token的最佳方式/实践是什么,而不需要用户重新登录? - 如果C1通过本地存储或其他方式传递jwt id_token到C2,一种可能的方法是按照this交换id_token以获得access_token。 - 如果我们采用上述方法,只验证id_token并发放access_token是否足够,还是应该添加其他检查? - 任何其他方法。
谢谢。
2个回答

4

根据客户端类型的不同,选择的流程也会有所不同。例如,客户端可以是本地应用程序,可以使用授权码流(我猜你指的是显式流)。或者是仅在浏览器上运行的JavaScript应用程序。

解决方案 - 基于会话cookie的SSO

在OAuth 2.0(包括OpenID Connect)中,终端用户(例如您示例中的U1)的身份验证是通过浏览器交互进行的。在此过程中,通常授权服务器会建立一个会话。这个会话的作用是保持对先前经过身份验证的用户的引用。例如,这允许用户访问IDP并在那里更新用户内容(如果您的身份提供者支持此功能)。

现在,如果两个应用程序都使用相同的浏览器(例如Microsoft Edge)来显示OpenID Connect的登录屏幕中的授权请求,则授权服务器可以检查浏览器中是否存在会话cookie。如果是这种情况,授权服务器可以跳过登录屏幕并响应相关内容。以下是使用全新登录的示例场景:

  1. C1启动授权请求,并重定向到授权端点
  2. 授权服务器接收请求并检查会话cookie。
  3. 由于这是一个全新的开始,不存在cookie,因此需要登录
  4. 用户U1登录
  5. 授权服务器发送响应并C1完成令牌获取
  6. C2启动授权请求,并重定向到授权端点
  7. 授权服务器接收请求并检查会话cookie。
  8. 由于我们使用相同的浏览器,会话cookie存在且相关联的用户被识别为U1
  9. 授权服务器发送响应并C2完成令牌获取

现在,C1和C2都已经有U1用户登录。这是基于浏览器的SSO。


2
如果这些客户端是Web应用程序,建议使用Implicit流程,原因如下:
- 与混合流程相比,它更加安全,因为混合流程与客户端共享一个密钥,客户端必须保留该密钥,该密钥用于生成访问令牌。而Implicit流程直接向客户端提供具有短生命周期的访问令牌,因此最好提供具有短生命周期的访问令牌,而不是具有长生命周期的授权密钥,后者可用于生成令牌。
- 单点登录(SSO)将在共享同一STS服务器的客户端之间完美地工作,因此C2可以在不进行身份验证的情况下获得访问令牌,以下是步骤:
1. C1进行身份验证并获取id-token和access_token。 2. 为该活动会话创建一个会话cookie。 3. C2单击登录,将直接获得访问令牌,无需进行身份验证,因为浏览器将发送从C1身份验证创建的有效cookie。

如果访问令牌中嵌入了客户端ID,并且服务器使用客户端ID来控制访问,则所提到的解决方案将起作用。 - Roll no1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接