OpenID Connect中ID令牌到期时间的意图是什么?

在OpenID Connect中, 访问令牌具有到期时间。 对于授权码stream,这通常很短(例如20分钟),之后您使用刷新令牌来请求新的访问令牌。

ID令牌也有一个到期时间。 我的问题是这个意图是什么?

任何小于刷新令牌到期时间的ID令牌过期时间将意味着您最终将拥有过期的ID令牌,但是会有一个有效的访问令牌。

那么你的意思是:

  • 让您的ID令牌的有效期超过刷新令牌到期时间,或者
  • 将其设置为与访问令牌相同的过期时间,并在到期时执行一些操作(什么?)或
  • 只是在收到客户的消费ID标记,然后忽略到期后的时间?

OpenID Connect规范只是说当validation一个ID令牌时,

"The current time MUST be before the time represented by the exp Claim." 

(可能)支持上面的第三个选项。


编辑

由于OpenID Connect基于OAuth2构build,下面的补充问题的答案可以在OAuth2规范中find,

 expires_in RECOMMENDED. The lifetime in seconds of the access token. 

一个相关的问题是,当你交换令牌的授权代码时,同样的规范说你可能会得到如下回应:

 { "access_token": "SlAV32hkKG", "token_type": "Bearer", "refresh_token": "8xLOxBtZp8", "expires_in": 3600, "id_token": "eyJhbG[...]" } 

但是在这种情况下,“expires_in”涉及什么? 访问令牌,刷新令牌或ID令牌?

(有关信息, IdentityServer3将其设置为访问令牌到期时间)。

我在回答自己的问题时发现,我的问题背后的一些假设是错误的,在这里更容易澄清,而不是重写问题。

ID令牌用于向客户certificate用户已经authentication,以及他们是谁。

当客户端收到一个ID令牌时,通常会将其转换为ClaimsIdentity,并坚持这一点,例如使用cookie。

ID令牌在这个使用点必须是未到期的(应该是,因为它刚刚发布)。 但在此之后不再使用,因此在用户仍然有活动会话的情况下它是否到期并不重要 。 客户端拥有它所需要的authentication信息,并且可以select自己的策略,在用户再次login之前会话持续多长时间。

当提出这个问题时,我的错误假设是ID标记和访问令牌应该一起使用,因此都需要有有效的过期date。 这是错误的各种原因:

  • ID令牌仅用于向客户端进行身份validation(如上所述)。
  • 访问令牌与客户端无关。 它们用于访问资源,而客户端只有在需要调用资源时才处理它们。
  • 像独立的MVC或WebForms应用程序需要一个ID令牌。 如果没有调用外部资源,则没有任何权限访问,所以没有访问令牌。

我不得不根据自己的理由深入研究,写下来,所以我会发布我在这里学到的东西。

首先,回答这个问题的风险是明显的:如果当前时间大于过期时间,ID令牌不能被信任,并且其内容必须被忽略。 提问者的回答表明,在用户初始authentication之后,ID令牌不再被使用。 但是,由于ID令牌由身份提供商签名 ,因此在任何时候都可以有用地确定用户是否可以使用其他服务。 使用简单的用户ID或电子邮件地址是不可靠的,因为它很容易被欺骗(任何人都可以发送电子邮件地址或用户ID),但是由于OIDC ID令牌由授权服务器签名(通常还有作为第三方),它不能被欺骗,是一个更可靠的authentication机制。

例如,移动应用程序可能希望能够告诉后端服务是用户正在使用该应用程序,并且可能需要在初始authentication之后的短暂时间之后这样做,此时ID标记已经过期,因此不能用于可靠地authentication用户。

因此,就像访问令牌(用于授权 – 指定用户拥有什么权限 )可以刷新一样,是否可以刷新ID令牌 (用于validation – 指定用户是 )? 根据OIDC规范,答案并不明显。 在OIDC / OAuth中,有三个获取令牌的“stream程”,授权码stream程,隐式stream程和混合stream程(我将在下面略过,因为它是另外两个的变体)。

对于OIDC / OAuth中的隐式stream,您可以通过将浏览器中的用户redirect到授权端点并将id_token作为response_type请求参数的值,请求授权端点上的ID令牌。 隐式stream成功authentication响应需要包含id_token

对于“validation码”stream程 ,当将用户redirect到授权端点时,客户端将code指定为response_type请求参数的值。 成功的响应包括授权码。 客户端客户端使用授权码向令牌端点发出请求,根据OIDC核心章节3.1.3.3成功令牌响应 ,响应必须包含一个ID令牌

所以对于任何一个stream程,这就是你最初得到ID令牌的方式,但是你怎么刷新它呢? OIDC第12部分:使用刷新令牌有关刷新令牌响应的以下声明:

在成功validation刷新令牌之后,响应主体是3.1.3.3节的令牌响应,除了它可能不包含id_token

