将openid connect用作多个应用程序的SSO

时间:2018-08-13 14:09:39

标签: security oauth-2.0 openid-connect

我正在尝试使用openid connect为我的应用程序创建SSO。

基本上我们只有一个API层,并且不同的Apps(客户端)将使用该层的服务。

首先,我们为每个不同的应用添加了OAuth2.0进行授权;为了进行身份验证,我们目前正在使用我们自己的数据库(IDP)

我们希望最终用户对此流程具有单一登录体验。 为此,我们在构建的OAuth流之上添加了openid。

Web服务器具有标准的oauth + openid实现,并且具有以下功能

  • 显式流
  • 隐式流
  • 密码授予

添加openid连接后,服务器现在还可以根据范围和请求类型发送id_token(jwt)

有两个注册的客户(C1和C2)

步骤1:C1遵循显式流程,并使用响应类型作为代码,因此,当用户(U1)访问C1时,它将被重定向到U1输入凭据的身份验证服务器。

步骤2:授权服务器验证凭据并提示用户同意,确认哪个将代码发送到C1的redirect_uri

第3步:C1然后请求令牌,服务器发出access_token和id_token;访问令牌被持久存储在数据库中

第4步:U1现在需要访问C2

问题:

  • C2从api服务器获取访问令牌而无需用户再次登录的最佳方法/做法是什么。
  • 如果C1通过本地存储或任何其他方式将jwt id_token传递给C2,则一种可能的方法是将{_3}}之后的id_token替换为access_token。
  • 如果采用上述方法,仅验证id_token并签发access_token就足够了,还是应该添加任何其他检查
  • 任何其他方法。

谢谢

2 个答案:

答案 0 :(得分:2)

如果这些客户端是Web应用程序,则出于某些原因,最佳和推荐使用的流程是隐式流程:

  • 在这种情况下,如果将其与混合流进行比较,则它是安全的,因为混合流与clinet共享一个秘密密钥,并且客户端必须保留它,另一方面,此密钥用于生成acces_tokens隐式流直接向客户端提供访问令牌,且生存期很短,因此,最好的方法是为访问令牌提供较短的生存期,而不是可以用于生成令牌的具有较长生存期的授权密钥。
  • SSO(单点登录)将在共享同一STS服务器的客户端之间完美运行,因此C2可以具有无需身份验证的access_token,这是步骤:

    1. C1进行身份验证并获取ID令牌和一个access_token

    2. 为此活动会话创建了一个会话cookie

    3. C2单击登录,将直接获得无需身份验证的access_token,因为浏览器将发送通过C1身份验证创建的有效cookie

答案 1 :(得分:2)

流量的选择将取决于客户端的类型。例如,客户端可以是本机应用程序,可以使用授权代码流(我想您将“显式流”称为该流)。或仅在浏览器上运行的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。