本文重点介绍了将使用Azure Active Directory身份验证库(ADAL)的应用程序迁移到Microsoft 身份验证库(MSAL)时需要做出的更改。
用于 Java 的 Microsoft 身份验证库(MSAL4J)和用于 Java 的 Azure AD 身份验证库(ADAL4J)用于对Microsoft Entra实体进行身份验证,并从Microsoft Entra ID请求令牌。 到目前为止,大多数开发人员都使用 Azure AD,以便开发人员(v1.0)使用各种标识(例如工作和学校帐户)进行身份验证,方法是使用 Azure AD 身份验证库(ADAL)请求令牌。
MSAL 具有以下优势:
- 由于它使用的是较新的 Microsoft 标识平台,因此你可以对更广泛的一组 Microsoft 标识进行身份验证,例如通过 Azure AD Business to Consumer (Azure AD B2C) 进行身份验证的 Microsoft Entra 标识、Microsoft 帐户、社交帐户和本地帐户,以及通过 Microsoft Entra 外部 ID 进行身份验证的社交或本地客户帐户。
- 你的用户将获得最佳的单一登录体验。
- 应用程序可以启用增量许可,并支持新功能,例如条件访问。
MSAL for Java 是我们建议与 Microsoft 标识平台配合使用的身份验证库。 ADAL4J 上不会实现任何新功能。 今后所做的一切努力都集中在改进 MSAL 上。
可以了解有关 MSAL 的详细信息,并开始使用Microsoft 身份验证库。
范围不是资源
ADAL4J 为资源获取令牌,而 MSAL for Java 为作用域获取令牌。 许多用于Java类的 MSAL 都需要范围参数。 此参数是一个字符串列表,用于声明所请求的权限和资源。 请参阅Microsoft Graph的范围以查看示例范围。
可以将范围后缀添加到 /.default 资源,以帮助将应用从 ADAL 迁移到 MSAL。 例如,对于资源值 https://graph.microsoft.com,等效的范围值为 https://graph.microsoft.com/.default。 如果资源不是 URL 形式,而是采用 XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX 这种形式的资源 ID,则仍然可以将 scope 值设为 XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/.default。
有关不同类型的作用域的详细信息,请参阅Microsoft 标识平台中的权限和许可以及接受 v1.0 令牌的 Web API 的作用域这两篇文章。
核心类
在 ADAL4J 中,AuthenticationContext 类表示你通过 Authority 与安全令牌服务(STS)或授权服务器建立的连接。 但是,适用于Java的 MSAL 围绕客户端应用程序进行设计。 它提供两个单独的类: PublicClientApplication 并 ConfidentialClientApplication 表示客户端应用程序。 后者 ConfidentialClientApplication表示一个应用程序,旨在安全地维护机密,例如守护程序应用的应用程序标识符。
下表显示了 ADAL4J 函数如何映射到Java函数的新 MSAL:
| ADAL4J 方法 | MSAL4J 方法 |
|---|---|
| acquireToken(String resource, ClientCredential credential, AuthenticationCallback callback) | ClientCredentialParameters |
| acquireToken(String resource, ClientAssertion assertion, AuthenticationCallback callback) | ClientCredentialParameters |
| acquireToken(String resource, AsymmetricKeyCredential credential, AuthenticationCallback callback) | ClientCredentialParameters |
| acquireToken(String resource, String clientId, String username, String password, AuthenticationCallback callback) | UserNamePasswordParameters |
| acquireToken(String resource, String clientId, String username, String password=null, AuthenticationCallback callback) | IntegratedWindowsAuthenticationParameters |
| acquireToken(String resource, UserAssertion userAssertion, ClientCredential credential, AuthenticationCallback callback) | OnBehalfOfParameters |
| acquireTokenByAuthorizationCode() | AuthorizationCodeParameters |
| acquireDeviceCode() and acquireTokenByDeviceCode() | DeviceCodeFlowParameters |
| acquireTokenByRefreshToken() | SilentParameters |
用 IAccount 代替 IUser
ADAL4J 管理用户。 尽管用户表示单个人类或软件代理,但它可以在Microsoft标识系统中拥有一个或多个帐户。 例如,用户可能有多个Microsoft Entra ID、Azure AD B2C 或Microsoft个人帐户。
MSAL for Java 通过 IAccount 接口定义了账户这一概念。 这是相较于 ADAL4J 的破坏性变更。 这体现了这样一个事实:同一用户可以拥有多个帐户,这些帐户甚至可能位于不同的 Microsoft Entra 目录中。 MSAL for Java 在来宾场景中能够提供更完善的信息,因为它提供了主帐户信息。
缓存持久性
ADAL4J 不支持令牌缓存。 MSAL for Java添加了令牌缓存,以便尽可能自动刷新过期的令牌,并防止用户提供凭据的不必要的提示,从而简化令牌生存期的管理。
通用机构
在 v1.0 中,如果您使用 https://login.microsoftonline.com/common 授权机构,用户可以使用来自任何组织的 Microsoft Entra 帐户登录。
如果你在 v2.0 中使用 https://login.microsoftonline.com/common 颁发机构,用户可以登录任何 Microsoft Entra 组织,甚至 Microsoft 个人帐户 (MSA)。 在 MSAL for Java 中,如果你想将登录限制在任何 Microsoft Entra 帐户,请使用 https://login.microsoftonline.com/organizations 颁发机构(这与 ADAL4J 的行为相同)。 若要指定颁发机构,请在实例化authority类时在PublicClientApplication.Builder方法中设置PublicClientApplication参数。
v1.0 和 v2.0 令牌
v1.0 端点(由 ADAL 使用)仅颁发 v1.0 令牌。
v2.0 终结点(由 MSAL 使用)可以颁发 v1.0 和 v2.0 令牌。 Web API 的应用程序清单的属性使开发人员能够选择接受哪个版本的令牌。 请参阅accessTokenAcceptedVersion应用程序清单参考文档中的信息。
有关 v1.0 和 v2.0 令牌的详细信息,请参阅Microsoft Entra访问令牌。
ADAL 到 MSAL 的迁移
在 ADAL4J 中,刷新令牌已公开,这允许开发人员缓存这些令牌。 然后,他们将使用 AcquireTokenByRefreshToken() 来支持此类解决方案,例如实现长期运行的服务,以便在用户不再处于连接状态时代表用户刷新仪表板。
MSAL for Java不会出于安全原因公开刷新令牌。 而是由 MSAL 代你处理令牌刷新。
MSAL for Java 有一个 API,允许你将使用 ADAL4J 获取的刷新令牌迁移到 ClientApplication:RefreshTokenParameters。 使用此方法可以结合所需的任何范围(资源)提供以前用过的刷新令牌。 刷新令牌将用于换取新的令牌,并将该新令牌缓存起来供您的应用程序使用。
以下代码片段显示了机密客户端应用程序中的简单迁移代码片段:
String rt = GetCachedRefreshTokenForSignedInUser(); // Get refresh token from where you have them stored
Set<String> scopes = Collections.singleton("SCOPE_FOR_REFRESH_TOKEN");
RefreshTokenParameters parameters = RefreshTokenParameters.builder(scopes, rt).build();
PublicClientApplication app = PublicClientApplication.builder(CLIENT_ID) // ClientId for your application
.authority(AUTHORITY) //plug in your authority
.build();
IAuthenticationResult result = app.acquireToken(parameters);
IAuthenticationResult 会返回访问令牌和 ID 令牌,而新的刷新令牌会存储在缓存中。 应用程序现在还将包含一个 IAccount:
Set<IAccount> accounts = app.getAccounts().join();
若要使用缓存中的令牌,请调用:
SilentParameters parameters = SilentParameters.builder(scope, accounts.iterator().next()).build();
IAuthenticationResult result = app.acquireToken(parameters);