提高你开发的客户端应用程序中身份验证和授权的复原能力Increase the resilience of authentication and authorization in client applications you develop

本部分提供了有关在使用 Microsoft 标识平台和 Azure Active Directory 将用户登录并代表这些用户执行操作的客户端应用程序中构建复原能力的指南。This section provides guidance on building resilience into client applications that use the Microsoft identity platform and Azure Active Directory to sign in users and perform actions on behalf of those users.

使用 Microsoft 身份验证库 (MSAL)Use the Microsoft Authentication Library (MSAL)

Microsoft 身份验证库 (MSAL)Microsoft 标识平台的关键部分。The Microsoft Authentication Library (MSAL) is a key part of the Microsoft identity platform. 它简化并管理令牌的获取、管理、缓存和刷新,并使用最佳做法来实现复原能力。It simplifies and manages acquiring, managing, caching, and refreshing tokens, and uses best practices for resilience. MSAL 设计用来提供安全的解决方案,使开发人员无需担心实现细节。MSAL is designed to enable a secure solution without developers having to worry about the implementation details.

MSAL 缓存令牌并使用无提示令牌获取模式。MSAL caches tokens and uses a silent token acquisition pattern. 它还会自动序列化本身提供安全存储的平台(例如 Windows UWP、iOS 和 Android)上的令牌缓存。It also automatically serializes the token cache on platforms that natively provide secure storage like Windows UWP, iOS and Android. 当使用 Microsoft.Identity.WebMSAL.NETMSAL for JavaMSAL for Python 时,开发人员可以自定义序列化行为。Developers can customize the serialization behavior when using Microsoft.Identity.Web, MSAL.NET, MSAL for Java, and MSAL for Python.

使用 MSAL 来调用 Microsoft 标识的设备和应用程序的图像

使用 MSAL 时,可通过以下模式实现令牌缓存、刷新和无提示令牌获取。When using MSAL, you get token caching, refreshing, and silent token acquisition by using the following pattern.

try
{
    result = await app.AcquireTokenSilent(scopes, account).ExecuteAsync();
}
catch(MsalUiRequiredException ex)
{
    result = await app.AcquireToken(scopes).WithClaims(ex.Claims).ExecuteAsync()
}

在某些情况下,MSAL 可以主动刷新令牌。MSAL can in some cases proactively refresh tokens. 当 Microsoft 标识颁发生存期较长的令牌时,它可以向客户端发送信息来指明刷新令牌的最佳时间(“refresh_in”)。When Microsoft Identity issues a long-lived token, it can send information to the client for the optimal time to refresh the token ("refresh_in"). MSAL 会根据此信息主动刷新令牌。MSAL will proactively refresh the token based on this information. 当旧令牌有效但会有更大的时间范围来进行另一次成功的令牌获取时,应用将继续运行。The app will continue to run while the old token is valid but will have a longer timeframe during which to make another successful token acquisition.

掌握最新动态Stay up to date

开发人员应当实施更新到最新 MSAL 版本的流程。Developers should have a process for updating to the latest MSAL release. 身份验证是应用安全的一部分,你的应用需要与新的 MSAL 版本中包含的安全增强功能保持同步。Authentication is part of your app security and your app needs to stay current with the security improvements contained in new MSAL releases. 对于正在持续开发的库来说,这通常是一个很好的做法,这样做可以确保你拥有与应用复原能力相关的最新代码。This is generally good practice for libraries under continuous development and doing so will ensure you have the most up to date code with respect to app resilience. 随着 Microsoft 标识不断创新各种方法来使应用具有更强的复原能力,使用最新 MSAL 的应用将是经过最充分的准备来基于这些创新进行构建的应用。As Microsoft Identity continues to innovate on ways for applications to be more resilient, apps that use the latest MSAL will be the most prepared to build on these innovations.

查看最新的 MSAL.js 版本和发行说明Check the latest MSAL.js version and release notes

查看最新的 MSAL .NET 版本和发行说明Check the latest MSAL .NET version and release notes

查看最新的 MSAL Python 版本和发行说明Check the latest MSAL Python version and release notes

查看最新的 MSAL Java 版本和发行说明Check the latest MSAL Java version and release notes

查看最新的 MSAL iOS 和 macOS 版本和发行说明Check the latest MSAL iOS and macOS version and release notes

查看最新的 MSAL Android 版本和发行说明Check the latest MSAL Android version and release notes

查看最新的 MSAL Angular 版本和发行说明Check the latest MSAL Angular version and release notes

