从 ADAL 迁移到 MSAL 后如何获取 ServiceClientCredentials
How to get ServiceClientCredentials after migrating from ADAL to MSAL
对 ADAL 的支持将于 2022 年 6 月 30 日结束,Microsoft recommends migrating applications to MSAL。
在迁移期间,我在将访问 Data Lake Storage 的代码从 ADAL 迁移到 MSAL 时遇到了困难。我几乎可行的尝试是:
// Before migration (authenticate using obsolete ADAL)
ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
ServiceClientCredentials credentials = await ApplicationTokenProvider.LoginSilentAsync(tenantId, clientCredential);
var adlsClient = AdlsClient.CreateClient(dataLakeStoreName, serviceCredentials)
// After migration (authenticate using newer MSAL)
var clientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithClientSecret(clientSecrret)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
.Build();
AuthenticationResult credentials = await (new[] { $"https://datalake.azure.net/.default" })
.ExecuteAsync();
// We no longer have ServiceClientCredentials object, so the only overload left is the one that accepts a bearer token as a string:
var adlsClient = AdlsClient
.CreateClient(dataLakeStoreName, $"{credentials.TokenType} {credentials.AccessToken}");
上面的 MSAL 代码工作了一段时间,但随着 ServiceClientCredentials
消失,我们丢失了负责刷新令牌的对象。因此,当令牌过期时,adlsClient
现在停止工作。
是否有任何简单的方法可以使用 MSAL 创建 ServiceClientCredentials
?
或者我们是否需要在迁移到 MSAL 时自己编写刷新令牌的逻辑?
最近遇到了同样的问题。您可以实现自己的 ServiceClientCredentials
,它可以利用 IConfidentialClientApplication
来管理访问令牌。例如:
public class DataLakeGen1ClientCredentials : ServiceClientCredentials
{
private readonly IConfidentialClientApplication _application;
public DataLakeGen1ClientCredentials(string? appId, string? secretKey, string? directoryId)
{
_application = ConfidentialClientApplicationBuilder
.Create(appId)
.WithClientSecret(secretKey)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{directoryId}"))
.Build();
}
public override async Task ProcessHttpRequestAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
HttpRequestHeaders httpRequestHeaders = request.Headers;
var authResult = await _application.AcquireTokenForClient(new[] { $"https://datalake.azure.net/.default" })
.ExecuteAsync(cancellationToken).ConfigureAwait(false);
httpRequestHeaders.Authorization = new AuthenticationHeaderValue(authResult.TokenType, authResult.AccessToken);
await base.ProcessHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
}
}
您需要覆盖 AdlsClient
使用的 ProcessHttpRequestAsync
,以便在发送请求之前将令牌插入 HTTP headers。 AcquireTokenForClient
将为您提供一个有效的令牌。
使用 ServiceClientCredentials
的这个实现,您可以初始化 adlsClient
并像以前一样使用它:
var serviceCredentials = new DataLakeGen1ClientCredentials(clientId, clientSecret, tenantId);
AdlsClient client = AdlsClient.CreateClient(DataLakeStoreName, serviceCredentials);
对 ADAL 的支持将于 2022 年 6 月 30 日结束,Microsoft recommends migrating applications to MSAL。
在迁移期间,我在将访问 Data Lake Storage 的代码从 ADAL 迁移到 MSAL 时遇到了困难。我几乎可行的尝试是:
// Before migration (authenticate using obsolete ADAL)
ClientCredential clientCredential = new ClientCredential(clientId, clientSecret);
ServiceClientCredentials credentials = await ApplicationTokenProvider.LoginSilentAsync(tenantId, clientCredential);
var adlsClient = AdlsClient.CreateClient(dataLakeStoreName, serviceCredentials)
// After migration (authenticate using newer MSAL)
var clientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithClientSecret(clientSecrret)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{tenantId}"))
.Build();
AuthenticationResult credentials = await (new[] { $"https://datalake.azure.net/.default" })
.ExecuteAsync();
// We no longer have ServiceClientCredentials object, so the only overload left is the one that accepts a bearer token as a string:
var adlsClient = AdlsClient
.CreateClient(dataLakeStoreName, $"{credentials.TokenType} {credentials.AccessToken}");
上面的 MSAL 代码工作了一段时间,但随着 ServiceClientCredentials
消失,我们丢失了负责刷新令牌的对象。因此,当令牌过期时,adlsClient
现在停止工作。
是否有任何简单的方法可以使用 MSAL 创建 ServiceClientCredentials
?
或者我们是否需要在迁移到 MSAL 时自己编写刷新令牌的逻辑?
最近遇到了同样的问题。您可以实现自己的 ServiceClientCredentials
,它可以利用 IConfidentialClientApplication
来管理访问令牌。例如:
public class DataLakeGen1ClientCredentials : ServiceClientCredentials
{
private readonly IConfidentialClientApplication _application;
public DataLakeGen1ClientCredentials(string? appId, string? secretKey, string? directoryId)
{
_application = ConfidentialClientApplicationBuilder
.Create(appId)
.WithClientSecret(secretKey)
.WithAuthority(new Uri($"https://login.microsoftonline.com/{directoryId}"))
.Build();
}
public override async Task ProcessHttpRequestAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
HttpRequestHeaders httpRequestHeaders = request.Headers;
var authResult = await _application.AcquireTokenForClient(new[] { $"https://datalake.azure.net/.default" })
.ExecuteAsync(cancellationToken).ConfigureAwait(false);
httpRequestHeaders.Authorization = new AuthenticationHeaderValue(authResult.TokenType, authResult.AccessToken);
await base.ProcessHttpRequestAsync(request, cancellationToken).ConfigureAwait(false);
}
}
您需要覆盖 AdlsClient
使用的 ProcessHttpRequestAsync
,以便在发送请求之前将令牌插入 HTTP headers。 AcquireTokenForClient
将为您提供一个有效的令牌。
使用 ServiceClientCredentials
的这个实现,您可以初始化 adlsClient
并像以前一样使用它:
var serviceCredentials = new DataLakeGen1ClientCredentials(clientId, clientSecret, tenantId);
AdlsClient client = AdlsClient.CreateClient(DataLakeStoreName, serviceCredentials);