Новый токен извлекается всякий раз, когда добавляется новый поток при использовании поставщика проверки подлинности MSAL с Micrsoft Graph SDK и функцией Azure - PullRequest
1 голос
/ 05 августа 2020

Я разрабатываю приложение Azure Function. Функция использует Microsoft Graph SDK для использования Graph. Он использует MSAL Authentication Provider.

Я реализовал Graph Service Client как объект stati c и убедился, что для приложения существует только один экземпляр GraphServiceClient. Пока выполняется единственный экземпляр Azure Function, токен остается неизменным для различных вызовов Graph и обновляется только по истечении срока его действия. Токен и новый токен извлекаются методом AcquireTokenForClient (scopes) .

Однако всякий раз, когда добавляется новый экземпляр функции azure, например, я вызываю функцию два или более раз быстро один после другого токен обновляется для каждого вызова или всякий раз, когда добавляется новый экземпляр. Я также попытался реализовать его, как описано в этом сообщении https://github.com/BrianTJackett/BTJ.CSAdvent.AZFunc, но сохраняя состояние клиента графа c. Результат тот же.

Я хочу сохранить один и тот же токен, который будет использоваться со всеми экземплярами функции azure, и получать новый токен только тогда, когда истекает срок действия текущего. Есть ли способ, которым это может быть достигнуто?

Это для потока учетных данных клиента.

Вот мой код:

public class MSGraphAuth
{
    private static MSGraphAuth _graphAuth;
    private static GraphServiceClient _graphClient;
    private static readonly object _lock = new object();

    private MSGraphAuth() { }

    public static MSGraphAuth GraphAuth
    {
        get
        {
            if (_graphAuth == null)
            {
                lock (_lock)
                {
                    if (_graphAuth == null)
                    {
                        _graphAuth = new MSGraphAuth();
                        _graphAuth.InitializeGraphClient();
                    }
                }
            }

            return _graphAuth;
        }
    }

    public GraphServiceClient GraphClient
    {
        get
        {
            return _graphClient;
        }
    }

    void InitializeGraphClient()
    {
        string authority = "{authority}";

        IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
        .Create(AppSettings.MSGRAPHCLIENTID)
        .WithAuthority(authority)
        .WithClientSecret(AppSettings.MSGRAPHCLIENTSECRET)
        .Build();

        _graphClient = new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
        {

            var scopes = new string[] { "https://graph.microsoft.com/.default" };

            var authResult = await confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync();

            requestMessage
                .Headers
                .Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);

        }));
    }
}

1 Ответ

0 голосов
/ 06 августа 2020

По вашему требованию нам непросто реализовать одноэлементный экземпляр GraphServiceClient в функции azure. Но мы можем сделать это другим способом, см. Решение ниже:

Мы можем получить токен в первый раз и установить его в переменной среды. Когда следующий запрос функции (или запрос другого экземпляра функции) захочет использовать токен доступа, ему просто нужно получить токен из переменной среды. Мы можем реализовать это с помощью приведенного ниже кода в функции.

string tokenVal = Environment.GetEnvironmentVariable("token");
if (tokenVal != null) {
    log.LogInformation("do the operations what you want by access token");
}else {
    log.LogInformation("request for a new token and set it in environment variable, then use the token to do the what you want");
    Environment.SetEnvironmentVariable("token", "token_value");
}

По истечении срока действия токена мы можем получить дату истечения срока действия authResult.ExpiresOn, а также сначала установить ее в переменной окружения. Затем мы можем сравнить его с текущей датой в коде функции, если срок действия токена доступа истекает, запросить другой токен и установить его в переменной среды (также установить новую дату истечения срока действия в переменной среды). Вы можете реализовать часть даты сравнения и добавить ее в условие « if » в приведенном выше коде (обратите внимание на часовой пояс даты, полученной от authResult.ExpiresOn).

Кстати, токен доступа и дату истечения срока действия можно установить в среде, но они не будут отображаться в настройках приложения вашей функции-приложения. И если перезапустить приложение-функцию, они будут потеряны .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...