【问题标题】:JWT (Json Web Token) Audience "aud" versus Client_Id - What's the difference?JWT(Json Web 令牌)受众“aud”与 Client_Id - 有什么区别?
【发布时间】:2015-04-09 16:47:24
【问题描述】:

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

我怀疑aud 应该指的是资源服务器,而client_id 应该指的是身份验证服务器识别的客户端应用程序之一(即 Web 应用程序或 iOS 应用程序)。

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

【问题讨论】:

  • 可能会有帮助!!实际上,我试图弄清楚audience 原来是client_id 也是我的audience。 (这取决于keycloak Admin中的配置。)

标签: oauth oauth-2.0 jwt


【解决方案1】:

虽然这很旧,但我认为即使在今天也是有效的

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

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

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

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

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

第二个场景很有趣。 RFC8707 "Resource Indicators for OAuth 2.0" 解释了您可以使用 resource 参数在授权请求中定义目标受众的位置。因此,生成的令牌将仅限于指定的受众。此外,Azure OIDC 使用类似的方法,它允许资源注册并允许身份验证请求包含资源参数以定义访问令牌目标受众。此类机制允许 OAuth 采用在客户端和令牌消费(受众)方之间进行分离。

【讨论】:

    【解决方案2】:

    JWT aud(观众)声明

    根据RFC 7519

    “aud”(受众)声明标识 JWT 的接收者 用于。打算处理 JWT 的每个主体都必须 用受众声明中的价值来识别自己。如果校长 处理索赔并不表明自己具有价值 当此声明存在时,“aud”声明,则 JWT 必须是 被拒绝。在一般情况下,“aud”值是一个 case- 敏感字符串,每个都包含一个 StringOrURI 值。在里面 当 JWT 有一个受众的特殊情况下,“aud”值可能是 包含 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 验证将通过专门查找aud 中的refresh 声明来告诉我们令牌是否实际上是有效的刷新令牌。

    OAuth 客户端 ID 与 JWT aud 声明

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

    接受这些标记的应用程序负责解析和验证这些标记的含义。我认为在 JWT aud 声明中指定 OAuth 客户端 ID 没有多大价值。

    【讨论】:

    • 我对整个“必须表明自己”有点模糊。 RFC7519 充满了类似的无法解释的部分,以及对其他身份验证系统的模糊暗示,这可能是对标准声明字段的正确解释。坦率地说,尽管 RFC 可能很有用,但绝不应该在这样的状态下离开草稿阶段。
    • @ChuckAdams 我编辑以澄清我的想法。我同意 RFC 非常含糊,尤其是围绕“标准声明”以及如何/何时使用它们。
    • 我们目前就如何使用 aud 字段进行了相同的讨论,我同意它旨在包含接收者(验证和接受令牌的人)而不是 client_id(那个,谁要求令牌代表用户行事)。
    • 以下内容显然是错误的,并且违反了 RFC 7519:“当然,收件人可能会选择忽略 aud,因此这仅在收件人希望确认令牌是为其创建的情况下才有用具体来说。”来自 RFC 7519 的句子:“如果处理该声明的主体在此声明存在时未使用 aud 声明中的值标识自己,则必须拒绝 JWT。”暗示如果受众声明存在,您必须使用它来检查您是否认同它的价值观之一。
    • 它是可选的,因为发行者可以选择不包含它,但是接收者在它存在时丢弃它不是可选的。
    【解决方案3】:

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

    我知道这是为 oauth 2.0 和 NOT OIDC 标记的,但是这两个标准之间经常存在混淆,因为这两个标准可以使用 JWT 和 @987654323 @ 宣称。一个(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)

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

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

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

    【讨论】:

    • 请注意一件事:Oauth2 不强制使用 JWT。
    【解决方案4】:

    事实证明,我的怀疑是正确的。 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 不适合它。

    【讨论】:

    • 看来aud也可能是client_id。见tools.ietf.org/id/draft-hunt-oauth-v2-user-a4c-01.txtaud REQUIRED for session_token. Contains the client_id of the client receiving the assertion.
    • 资源服务器不知道客户端将 JWT 发送到哪里。资源服务器将如何拒绝从您的 iOS 应用到其他 URL 的此类流量?我不认为你是正确的。
    • 我会说“如果“aud”包含“www.webapp.com”,但客户端应用程序尝试在“secret.webapp.com”上使用 JWT”
    • RFC 说观众 (aud) 识别收件人。收件人会收到您的 JWT 令牌。如果您有一个网络应用程序,那么这可能是contoso.com,但如果您有一些桌面或移动应用程序(可以进行身份​​验证),则受众没有任何 URI。发行者是生成 JWT 令牌的人,因此很可能是服务器的地址。 RFC 说此声明的使用是可选的,因此仅在需要时使用它。
    • 其实我很困惑受众和发行者之间的区别。
    猜你喜欢
    • 2023-04-08
    • 2020-06-29
    • 2019-03-25
    • 2020-06-20
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 2016-08-01
    • 2023-03-14
    相关资源
    最近更新 更多