JWT(Json Web Token)观众" aud"与Client_Id - 有什么区别?

时间:2015-02-09 20:07:27

标签: oauth oauth-2.0 jwt

我正在我的身份验证服务器中实现OAuth 2.0 JWT access_token。但是,我不清楚JWT aud声明与client_id HTTP标头值之间的差异。它们是一样的吗?如果没有,你能解释两者之间的区别吗?

我怀疑aud应该引用资源服务器,client_id应该引用认证服务器识别的客户端应用程序之一(即web应用程序或iOS应用程序) )。

在我目前的情况下,我的资源服务器也是我的网络应用客户端。

4 个答案:

答案 0 :(得分:91)

事实证明,我的怀疑是正确的。 JWT中的受众aud声明旨在引用应接受令牌的资源服务器。

正如this帖子简单地说的那样:

  

令牌的受众是令牌的预期收件人。

     

受众值是一个字符串 - 通常是该字符串的基址   正在访问的资源,例如https://contoso.com

OAuth中的client_id是指将从资源服务器请求资源的客户端应用程序。

客户端应用(例如您的iOS应用)将从您的身份验证服务器请求JWT。在这样做时,它会传递client_idclient_secret以及可能需要的任何用户凭据。授权服务器使用client_idclient_secret验证客户端并返回JWT。

JWT将包含aud声明,指定JWT对哪些资源服务器有效。如果aud包含www.myfunwebapp.com,但客户端应用尝试在www.supersecretwebapp.com上使用JWT,则访问将被拒绝,因为资源服务器将看到JWT不适合它。

答案 1 :(得分:46)

JWT aud(受众)声明

根据RFC 7519

  

“aud”(观众)声明标识了JWT所在的收件人      打算用于。每个校长都打算处理JWT      用受众群体声明中的值来表明自己。如果校长      处理索赔并不表示自己的值      “声明”声称,如果存在此声明,那么JWT必须是      被拒绝。在一般情况下,“aud”值是一个案例数组 -      敏感字符串,每个字符串包含StringOrURI值。在里面      特殊情况当JWT有一个观众时,“aud”值可能是a      包含StringOrURI值的单个区分大小写的字符串。的的      对受众价值的解释通常是针对特定应用的。      使用此声明是可选的。

