MSAL 中的身份验证流支持

Microsoft 身份验证库 (MSAL) 可支持供不同应用程序类型和方案使用的多种授权和关联令牌流。

身份验证流 允许 支持的应用程序类型
授权代码 代表用户进行用户登录并访问 Web API。 桌面型
Mobile
单页应用 (SPA)(需要 PKCE)
Web
客户端凭据 使用应用程序本身的标识访问 Web API。 通常用于服务器到服务器的通信,以及无需用户交互的自动化脚本。 守护程序
设备代码 在智能电视和 IoT 设备等输入受限的设备上代表用户进行用户登录并访问 Web API。 也由命令行接口 (CLI) 应用程序使用。 桌面型、移动型
隐式授权 代表用户进行用户登录并访问 Web API。 不要使用此流 - 请改用采用 PKCE 的授权代码。 * 单页应用 (SPA)
* Web
代理 (OBO) 代表用户从“上游”Web API 访问“下游”Web API。 用户的标识和委托的权限将从上游 API 传递到下游 API。 Web API
用户名/密码 (ROPC) 允许应用程序通过直接处理用户密码来登录用户。 不要使用此流。 桌面型、移动型
集成 Windows 身份验证 (IWA) 允许已加入域或已加入 Microsoft Entra 的计算机上的应用程序静默获取令牌(无需用户进行任何 UI 交互)。 桌面型、移动型

令牌

应用程序可以使用一个或多个身份验证流。 每个流均使用特定的令牌类型进行身份验证、授权和令牌刷新,某些流还使用授权代码。

身份验证流或操作 需要 ID 令牌 访问令牌 刷新令牌 授权代码
授权代码流 身份验证流适用于 ID 令牌 身份验证流适用于访问令牌 身份验证流适用于刷新令牌 授权代码有效
客户端凭据 身份验证流适用于访问令牌(仅限应用)
设备代码流 身份验证流适用于 ID 令牌 身份验证流适用于访问令牌 身份验证流适用于刷新令牌
隐式流 身份验证流适用于 ID 令牌 身份验证流适用于访问令牌
代理流 访问令牌 身份验证流适用于 ID 令牌 身份验证流适用于访问令牌 身份验证流适用于刷新令牌
用户名/密码 (ROPC) 用户名、密码 身份验证流适用于 ID 令牌 身份验证流适用于访问令牌 身份验证流适用于刷新令牌
混合 OIDC 流 身份验证流适用于 ID 令牌 授权代码有效
刷新令牌兑换 刷新令牌 身份验证流适用于 ID 令牌 身份验证流适用于访问令牌 身份验证流适用于刷新令牌

交互式和非交互式身份验证

上面的其中一些流既支持交互式令牌获取,又支持非交互式令牌获取。

  • 交互式 - 用户可以由授权服务器提示进行输入。 例如,“若要登录,请执行多重身份验证(MFA)”或“请对更多的资源访问权限授予同意”。
  • 非交互式(静默)- 用户不可以被提示进行输入。 也称为“无提示”令牌获取,应用程序将尝试使用一种方法获取令牌,在这种方法中,授权服务器不可以提示用户进行输入。

基于 MSAL 的应用程序应该会先尝试以无提示方式获取令牌,然后仅在非交互式的尝试失败时才回退到交互式方法。 若要详细了解此模式,请参阅使用 Microsoft 身份验证库 (MSAL) 获取和缓存令牌

授权代码

OAuth 2.0 授权代码授予可由 Web 应用、单页应用 (SPA) 和本机(移动和桌面)应用用来获取对受保护资源(如 Web API)的访问权限。

当用户登录到 Web 应用程序时,该应用程序将收到一个授权代码,此代码可兑换为用于调用 Web API 的访问令牌。

在下图中,应用程序会:

  1. 请求授权代码,该代码被兑换为访问令牌
  2. 使用访问令牌调用一个 Web API,即 Microsoft Graph

授权代码流示意图。

授权代码的约束

  • 使用授权代码授予流时,单页应用程序需要 Proof Key for Code Exchange (PKCE)。 MSAL 支持 PKCE。

  • OAuth 2.0 规范要求一个授权代码只能用来兑换一次访问令牌。

    如果尝试使用相同的授权代码多次获取访问令牌,则 Microsoft 标识平台将返回与以下内容类似的错误。 某些库和框架会自动为你请求授权代码,在这种情况下,手动请求代码也会导致此错误。

    AADSTS70002: Error validating credentials. AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.
    

客户端凭据

使用 OAuth 2.0 客户端凭据流时,可通过使用应用程序的标识来访问 Web 托管资源。 这种授予通常用于必须在后台运行的服务器间交互,不需要立即与用户交互。 此类应用程序通常称为守护程序或服务帐户。