查看最新的 Microsoft.Identity.Web 版本和发行说明Check the latest Microsoft.Identity.Web version and release notes

如果未使用 MSAL,请使用这些复原模式进行令牌处理If not using MSAL, use these resilient patterns for token handling

通常,使用新式身份验证的应用程序会调用一个终结点来检索对用户进行身份验证或授权应用程序调用受保护 API 的令牌。In general, an application that uses modern authentication will call an endpoint to retrieve tokens that authenticate the user or authorize the application to call protected APIs. MSAL 用于处理身份验证的细节并实现多种模式来提高此过程的复原能力。MSAL is meant to handle the details of authentication and implements several patterns to improve resilience of this process. 如果选择使用 MSAL 以外的库,请使用本部分的指南来实施最佳做法。Use the guidance in this section to implement best practices if you choose to use a library other than MSAL. 如果你使用 MSAL,则可以免费获得所有这些最佳做法,因为 MSAL 会自动实现它们。If you use MSAL, you get all of these best-practices for free, as MSAL implements them automatically.

缓存令牌Cache tokens

应用应当正确缓存从 Microsoft 标识收到的令牌。Apps should properly cache tokens received from Microsoft Identity. 当你的应用接收令牌时,包含令牌的 HTTP 响应还会包含一个“expires_in”属性,该属性告知应用程序缓存和重复使用令牌的时间长度。When your app receives tokens, the HTTP response that contains the tokens also contains an "expires_in" property that tells the application how long to cache, and reuse, the token. 应用程序必须使用“expires_in”属性来确定令牌的有效期。In it important that applications use the "expires_in" property to determine the lifespan of the token. 应用程序绝对不得尝试对 API 访问令牌进行解码。Application must never attempt to decode an API access token.

应用程序调用 Microsoft 标识,但该调用会通过运行此应用程序的设备上的令牌缓存来进行

使用缓存的令牌可防止你的应用与 Microsoft 标识之间发生不必要的流量,并通过减少令牌获取调用次数使应用不易受到令牌获取失败的影响。Using the cached token prevents unnecessary traffic between your app and Microsoft Identity, and makes your app less susceptible to token acquisition failures by reducing the number of token acquisition calls. 缓存的令牌还可以提高你的应用程序的性能,因为应用因获取令牌而需要进行阻塞的频率会更低。Cached tokens also improve your application's performance as the app needs to block on acquiring tokens less. 你的用户可以在该令牌的生存期内保持登录到你的应用程序。Your user can stay signed-in to your application for the length of that token's lifetime.

将令牌序列化和持久化Serialize and persist tokens

应用会安全地序列化其令牌缓存,以便在应用实例之间持久保存令牌。Apps should securely serialize their token cache to persist the tokens between instances of the app. 令牌在其有效生存期内可以重复使用。Tokens can be reused as long as they are within their valid lifetime. 刷新令牌访问令牌在颁发后就可以使用越来越长的时间。Refresh tokens, and, increasingly, access tokens, are issued for many hours. 在此有效时间内还允许用户多次启动你的应用程序。This valid time can span a user starting your application many times. 当应用启动时,它会检查是否存在可以使用的有效访问令牌或刷新令牌。When your app starts, it should check to see if there is a valid access or refresh token that can be used. 这会增加应用的复原能力和性能,因为这可以避免任何不必要的 Microsoft 标识调用。This will increase the app's resilience and performance as it avoids any unnecessary calls to Microsoft Identity.

应用程序调用 Microsoft 标识,但该调用会通过运行此应用程序的设备上的令牌缓存和令牌存储来进行

持久性令牌存储应进行访问控制,并进行加密以仅供所有者用户或进程标识访问。The persistent token storage should be access controlled and encrypted to the owning user or process identity. 在诸如移动平台、Windows 平台和 Mac 平台之类的平台上,开发人员应当利用内置功能来存储凭据。On platforms like mobile, Windows and Mac, the developer should take advantage of built-in capabilities for storing credentials.

以无提示方式获取令牌Acquire tokens silently

对用户进行身份验证或检索授权以调用 API 的过程中,可能需要在 Microsoft 标识中执行多个步骤。The process of authenticating a user or retrieving authorization to call an API can require multiple steps in Microsoft Identity. 例如,当用户首次登录时,可能需要输入凭据并通过短信执行多重身份验证。For example, when the user signs in for the first time they may need to enter credentials and perform a multi-factor authentication via a text message. 每个步骤都会增加对提供该服务的资源的依赖性。Each step adds a dependency on the resource that provides that service. 用户的最佳体验以及依赖性最少的体验是尝试在请求用户交互之前以无提示方式获取令牌,以避免这些额外的步骤。The best experience for the user, and the one with the least dependencies, is to attempt to acquire a token silently to avoid these extra steps before requesting user interaction.