规范定义的受众(aud)声明是通用的,并且是特定于应用程序的。预期用途是识别令牌的预期接收者。收件人的意思是特定于应用程序。受众值可以是字符串列表,也可以是单个字符串(如果只有一个aud声明。令牌的创建者不强制aud被正确验证,责任是接收者确定是否应该使用令牌。

无论价值是什么,当收件人验证JWT并且它希望验证该令牌是否用于其目的时,它必须确定aud中的哪个值标识自己,并且令牌应该仅验证收件人的声明ID是否出现在aud声明中。如果这是URL或其他特定于应用程序的字符串,则无关紧要。例如,如果我的系统决定使用字符串audapi3.app.com中标识自己,则只有aud声明在其受众值列表中包含api3.app.com时,它才应接受JWT

当然,收件人可以选择忽略aud,因此这仅在收件人希望肯定验证是否专门为其创建令牌时才有用。

我基于规范的解释是aud声明对于创建仅针对特定目的有效的专用JWT非常有用。对于一个系统,这可能意味着您希望令牌对某些功能有效,但对其他功能无效。您可以发出仅限于某些“受众”的令牌,同时仍然使用相同的密钥和验证算法。

由于在典型情况下,JWT由受信任的服务生成,并由其他受信任的系统(不想使用无效令牌的系统)使用,因此这些系统只需要协调它们将使用的值。

当然,aud是完全可选的,如果您的用例不能保证,则可以忽略它。如果您不想限制令牌被特定受众群体使用,或者您的系统实际上都不会验证aud令牌,那么它就没用了。

示例:访问与刷新令牌

我能想到的一个设计(但简单)的例子可能是我们想要使用JWT进行访问和刷新令牌而不必实现单独的加密密钥和算法,而只是想确保访问令牌不会验证为刷新令牌,反之亦然。

通过使用aud,我们可以为刷新令牌指定refresh的声明,并在创建这些令牌时为访问令牌声明access声明。当请求从刷新令牌获取新的访问令牌时,我们需要验证刷新令牌是否为真正的刷新令牌。如上所述的aud验证将通过专门查找refreshaud的声明来告诉我们该令牌是否实际上是有效的刷新令牌。

OAuth客户端ID与JWT aud声明

OAuth客户端ID完全不相关,与JWT aud声明没有直接关联。从OAuth的角度来看,令牌是不透明的对象。

接受这些令牌的应用程序负责解析和验证这些令牌的含义。我认为在JWT aud声明中指定OAuth客户端ID并不重要。

答案 2 :(得分:4)

如果您来这里搜索OpenID Connect(OIDC): OAuth 2.0!= OIDC

我认识到这是为oauth 2.0和 OIDC标记的,但是两个标准之间经常存在混淆,因为这两个标准可以使用JWT和{{ 1}}索赔。一个(OIDC)本质上是另一个(OAUTH 2.0)的扩展。 (我偶然发现了这个问题,亲自寻找OIDC。)

OAuth 2.0访问令牌##

对于OAuth 2.0 访问令牌,现有的答案相当不错。另外,这是OAuth 2.0 Framework (RFC 6749)

中的一个相关部分

对于使用隐式流的公共客户端,此规范不 提供任何方法让客户端确定要访问哪个客户端 令牌已颁发给。
...
向客户端验证资源所有者不在此范围内 规范。任何使用授权过程的规范 作为委托给客户端的最终用户身份验证的一种形式(例如, 第三方登录服务)不得在没有以下情况的情况下使用隐式流程 额外的安全机制,使客户端能够 确定是否发布了访问令牌供其使用(例如,受众群体- 限制访问令牌。

OIDC ID令牌##

OIDC除访问令牌外还具有 ID令牌。 OIDC规范对于在ID令牌中使用aud声明是明确的。 (openid-connect-core-1.0

aud
需要。此ID令牌的目标受众。 它必须包含依赖方的OAuth 2.0 client_id作为受众群体值。它还可以包含其他受众群体的标识符。通常,aud值是区分大小写的字符串数组。在只有一个听众的特殊情况下,aud值可以是单个区分大小写的字符串。

此外,当aud具有多个值时,OIDC指定与azp结合使用的aud声明。

azp
可选的。授权方-颁发ID令牌的一方。如果存在,则必须包含该参与方的OAuth 2.0客户端ID。仅当ID令牌具有单个受众值并且该受众不同于授权方时,才需要此声明。即使授权方与唯一的听众相同,也可以包括在内。 azp值是区分大小写的字符串,其中包含StringOrURI值。

答案 3 :(得分:1)

虽然这个年代很久,但我认为这个问题在今天仍然有效

我怀疑aud应该引用资源服务器,并且 client_id应该引用客户端应用程序之一 认证服务器认可

是的, aud 应该指代币消费方。并且 client_id 指代币获取方。

在当前情况下,我的资源服务器也是我的Web应用程序客户端。

在OP的情况下,Web应用程序和资源服务器都属于同一方。因此,这意味着客户和受众相同。但是在某些情况下并非如此。

考虑使用消耗OAuth保护的资源的SPA。在这种情况下,SPA是客户端。受保护的资源是访问令牌的受众。

第二种情况很有趣。有一个名为“ Resource Indicators for OAuth 2.0”的工作草案,它解释了您可以在授权请求中定义目标受众的位置。因此,生成的令牌将仅限于指定的受众。此外,Azure OIDC使用类似的方法,它允许资源注册并允许auth请求包含资源参数,以定义访问令牌预期的访问者。通过这种机制,OAuth专用区可以将客户端与令牌消费(受众)方分隔开来。