客户端凭据授权流允许 Web 服务(机密客户端)在调用其他 Web 服务时使用它自己的凭据(而不是模拟用户)进行身份验证。 在这种情况下,客户端通常是中间层 Web 服务、后台程序服务或网站。 为了进行更高级别的保证,Microsoft 标识平台还允许调用服务将证书(而不是共享机密)用作凭据。

应用程序密钥

在下图中,应用程序会:

  1. 使用应用程序机密或密码凭据获取令牌
  2. 使用令牌发出资源请求

包含密码的机密客户端示意图。

证书

在下图中,应用程序会:

  1. 通过使用证书凭据获取令牌
  2. 使用令牌发出资源请求

包含证书的机密客户端示意图。

这些客户端凭据需要:

  • 已向 Microsoft Entra ID 注册
  • 在代码中构造机密客户端应用程序对象时传入

客户端凭据的约束

Android、iOS 或 UWP 等移动平台不支持机密客户端流。 移动应用程序被视为无法保证其凭据机密性的公共客户端应用程序。

设备代码

使用 OAuth 2.0 设备代码流时,用户可以登录到输入受限的设备,如智能电视、IoT 设备和打印机。 使用 Microsoft Entra ID 进行的交互式身份验证需要 Web 浏览器。 如果设备或操作系统不提供 Web 浏览器,设备代码流允许用户使用另一台设备(例如计算机或手机)以交互方式登录。

应用程序使用设备代码流通过为这些设备和操作系统设计的双步过程获取令牌。 此类应用程序的示例包括 IoT 设备上运行的应用程序和命令行接口 (CLI) 工具。

