是否可以构建一个使用 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);
    }
}