此图显示了 Microsoft 标识中可能需要运行以完成对用户的身份验证或授权过程的各种服务

以静默方式获取令牌首先会使用来自应用的令牌缓存的有效令牌。Acquiring a token silently starts with using a valid token from the app's token cache. 如果没有可用的有效令牌,则应用会尝试使用刷新令牌(如果有)和令牌终结点来获取令牌。If there is no valid token available, the app should attempt to acquire a token using a refresh token, if available, and the token endpoint. 如果这些选项都不可用,则应用会使用“prompt = none”参数来获取令牌。If neither of these options is available, the app should acquire a token using the "prompt=none" parameter. 这将使用授权终结点,但不会向用户显示任何 UI。This will use the authorization endpoint, but not show any UI to the user. 如果 Microsoft 标识可以在不与用户交互的情况下提供应用的令牌,则它会这样做。If the Microsoft Identity can provide a token to the app without interacting with the user, it will. 如果这些方法都不能生成令牌,则用户需要以交互方式重新进行身份验证。If none of these methods result in a token, then a user will need to re-authenticate interactively.

备注

通常情况下,应用应避免使用“登录”和“同意”之类的提示,因为它们会强制实施用户交互,即使不需要交互也是如此。In general, apps should avoid using prompts like "login" and "consent" as they will force user interaction even when no interaction is required.

正确处理服务响应Handle service responses properly

当应用程序应当处理所有错误响应时,某些响应可能会影响复原能力。While applications should handle all error responses, there are some responses that can impact resilience. 如果你的应用程序收到 HTTP 429 响应代码(请求过多),则 Microsoft 标识会限制你的请求。If your application receives an HTTP 429 response code, Too Many Requests, Microsoft Identity is throttling your requests. 如果你的应用继续发出太多请求,则会继续限制你的应用,阻止它接收令牌。If your app continues to make too many requests, it will continue to be throttled preventing your app from receiving tokens. 你的应用程序不应再次尝试获取令牌,直至经过 Retry-After 响应字段中的时间(以秒为单位)。Your application should not attempt to acquire a token again until after the time, in seconds, in the Retry-After response field has passed. 收到 429 响应通常表示应用程序未正确缓存并重复使用令牌。Receiving a 429 response is often an indication that the application is not caching and reusing tokens correctly. 开发人员应当查看令牌在应用程序中是如何缓存并重复使用的。Developers should review how tokens are cached and reused in the application.

应用程序在收到 HTTP 5xx 响应代码时不得进入快速重试循环。When an application receives an HTTP 5xx response code the app must not enter a fast retry loop. 如果收到 HTTP 5xx 响应代码,应用程序应遵循与 429 响应相同的 Retry-After 处理。When present, the application should honor the same Retry-After handling as it does for a 429 response. 如果响应未提供 Retry-After 标头,我们建议实施指数退避重试,第一次重试至少应比响应晚 5 秒。If no Retry-After header is provided by the response, we recommend implementing an exponential back-off retry with the first retry at least 5 seconds after the response.

当请求超时时,应用程序不应立即重试。When a request times out applications should not retry immediately. 实施指数退避重试,第一次重试至少应比响应晚 5 秒。Implement an exponential back-off retry with the first retry at least 5 seconds after the response.

许多应用程序和 API 都需要关于用户的特定信息来做出授权决策。Many applications and APIs need specific information about the user to make authorization decisions. 应用程序可以使用几种方法来获取此信息。There are a few ways for an application to get this information. 每一种方法都有其优缺点。Each method has its advantages and disadvantages. 开发人员应权衡这些方法,以确定哪种方法最适合其应用中的复原能力。Developers should weigh these to determine which strategy is best for resilience in their app.

令牌Tokens

标识 (ID) 令牌和访问令牌包含标准声明,这些声明提供关于主题的信息。Identity (ID) tokens and access tokens contain standard claims that provide information about the subject. Microsoft 标识平台 ID 令牌Microsoft 标识平台访问令牌中介绍了这些令牌。These are documented in Microsoft identity platform ID tokens and Microsoft identity platform access tokens. 如果你的应用需要的信息已在令牌中,则检索该数据的最有效方法是使用令牌声明,因为这样不需要单独检索该信息,从而节省额外网络调用的开销。If the information your app needs is already in the token, then the most efficient technique for retrieving that data is to use token claims as that will save the overheard of an additional network call to retrieve information separately. 网络调用越少意味着应用程序的总体复原能力越高。Fewer network calls mean higher overall resilience for the application.

