【问题标题】:Why do access tokens issued by AAD contain information about the user?为什么 AAD 颁发的访问令牌包含有关用户的信息?
【发布时间】:2020-05-30 23:19:41
【问题描述】:

我阅读了很多关于 OAuth 2.0 和 OpenId Connect 的内容,理论上我现在了解这两个概念。
但是如果我去实践,有些事情仍然让我感到困惑,我希望你能以某种方式启发我......
首先,在所有代码示例中,如何在 AAD 环境中保护 .net 核心 API,我在配置部分中找到了这样的行:

app.UseAuthentication()

ConfigureServices 部分中类似这样的行:

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = "https://login.microsoftonline.com/xxxxxxxx";
            options.Audience = "xxxx-xxx-xxx-xxx-xxxx";
        });

但是,要访问我的 API,我没有使用 ID 令牌,而是使用访问令牌 Authorization,而不是“Authentication”就像在代码示例中一样。
这行得通 - 但我不能 100% 理解它。
所以我的第一个问题是:

  1. 访问令牌是否也以某种方式“验证”?

第二件事:
我读到访问令牌没有标准化格式。它们可以是或不是 JWT,可以有或没有观众等。因此,您甚至可以像微软一样将用户信息放入令牌中。访问令牌包含诸如“姓氏”或“名字”等声明。
相比之下,ID 令牌具有标准化格式,以确保每个人都以相同的方式完成身份验证。

如果人们使用访问令牌访问我的 API,例如,我可以使用“user.identity.name”读取他们的姓名或电子邮件地址。我可以使用这个值来存储编辑了某些东西或插入了某些东西的信息。
所以我正在使用访问令牌获取有关用户的信息!
所以我的第二个问题是:

  1. 我在这里做对了吗?或者应该以其他方式完成。

和:

  1. 访问令牌是否应该包含有关用户的信息?

【问题讨论】:

    标签: azure .net-core oauth-2.0 azure-active-directory openid-connect


    【解决方案1】:

    访问令牌是否也以某种方式“验证”?

    是的。 您的 API 在收到访问令牌时会对其进行验证。 这是身份验证部分,当您的 API 验证令牌签名有效时,令牌签名来自您信任的 Azure AD 租户,它适用于您的 API 并且尚未过期。

    授权是当您检查令牌包含的权限时。 您的 API 可以定义授予客户端应用程序的不同权限,允许它们具有不同级别的访问权限。 有效的令牌可以通过身份验证,但如果缺少必要的权限,则可能无法通过授权。

    我在这里做对了吗?或者应该以其他方式完成。

    从根本上说,您正在做正确的事情。 令牌告诉您正在使用客户端应用程序的用户是谁,如果您需要知道是谁做了某事,这就是您使用的信息。 但是,如果您真的想将操作连接到用户,我建议您使用他们的对象标识符/对象 id/oid 而不是他们的名称/用户名,因为这些可以更改。 除非您只想要他们的显示名称。

    访问令牌是否应该包含有关用户的信息?

    在 Azure AD 的上下文中,如果客户端应用程序代表用户访问 API,则访问令牌将始终包含有关用户的信息。 这包括授权代码、设备代码、隐式和代表身份验证流程。 他们都使用委托权限(也称为范围)代表用户调用 API。 因此,令牌包含有关调用应用程序和用户的信息。

    如果应用使用不涉及用户的客户端凭据流获取访问令牌,则令牌中将没有用户信息。 在这种情况下,将使用应用程序权限而不是 Azure AD 中的委派权限。 应用程序作为自己,而不是代表任何用户。

    如果您的 API 支持这两种情况,则令牌有时包含用户信息,有时不包含。

    从规范的角度来看,关于令牌格式的部分基本上是正确的。 OAuth 没有为访问令牌定义严格的格式,而 OpenID Connect 确实为 ID 令牌定义了一种格式。

    使用访问令牌调用您的 API 绝对是正确的。 ID 令牌仅适用于启动用户身份验证的应用程序,而不适用于它调用的任何 API。 这就是访问令牌的用途。

    【讨论】:

    • 好的,谢谢你的详细回答。这是否意味着微软不遵循开放 id 和 oauth 标准?我到处都在阅读不应该将访问令牌用于身份验证......那么为什么任何应用程序都需要 id 令牌呢?我不能在 Microsoft 环境中只拥有访问令牌吗?
    • 好吧,从技术上讲,客户端应用程序没有使用访问令牌进行身份验证。从客户端应用程序的角度来看,ID 令牌用于身份验证,访问令牌用于授权对 API 的调用。但是接收 OAuth 访问令牌的 API 当然必须验证/验证它。如果不先对令牌本身进行身份验证,您就无法授权。访问令牌的主要目的是告诉您的 API 调用应用的权限 + 用户的角色(如果适用)。
    • 当然,他们随后在令牌中包含了一些关于用户的详细信息,这在技术上对于授权调用者来说是不必要的,例如用户名。
    【解决方案2】:

    如果您在此处查看:https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens 在较新的访问令牌中,默认情况下它遵循不包含有关用户的任何个人信息的标准。这是标准所建议的,访问令牌不应包含太多或任何关于用户的信息。而只是授权信息(用户可以访问的东西)。 但是,您始终可以为个人信息添加可选声明(并且 azure 允许您这样做),但最佳实践建议您不应该这样做。

    就附加身份验证而言:身份验证基本上证明了您所说的身份。 addauthentication(),基本上调用 microsoft azure ad 来执行这个任务,说嘿 aad 请问这个人他是谁,azure 然后检查并说这是一个真实的人,但我不会告诉你任何关于他的信息id,他们可以访问您的 api/应用程序。所以从你的片段来看,没关系。

    此时,您的服务器端不应该有任何关于用户的个人信息,只是他们有权访问以及哪些范围/角色。如果它想要有关用户的信息,则应获取该授权(访问令牌)并从该令牌有权访问的任何端点请求它(图)

    这是一个很好的阅读:https://auth0.com/blog/why-should-use-accesstokens-to-secure-an-api/

    希望这有助于澄清一些问题,而不是给问题增加更多混乱。

    【讨论】:

    • 说实话,这有点令人困惑......现在这是否与 juunas 所说的相矛盾?我将阅读这两篇文章,但我使用的是现代 msal,并且没有更改标准或任何默认值。无论如何,我的令牌包含用户信息......那么现在是真的吗?
    • 这并不完全矛盾,当他说它包含有关用户的信息时,因为即使是访问令牌也需要包含最少数量的“个人”用户信息,以便向 webapi 识别用户,例如.用户名或类似的东西。访问令牌不应该包含信息、电子邮件地址、国家等信息。如果它是访问令牌,则您的令牌不应包含电子邮件。我承认微软通过在访问令牌中包含 Name 有点作弊,如果您要严格解释,它不应该包含技术上包含它。
    猜你喜欢
    • 2015-04-14
    • 2020-07-17
    • 2021-09-29
    • 2021-06-12
    • 1970-01-01
    • 2021-11-24
    • 2017-08-31
    • 2018-02-21
    • 2017-03-23
    相关资源
    最近更新 更多