是否可以构建一个使用 graph api 调用的 azure 函数,并且可以在大量负载下处理可靠的身份验证?
is it possible to build a azure function which uses graph api call and can handle reliable authentification on massive load?
据此post
azure 函数同时在多个触发器上崩溃,因此如果在代码中执行令牌(图 API),将多次请求令牌,从而引发此异常。
2022-01-31T06:51:59Z [Information] AADSTS900023: Specified tenant identifier 'a1ae89fb-21b9-40bf-9d82-a10ae85a2407a1ae89fb-21b9-40bf-9d82-a10ae85a2407' is neither a valid DNS name, nor a valid external domain.
Trace ID: ebbb51ed-2ef1-4931-81b6-702833c93f00
Correlation ID: cb112afc-08bf-44bb-9a8e-b0a93938f6cb
Timestamp: 2022-01-31 06:51:55Z
at Microsoft.Identity.Client.Internal.Requests.RequestBase.HandleTokenRefreshError(MsalServiceException e, MsalAccessTokenCacheItem cachedAccessTokenItem)
at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenForClientParameters clientParameters, CancellationToken cancellationToken)
at Namespace1.Webhook.GetOnlyDesiredDataAfterFiltersAsync(String CallRecordId, AzFuncCallRecordsConfiguration config, ILogger log) in D:\Repos\Webhook.cs:line 518
at Namespace1.Webhook.Run(HttpRequest req, ExecutionContext context, ILogger log) in D:\Repos..\BWebhook.cs:line 180
所以现在的问题是:
它是否可以通过 azure 函数实现,因为在有状态服务上可以存储身份验证令牌以避免每次都需要?
我希望这个问题不会被视为重复,但这是两个不同的问题。
如果否,请写下可能的失败原因,为什么不可能。
在 .NET Azure Functions 中,您可以使用静态变量来跨执行保存数据。
这些变量将特定于该实例,如果该实例被删除,这些变量将被擦除。
在 junas 的评论和回答之后我做了这个解决方法:
将这 2 个静态变量添加到您的 class:
static string AuthToken = null;
static DateTime TokenExpDate;
在获取令牌之前检查此变量。
IConfidentialClientApplication app;
AuthenticationResult result = null;
string[] scopes = null;
string data = null;
IRestResponse response = null;
// build Authenticate for getting a token
config.Authority += config.CallRecordTenantID;
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientSecret(config.ClientSecret)
.WithAuthority(new Uri(config.Authority))
.Build();
scopes = new string[] { "https://graph.microsoft.com/.default" };
// ask static vars if token is vaild
if (AuthToken == null || TokenExpDate < DateTime.UtcNow)
{
try
{
result = await app.AcquireTokenForClient(scopes)
.ExecuteAsync();
if (result != null)
{
AuthToken = result.AccessToken;
TokenExpDate = result.ExpiresOn.UtcDateTime;
}
}
catch (Exception ex)
{
log.LogInformation("Exc.:" + ex.Message + "\n" + ex.StackTrace);
}
}
据此post
azure 函数同时在多个触发器上崩溃,因此如果在代码中执行令牌(图 API),将多次请求令牌,从而引发此异常。
2022-01-31T06:51:59Z [Information] AADSTS900023: Specified tenant identifier 'a1ae89fb-21b9-40bf-9d82-a10ae85a2407a1ae89fb-21b9-40bf-9d82-a10ae85a2407' is neither a valid DNS name, nor a valid external domain.
Trace ID: ebbb51ed-2ef1-4931-81b6-702833c93f00
Correlation ID: cb112afc-08bf-44bb-9a8e-b0a93938f6cb
Timestamp: 2022-01-31 06:51:55Zat Microsoft.Identity.Client.Internal.Requests.RequestBase.HandleTokenRefreshError(MsalServiceException e, MsalAccessTokenCacheItem cachedAccessTokenItem)
at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenForClientParameters clientParameters, CancellationToken cancellationToken)
at Namespace1.Webhook.GetOnlyDesiredDataAfterFiltersAsync(String CallRecordId, AzFuncCallRecordsConfiguration config, ILogger log) in D:\Repos\Webhook.cs:line 518
at Namespace1.Webhook.Run(HttpRequest req, ExecutionContext context, ILogger log) in D:\Repos..\BWebhook.cs:line 180
所以现在的问题是: 它是否可以通过 azure 函数实现,因为在有状态服务上可以存储身份验证令牌以避免每次都需要?
我希望这个问题不会被视为重复,但这是两个不同的问题。
如果否,请写下可能的失败原因,为什么不可能。
在 .NET Azure Functions 中,您可以使用静态变量来跨执行保存数据。 这些变量将特定于该实例,如果该实例被删除,这些变量将被擦除。
在 junas 的评论和回答之后我做了这个解决方法:
将这 2 个静态变量添加到您的 class:
static string AuthToken = null;
static DateTime TokenExpDate;
在获取令牌之前检查此变量。
IConfidentialClientApplication app;
AuthenticationResult result = null;
string[] scopes = null;
string data = null;
IRestResponse response = null;
// build Authenticate for getting a token
config.Authority += config.CallRecordTenantID;
app = ConfidentialClientApplicationBuilder.Create(config.ClientId)
.WithClientSecret(config.ClientSecret)
.WithAuthority(new Uri(config.Authority))
.Build();
scopes = new string[] { "https://graph.microsoft.com/.default" };
// ask static vars if token is vaild
if (AuthToken == null || TokenExpDate < DateTime.UtcNow)
{
try
{
result = await app.AcquireTokenForClient(scopes)
.ExecuteAsync();
if (result != null)
{
AuthToken = result.AccessToken;
TokenExpDate = result.ExpiresOn.UtcDateTime;
}
}
catch (Exception ex)
{
log.LogInformation("Exc.:" + ex.Message + "\n" + ex.StackTrace);
}
}