备注

某些应用程序调用 UserInfo 终结点来检索关于已进行身份验证的用户的声明。Some applications call the UserInfo endpoint to retrieve claims about the user that authenticated. 应用可以接收的 ID 令牌中提供的信息是它可以从 UserInfo 终结点获取的信息的超集。The information available in the ID token that your app can receive is a superset of the information it can get from the UserInfo endpoint. 你的应用应使用 ID 令牌来获取关于用户的信息,而不是调用 UserInfo 终结点。Your app should use the ID token to get information about the user instead of calling the UserInfo endpoint.

应用开发人员可以使用可选声明来补充标准令牌声明。An app developer can augment standard token claims with optional claims. 一个常见的可选声明是 groupsOne common optional claim is groups. 可以通过若干种方式来添加组声明。There are several ways to add group claims. “ApplicationGroup”选项仅包括分配给应用程序的组。The "Application Group" option only includes groups assigned to the application. “All”或“SecurityGroup”选项包括同一租户的所有应用中的组,这些选项可用来向令牌中添加许多组。The "All" or "Security groups" options include groups from all apps in the same tenant, which can add many groups to the token. 请务必在你的案例中评估影响,因为它可能导致令牌膨胀甚至需要额外的调用来获取组的完整列表,从而可能抵消通过在令牌中请求组而提高的效率。It is important to evaluate the effect in your case, as it can potentially negate the efficiency gained by requesting groups in the token by causing token bloat and even requiring additional calls to get the full list of groups.

你可以不在令牌中使用组,而是改为使用并包括应用角色。Instead of using groups in your token you can instead use and include app roles. 开发人员可以为其应用和 API 定义应用角色,客户可以使用门户或 API 从其目录管理这些角色。Developers can define app roles for their apps and APIs which the customer can manage from their directory using the portal or APIs. 然后,IT 专业人员可以将角色分配给不同的用户和组,以便控制特定用户对特定内容和功能的访问。IT Pros can then assign roles to different users and groups to control who has access to what content and functionality. 当为应用程序或 API 颁发令牌时,分配给用户的角色将出现在令牌的角色声明中。When a token is issued for the application or API, the roles assigned to the user will be available in the roles claim in the token. 直接在令牌中获取此信息可避免额外的 API 调用。Getting this information directly in a token can save additional APIs calls.

最后,IT 管理员还可以基于租户中的特定信息添加声明。Finally, IT Admins can also add claims based on specific information in a tenant. 例如,可以让企业的一个扩展使用特定于企业的用户 ID。For example, an enterprise can have an extension to have an enterprise specific User ID.

在所有情况下,将目录中的信息直接添加到令牌都可以提高效率,并且可以通过减少应用具有的依赖项的数目来提高应用复原能力。In all cases, adding information from the directory directly to a token can be efficient and increase the apps resilience by reducing the number of dependencies the app has. 另一方面,它不能解决因无法获取令牌而导致的任何复原能力问题。On the other hand, it does not address any resilience issues from being unable to acquire a token. 你只应为应用程序的主要场景添加可选声明。You should only add optional claims for the main scenarios of your application. 如果应用只需要管理员功能的信息,则最好只让应用程序根据需要获取该信息。If the app requires information only for the admin functionality, then it is best for the application to obtain that information only as needed.

Microsoft GraphMicrosoft Graph

Microsoft Graph 提供了一个统一的 API 终结点,用于访问描述组织中的工作效率模式、标识模式和安全性模式的 Microsoft 365 数据。Microsoft Graph provides a unified API endpoint to access the Microsoft 365 data that describes the patterns of productivity, identity and security in an organization. 使用 Microsoft Graph 的应用程序可能会使用 Microsoft 365 中的任何信息来做出授权决策。Applications that use Microsoft Graph can potentially use any of the information across Microsoft 365 for authorization decisions.

应用只需要一个令牌即可访问所有 Microsoft 365。Apps require just a single token to access all of Microsoft 365. 这比使用特定于 Microsoft 365 组件(例如 Microsoft Exchange 或 Microsoft SharePoint)的旧 API(需要多个令牌)时的复原能力更强。This is more resilient than using the older APIs that are specific to Microsoft 365 components like Microsoft Exchange or Microsoft SharePoint where multiple tokens are required.