在下图中:

  1. 每当需要用户身份验证时,应用都将提供一个代码,并要求用户使用另一台设备(如已连接到 Internet 的智能手机)访问某个 URL(例如 https://microsoft.com/devicelogin)。 然后,系统会提示用户输入该代码,并转到完成正常身份验证的体验,包括许可提示和多重身份验证(如果需要)。
  2. 成功完成身份验证后,命令行应用会通过传回通道收到所需的令牌,并使用这些令牌执行所需的 Web API 调用。

设备代码流示意图。

设备代码的约束

  • 设备代码流仅可用于公共客户端应用程序。
  • 在 MSAL 中初始化公共客户端应用程序时,请使用以下颁发机构格式之一:
    • 租户:https://login.partner.microsoftonline.cn/{tenant}/,,其中 {tenant} 是租户 ID 或与租户关联的域名。
    • 工作和学校帐户:https://login.partner.microsoftonline.cn/organizations/

隐式授权

隐式授权流已替换为采用 PKCE 的授权代码流,后者是客户端单页应用程序 (SPA) 首选的且更安全的令牌授予流。

警告

不再建议使用隐式授权流。 如果要构建 SPA,请改用带 PCKE 的授权代码流。

使用 JavaScript(包括 Angular、Vue.js 或 React.js 等框架)编写的单页 Web 应用是从服务器下载的,其代码直接在浏览器中运行。 由于其客户端代码在浏览器中运行,而不是在 Web 服务器上运行,因此它们的安全特征与传统服务器端 Web 应用程序不同。 在 Proof Key for Code Exchange (PKCE) 可用于授权代码流之前,SPA 使用隐式授权流来提高获取访问令牌时的响应能力和效率。

使用 OAuth 2.0 隐式授权流时,应用无需执行后端服务器凭据交换即可从 Microsoft 标识平台获取访问令牌。 隐式授权流允许应用从由用户代理(通常是 Web 浏览器)下载并运行的 JavaScript 代码内将用户登录、维护会话,以及为其他 Web API 获取令牌。

隐式授权流示意图

隐式授权的约束

隐式授权流不包括使用跨平台 JavaScript 框架(如 Electron 或 React Native)的应用程序方案。 这样的跨平台框架需要其他功能,以与运行这些框架的本机桌面和移动平台交互。

通过隐式流模式颁发的令牌具有长度限制,因为它们是通过 URL 返回给浏览器的(其中 response_modequeryfragment)。 某些浏览器会限制浏览器栏中 URL 长度,如果 URL 过长则会失败。 因此,这些隐式流令牌不包含 groupswids 声明。

代理 (OBO)

当应用程序调用服务或 Web API(该服务或 Web API 继而又需要调用另一个服务或 Web API)时,会使用 OAuth 2.0 代理身份验证流。 思路是通过请求链传播委托用户标识和权限。 要使中间层服务向下游服务发出身份验证请求,该服务需要代表用户保护 Microsoft 标识平台提供的访问令牌。

在下图中:

  1. 应用程序获取 Web API 的访问令牌。
  2. 客户端(Web、桌面、移动或单页应用程序)调用受保护的 Web API,在 HTTP 请求的身份验证标头中添加访问令牌作为持有者令牌。 Web API 对用户进行身份验证。
  3. 当客户端调用 Web API 时,Web API 代表用户请求另一个令牌。
  4. 受保护的 Web API 使用此令牌代表用户调用下游 Web API。 以后,Web API 也可以请求其他下游 API 的令牌(仍代表同一用户)。

代理流的示意图。

用户名/密码 (ROPC)

使用 OAuth 2.0 资源所有者密码凭据 (ROPC) 授权时,应用程序可以通过直接处理用户的密码来让用户登录。 在桌面应用程序中,可以使用用户名/密码流以静默方式获取令牌。 使用应用程序时无需 UI。

警告

不建议使用资源所有者密码凭据 (ROPC) 流。 ROPC 需要较高级别的信任,并且会透露凭据信息。 只有在无法使用更安全的流时,才采用 ROPC。 有关详细信息,请参阅如何解决不断增多的密码问题?

在下图中,应用程序会:

  1. 通过向标识提供者发送用户名和密码来获取令牌
  2. 使用令牌来调用 web API

用户名/密码流示意图。

若要在已加入 Windows 域的计算机上以无提示方式获取令牌,建议使用集成 Windows 身份验证 (IWA) 而不是 ROPC。 对于其他方案,请使用设备代码流

ROPC 的约束

以下约束适用于使用 ROPC 流的应用程序:

  • 单一登录不受支持。
  • 多重身份验证 (MFA) 不受支持。
    • 使用此流之前,请咨询租户管理员 - MFA 是一项常用的功能。
  • 条件访问不受支持。
  • ROPC 仅适用于工作和学校帐户。
  • .NET 桌面和 ASP.NET Core 应用程序支持 ROPC。
  • 通用 Windows 平台 (UWP) 应用程序不支持 ROPC。
  • AZURE AD B2C 中的 ROPC 仅受本地帐户支持。

集成 Windows 身份验证 (IWA)

对于已加入域和已加入 Microsoft Entra 的 Windows 计算机上运行的桌面或移动应用程序,MSAL 支持集成 Windows 身份验证 (IWA)。 这些应用程序可以使用 IWA 以无提示方式获取令牌,无需用户进行任何 UI 交互。

在下图中,应用程序会:

  1. 通过使用集成 Windows 身份验证获取令牌
  2. 使用令牌发出资源请求

集成 Windows 身份验证的示意图。

IWA 的约束

兼容性

集成 Windows 身份验证 (IWA) 是为 .NET 桌面应用、.NET 和 Windows 通用平台应用启用的。

IWA 仅支持 AD FS 联合用户(在 Active Directory 中创建并由 Microsoft Entra ID 支持的用户)。 直接在 Microsoft Entra ID 中创建但不是由 Active Directory 支持的用户(托管用户)不能使用此身份验证流。

多重身份验证 (MFA)

如果在 Microsoft Entra 租户中启用了 MFA,并且 Microsoft Entra ID 发出 MFA 质询,则 IWA 的非交互式(静默)身份验证可能会失败。 如果 IWA 失败,你应回退到前面所述的交互式身份验证方法

Microsoft Entra ID 使用 AI 来确定何时需要双重身份验证。 当用户从另外的国家/地区登录时或在不使用 VPN 的情况下连接到公司网络时通常需要双重身份验证,有时在通过 VPN 进行了连接的情况下也需要双重身份验证。 由于 MFA 的配置和质询频率可能会超出开发人员的控制范围,因此应用程序应正常处理 IWA 的无提示令牌获取失败。

颁发机构 URI 限制

构造公共客户端应用程序时传入的颁发机构必须为以下其中一项:

  • https://login.partner.microsoftonline.cn/{tenant}/ - 此机构指示单租户应用程序,其登录受众限于指定 Microsoft Entra 租户中的用户。 {tenant} 值可以是 GUID 格式的租户 ID 或与租户关联的域名。
  • https://login.partner.microsoftonline.cn/organizations/ - 此机构指示多租户应用程序,其登录受众为任何 Microsoft Entra 租户中的用户。

同意要求

由于 IWA 是静默流:

  • 应用程序的用户必须已事先许可使用该应用程序。

    或者

  • 租户管理员必须已事先许可租户中的所有用户使用该应用程序。

若要满足任一要求,必须已完成以下操作之一:

  • 你作为应用程序开发人员已在 Azure 门户中为自己选择了“授权”。
  • 租户管理员已在 Azure 门户中的应用注册的“API 权限”选项卡中选择了“代表 {租户域} 授予/撤销管理员同意”;请参阅添加用于访问 Web API 的权限
  • 你为用户提供了同意使用应用程序的方式,请参阅用户同意
  • 你提供了某种方式让租户管理员同意应用程序(请参阅管理员同意)。

有关同意的详细信息,请参阅权限和同意

下一步

了解如何获取和缓存这些流中使用的令牌: