OpenID Connect:验证用户身份的正确方法-ID令牌还是Access令牌?刷新ID令牌?

时间:2018-11-12 09:39:58

标签: asp.net authentication openid-connect refresh-token

在我们的Web应用程序(ASP.NET)中,我们将OpenID Connect与授权代码流结合使用:

  1. 将用户重定向到身份提供者(例如Azure AD),进行身份验证,
  2. 授权代码被回发到我们的Web应用程序中的页面。
  3. 然后,我们的Web应用程序使用授权码从身份服务器检索刷新令牌,ID令牌和访问令牌。这些作为cookie(将HttpOnly标志设置为true)存储在客户端上。这是为了避免在负载平衡器将用户路由到其他Web服务器的情况下依赖于服务器状态。
  4. 当用户访问页面时,我们将验证ID令牌的签名和有效期,并根据我们的应用程序中的用户数据库检查我们用于身份(例如电子邮件地址或UPN)的声明。

这可行-除了我们无法刷新ID令牌之外,因此用户在1小时后超时,需要重新登录。根据OpenID Connect规范,在使用令牌端点刷新令牌时,并非所有OpenID Connect提供程序都将提供新的ID令牌。

到目前为止我们看到的替代方案:

  1. 完全不使用ID令牌。使用访问令牌查询用户声明的UserInfo端点,并将其缓存在服务器上(在缓存未命中时,例如如果路由到其他Web服务器-只需使用cookie中提供的访问令牌再次请求UserInfo)。由于访问令牌可以刷新,因此可能会正常工作。
    • 优点:我们获得了正确刷新的令牌,该令牌已由服务器验证。
    • 缺点:至少对于Azure AD,UserInfo端点并没有提供所有声明(例如aud和iss)。
  2. 不要验证ID令牌的有效期,只是它不早于例如12小时。
    • 优点:简单,只需很少的努力即可改变当前的行为。拥有我们今天也拥有的所有主张。
    • 缺点:可能会带来安全风险吗?有评论吗?

那么,建议长时间保留用户登录名的方法是什么?将访问令牌与UserInfo端点一起使用是否合适?

2 个答案:

答案 0 :(得分:3)

首先,您需要了解每个令牌的用途。客户端(应用程序)将使用ID令牌。它包含可以验证以验证最终用户身份的声明(身份验证)。

访问令牌用于授权。它旨在用于受保护的资源(例如:受OAuth 2.0令牌保护的API)。 API收到令牌后,必须对其进行验证并授予访问权限。

刷新令牌可用于刷新访问令牌。现在,OpenID Connect是OAuth 2.0的扩展,允许使用刷新令牌。但正如您所知,ID令牌可能会刷新也可能不会刷新。我个人已经看到Auzre AD不会刷新ID令牌。

您最好的解决方案是在前端和后端之间使用会话。在验证来自令牌请求的令牌后,可以设置此会话。会话存储可以保存最初发送的访问令牌。并存储刷新令牌。您可以简单地验证ID令牌并将其丢弃(假设您将所有必需的信息存储到会话中)。确保此会话为HttpOnly和Secure(仅Https)。会话期满可以等于访问令牌有效性。

一旦访问令牌过期,您就可以使用刷新令牌来获取新令牌。而且,无论何时您的后端,都可以将访问令牌附加到来自后端的API请求中。这样,您就永远不会向前端公开访问令牌和刷新令牌。

答案 1 :(得分:3)

这取决于身份令牌的使用方式。通常情况下,只有客户可以使用。它允许客户端根据强制性sub声明对用户进行身份验证。 不应将其用于授权。这就是访问令牌的用途。

在混合流(代码+ id_token)中,您可以在请求其他令牌之前检查用户的真实性。在那种情况下,一个小的令牌是最有效的。

在授权代码流(代码)中,无论如何都必须使用代码来请求令牌。现在,它取决于id_token中的信息。如果id_token不包含配置文件声明,那么您需要从UserInfo端点请求信息。

为了访问UserInfo端点,您需要访问令牌。丢失的audiss声明可能不是问题,因为您是由授权机构本身请求令牌的。在我看来,此时发行人和受众已经广为人知。

请注意,id_token不用于授权,因此不存在安全风险。即使与资源共享id_token也是如此。

规范要求您按照说明验证收到的令牌。但是,当您没有收到新的id_token时,为什么还要再次验证当前的id_token?它可能不是最新的,但已经过验证。

所以IMO这两个选项都很好,尽管我认为第一个选项更常见。 id_token使用后很可能会被丢弃。因为访问令牌用于访问资源(包括UserInfo端点),而刷新令牌用于刷新访问令牌。

一句话,用户的同意被用作过滤器。如果用户不同意个人资料信息,那么它将完全不可用。