可能不包含一个ID令牌,因为没有办法强制它包含ID令牌,所以你必须假定这个回应将不包含ID令牌。 所以在技术上没有特定的方法来使用刷新令牌“刷新”ID令牌。 因此, 获得新的ID令牌的唯一方法是重新授权/authentication用户,方法是将用户redirect到授权端点,并启动隐式stream或authentication码stream程,如上所述。 OIDC规范确实为授权请求添加了prompt请求参数,因此客户端可以请求授权服务器不提示用户使用任何UI,但redirect仍然必须发生。

它的意图是一样的:在id_token之后,你不能使用id_token 。 主要区别在于id_token是一种数据结构,您不需要调用任何服务器或端点,因为信息是在令牌本身进行编码的。 一个普通的access_token通常是一个不透明的工件(像一个GUID)。

id_token必须始终validation它的(时间)有效性。

我对IS不是100%熟悉,但我想这是一个方便的领域。 你应该总是检查exp声明。

到期只是其中一个validation。 id_token也是数字签名的,这也是您必须执行的validation。

我想发表这个答案作为评论,但由于我还没有在StackOverflow非常活跃,我想我把它作为一个备用答案。

尝试将用户login到会话http://openid.net/specs/openid-connect-session-1_0.html时,还使用;id_token作为id_token_hint 。 我真的不认为,如果id_token在这个时候已经过期,那么它真的id_token ,因为你只关心注销一个特定的用户。

刷新令牌意味着您可以再次使用它来从授权服务器(在本例中是OP – OpenID-Connect提供程序)请求某些内容,即使用户没有login。 通常只允许用户使用有限的资源,并且只能在用户login后至less进行一次validation。 刷新令牌本身也应该在时间上受到限制。

在OIDC 隐式stream程中,您可以调用授权端点,
并在响应中接收ID令牌以及所有的范围和所有的声明信息。
对API的后续调用是用代码stream完成的。
隐式stream程旨在启用一个仅限于JavaScript或浏览器的应用程序。 不是与服务器交互的应用程序。
所以,即使有“刷新”这个标记的方法,你也不应该 – 安全明智 – 让它活太久。 它将被盗用并被未经授权的用户冒用身份证复用。 你应该强制一个新的login。

代码stream中,您调用OP的授权端点,并接收授权代码 (也称为授权令牌或简称为授权代码 )。 这应该过期类似于你隐式stream收到的id_token,出于同样的原因,不能也不应该被更新。

然后,您的UI或应用程序将调用OP的Token端点,并接收(有时在用户通过UI的进一步同意后,允许在OP服务器上使用其拥有的资源):

  • 一个id_token,用于身份validation – 在服务器调用中不应该再次使用该身份validation,除非在注销期间提示,到期时不重要,所以出于上述原因,应该让其过期,并且永远不要刷新。
  • 一个access_token – 稍后调用一个API时,可以给OP的UserInfo端点。 这将返回索赔,API可以相应授权。

您可以刷新此access_token,因为它只告诉API用户拥有什么声明,以及用户同意给您的资源(通过范围和每个范围的声明)。 如上所述,即使在用户没有login之后也允许访问。 当然,你不希望允许id_token被刷新,因为你不想在没有login的情况下允许模仿。

如果我理解正确,根据这一点和OpenID Connect Core 1.0规范 ,ID标记本身可以存储在cookie中,作为持久性会话的一种机制,并随每个需要身份validation的请求一起发送给客户端。 然后,客户端可以在本地validationID令牌,或者通过提供者的validation者端点validation(如果提供, 就像Google一样 )。 如果令牌已过期,则应该另外创build一个validation请求,除了这次在URL参数中使用prompt=none 。 还要确保在id_token_hint参数中发送过期的ID令牌,否则提供者可能会返回错误。

所以,ID令牌看起来很自然,但是prompt=none确保新的ID令牌可以在没有用户干预的情况下顺利地获得(除非用户当前登出了该OpenID)。

TLDR;

在信任它之前validationID令牌。

更多细节

OpenID Connect中ID令牌到期时间的意图是什么?

目的是允许客户端validationID令牌,并且客户端必须在使用ID令牌信息的操作之前validationID令牌

从OpenID隐式stream程规范 :

如果本文档中定义的任何validation程序失败,则任何要求未能正确validation的信息的操作必须中止,并且不能使用未validation的信息。

为了证实这一点, Google的OpenID Connect文档对此进行了关于ID令牌validation的说明:

让令牌有用的一件事是,您可以将它们传递给应用程序的不同组件。 这些组件可以使用ID令牌作为对应用程序和用户进行身份validation的轻量级身份validation机制。 但是,在您可以使用ID令牌中的信息或依赖它作为用户已authentication的断言之前,您必须validation它。

因此,如果我们的客户端应用程序将根据ID令牌的内容采取一些行动,那么我们必须再次validationID令牌。