使用 Microsoft Graph API 时,建议使用 Microsoft Graph SDKWhen using Microsoft Graph APIs, we suggest your use a Microsoft Graph SDK. Microsoft Graph SDK 设计用来简化可访问 Microsoft Graph 的优质、高效且可复原的应用程序的构建。The Microsoft Graph SDKs are designed to simplify building high-quality, efficient, and resilient applications that access Microsoft Graph.

对于授权决策,开发人员应考虑何时使用令牌中提供的声明作为某些 Microsoft Graph 调用的替代方法。For authorization decisions, developers should consider when to use the claims available in a token as an alternative to some Microsoft Graph calls. 如上所述,开发人员可以在其令牌中请求组、应用角色和可选声明。As mentioned above, developers could request groups, app roles, and optional claims in their tokens. 就复原能力而言,使用 Microsoft Graph 进行授权需要额外的网络调用,这些调用依赖于 Microsoft 标识(用于获取访问 Microsoft Graph 所需的令牌)以及 Microsoft Graph 本身。In terms of resilience, using Microsoft Graph for authorization requires additional network calls that rely on Microsoft Identity (to get the token to access Microsoft Graph) as well as Microsoft Graph itself. 但是,如果你的应用程序已依赖 Microsoft Graph 作为其数据层,则依赖 Graph 进行授权不会带来额外的风险。However, if your application already relies on Microsoft Graph as its data layer, then relying on the Graph for authorization is not an additional risk to take.

采用连续访问评估Adopt Continuous Access Evaluation

连续访问评估 (CAE) 是最新开发的一项功能,它可以使用长期生存的令牌提高应用程序的安全性和复原能力。Continuous Access Evaluation (CAE) is a recent development that can increase application security and resilience with long-lived tokens. CAE 是在 OpenID Foundation 的共享信号和事件工作组中开发的新兴行业标准。CAE is an emerging industry standard being developed in the Shared Signals and Events Working Group of the OpenID Foundation. 使用 CAE,可以根据严重事件策略评估而不是依赖令牌生存期短的特性来撤销访问令牌。With CAE, an access token can be revoked based on critical events and policy evaluation, rather than relying on a short token lifetime. 对于某些资源 API,由于风险和策略是实时评估的,因此 CAE 实际上可以将令牌生存期提高到最多 28 小时。For some resource APIs, because risk and policy are evaluated in real time, CAE can substantially increase token lifetime up to 28 hours. 当资源 API 和应用程序采用 CAE 时,Microsoft 标识将能够颁发可撤销并在长时间内有效的访问令牌。As resource APIs and applications adopt CAE, Microsoft Identity will be able to issue access tokens that are revocable and are valid for extended periods of time. MSAL 会主动刷新这些生存期长的令牌。These long-lived tokens will be proactively refreshed by MSAL.

尽管 CAE 处于早期阶段,但目前可以开发将从 CAE 受益的客户端应用程序,前提是应用程序使用的资源 (API) 采用 CAE。While CAE is in early phases, it is possible to develop client applications today that will benefit from CAE when the resources (APIs) the application uses adopt CAE. 随着越来越多的资源采用 CAE,应用程序也将能够为这些资源获取启用了 CAE 的令牌。As more resources adopt CAE, your application will be able to acquire CAE enabled tokens for those resources as well. Microsoft Graph API 和 Microsoft Graph SDK 将在 2021 年初提供 CAE 功能预览版。The Microsoft Graph API, and Microsoft Graph SDKs, will preview CAE capability early 2021. 如果你想参与包含 CAE 的 Microsoft Graph 的公共预览版,可以在此处告知我们你感兴趣:https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbRwl2bVHBxhlMhvLc-sgAWPdUOUpRMDAyWExSWjhEQ0NVV1IyNjBWSFc4Ui4uIf you would like to participate in the public preview of Microsoft Graph with CAE, you can let us know you are interested here: https://forms.office.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbRwl2bVHBxhlMhvLc-sgAWPdUOUpRMDAyWExSWjhEQ0NVV1IyNjBWSFc4Ui4u.

如果你开发资源 API,我们鼓励你参与共享信号和事件 WGIf you develop resource APIs, we encourage you to participate in the Shared Signals and Events WG. 我们正在与此工作组合作,目的是在 Microsoft 标识与资源提供程序之间实现安全事件共享。We are working with this group to enable the sharing of security events between Microsoft Identity and resource providers.

后续步骤Next steps