Azure 为什么AAD发布的访问令牌包含有关用户的信息?

Azure 为什么AAD发布的访问令牌包含有关用户的信息?,azure,.net-core,oauth-2.0,azure-active-directory,openid-connect,Azure,.net Core,Oauth 2.0,Azure Active Directory,Openid Connect,我读了很多关于OAuth 2.0和OpenId Connect的书,理论上我现在理解了这两个概念。 但是如果我去实践,有些事情仍然让我困惑,我希望你能以某种方式启发我… 首先,在如何在AAD环境中保护.net核心API的所有代码示例中,我在“配置”部分找到了如下行: app.UseAuthentication() 以及ConfigureServices部分中的以下行: services.AddAuthentication(JwtBearerDefaults.Authentica

我读了很多关于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令牌,而是访问令牌—什么是授权,而不是代码示例中的“身份验证”
这是可行的,但我不能百分之百地理解它。
因此,我的第一个问题是:

  • 访问令牌是否也以某种方式进行“身份验证” 第二件事:
    我读到访问令牌没有标准格式。他们可以是JWT或不是,可以有观众或不是等等。因此,你甚至可以像微软一样将用户信息放入令牌中。访问令牌包含诸如“姓氏”或“给定名称”等声明。
    相反,Id令牌具有标准化的格式,以确保每个人都以相同的方式进行身份验证

    如果人们使用访问令牌访问我的API,我可以读取他们的姓名或电子邮件地址,例如“user.identity.name”。此值可用于存储编辑或插入内容的信息。
    所以我用访问令牌获取关于用户的信息
    所以我的第二个问题是:

  • 我在这里做的对吗?或者应该用另一种方式来实现
  • 以及:

  • access令牌是否应该包含有关用户的信息
  • 访问令牌是否也以某种方式进行“身份验证”

    对。 API在收到访问令牌时正在验证它。 这是身份验证部分,当您的API验证令牌签名是否有效、是否来自您信任的Azure AD租户、是否用于您的API以及是否已过期时

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

    我在这里做的对吗?或者应该用另一种方式来实现

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

    access令牌是否应该包含有关用户的信息

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

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

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

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

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

    如果您选择此处: 在较新的访问令牌中,默认情况下,它遵循没有任何用户个人信息的标准。标准建议,访问令牌不应包含关于用户的太多或任何信息。而只是授权信息(用户可以访问的内容)。 不过,您可以随时为个人信息添加可选声明(azure允许您这样做),但最佳实践建议您不应该这样做

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

    在这一点上,服务器端不应该有任何关于用户的个人信息,只是他们有访问权限以及作用域/角色。如果它需要关于用户的信息,那么它应该获取该授权(访问令牌),并从该令牌可以访问的任何端点请求该授权(图)

    这里有一本关于它的好书:


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

    好的,谢谢你的详细回答。。这是否意味着微软不遵循开放id和oauth标准?我到处都在读访问令牌不应该用于身份验证。。。那么,为什么任何应用程序都需要id令牌呢?我不能在Microsoft环境中只使用访问令牌吗?从技术上讲,客户端应用程序不使用访问令牌进行身份验证。从客户端应用程序的角度来看,ID令牌是authen使用的