我正在我的身份验证服务器中实现OAuth 2.0 JWT access_token。但是,我不清楚JWT aud
声明与client_id
HTTP标头值之间的差异。它们是一样的吗?如果没有,你能解释两者之间的区别吗?
我怀疑aud
应该引用资源服务器,client_id
应该引用认证服务器识别的客户端应用程序之一(即web应用程序或iOS应用程序) )。
在我目前的情况下,我的资源服务器也是我的网络应用客户端。
答案 0 :(得分:91)
事实证明,我的怀疑是正确的。 JWT中的受众aud
声明旨在引用应接受令牌的资源服务器。
正如this帖子简单地说的那样:
令牌的受众是令牌的预期收件人。
受众值是一个字符串 - 通常是该字符串的基址 正在访问的资源,例如
https://contoso.com
。
OAuth中的client_id
是指将从资源服务器请求资源的客户端应用程序。
客户端应用(例如您的iOS应用)将从您的身份验证服务器请求JWT。在这样做时,它会传递client_id
和client_secret
以及可能需要的任何用户凭据。授权服务器使用client_id
和client_secret
验证客户端并返回JWT。
JWT将包含aud
声明,指定JWT对哪些资源服务器有效。如果aud
包含www.myfunwebapp.com
,但客户端应用尝试在www.supersecretwebapp.com
上使用JWT,则访问将被拒绝,因为资源服务器将看到JWT不适合它。
答案 1 :(得分:46)
aud
(受众)声明根据RFC 7519:
“aud”(观众)声明标识了JWT所在的收件人 打算用于。每个校长都打算处理JWT 用受众群体声明中的值来表明自己。如果校长 处理索赔并不表示自己的值 “声明”声称,如果存在此声明,那么JWT必须是 被拒绝。在一般情况下,“aud”值是一个案例数组 - 敏感字符串,每个字符串包含StringOrURI值。在里面 特殊情况当JWT有一个观众时,“aud”值可能是a 包含StringOrURI值的单个区分大小写的字符串。的的 对受众价值的解释通常是针对特定应用的。 使用此声明是可选的。
规范定义的受众(aud
)声明是通用的,并且是特定于应用程序的。预期用途是识别令牌的预期接收者。收件人的意思是特定于应用程序。受众值可以是字符串列表,也可以是单个字符串(如果只有一个aud
声明。令牌的创建者不强制aud
被正确验证,责任是接收者确定是否应该使用令牌。
无论价值是什么,当收件人验证JWT并且它希望验证该令牌是否用于其目的时,它必须确定aud
中的哪个值标识自己,并且令牌应该仅验证收件人的声明ID是否出现在aud
声明中。如果这是URL或其他特定于应用程序的字符串,则无关紧要。例如,如果我的系统决定使用字符串aud
在api3.app.com
中标识自己,则只有aud
声明在其受众值列表中包含api3.app.com
时,它才应接受JWT
当然,收件人可以选择忽略aud
,因此这仅在收件人希望肯定验证是否专门为其创建令牌时才有用。
我基于规范的解释是aud
声明对于创建仅针对特定目的有效的专用JWT非常有用。对于一个系统,这可能意味着您希望令牌对某些功能有效,但对其他功能无效。您可以发出仅限于某些“受众”的令牌,同时仍然使用相同的密钥和验证算法。
由于在典型情况下,JWT由受信任的服务生成,并由其他受信任的系统(不想使用无效令牌的系统)使用,因此这些系统只需要协调它们将使用的值。
当然,aud
是完全可选的,如果您的用例不能保证,则可以忽略它。如果您不想限制令牌被特定受众群体使用,或者您的系统实际上都不会验证aud
令牌,那么它就没用了。
我能想到的一个设计(但简单)的例子可能是我们想要使用JWT进行访问和刷新令牌而不必实现单独的加密密钥和算法,而只是想确保访问令牌不会验证为刷新令牌,反之亦然。
通过使用aud
,我们可以为刷新令牌指定refresh
的声明,并在创建这些令牌时为访问令牌声明access
声明。当请求从刷新令牌获取新的访问令牌时,我们需要验证刷新令牌是否为真正的刷新令牌。如上所述的aud
验证将通过专门查找refresh
中aud
的声明来告诉我们该令牌是否实际上是有效的刷新令牌。
aud
声明 OAuth客户端ID完全不相关,与JWT aud
声明没有直接关联。从OAuth的角度来看,令牌是不透明的对象。
接受这些令牌的应用程序负责解析和验证这些令牌的含义。我认为在JWT aud
声明中指定OAuth客户端ID并不重要。
答案 2 :(得分:4)
我认识到这是为oauth 2.0和不 OIDC标记的,但是两个标准之间经常存在混淆,因为这两个标准可以使用JWT和{{ 1}}索赔。一个(OIDC)本质上是另一个(OAUTH 2.0)的扩展。 (我偶然发现了这个问题,亲自寻找OIDC。)
对于OAuth 2.0 访问令牌,现有的答案相当不错。另外,这是OAuth 2.0 Framework (RFC 6749)
中的一个相关部分对于使用隐式流的公共客户端,此规范不 提供任何方法让客户端确定要访问哪个客户端 令牌已颁发给。
...
向客户端验证资源所有者不在此范围内 规范。任何使用授权过程的规范 作为委托给客户端的最终用户身份验证的一种形式(例如, 第三方登录服务)不得在没有以下情况的情况下使用隐式流程 额外的安全机制,使客户端能够 确定是否发布了访问令牌供其使用(例如,受众群体- 限制访问令牌。
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专用区可以将客户端与令牌消费(受众)方分隔开来。