Обновление токена Microsoft Graph access

#asp.net-core #microsoft-graph-api #microsoft-graph-sdks

#asp.net-ядро #microsoft-graph-api #microsoft-graph-sdks

Вопрос:

Я пишу приложение, которое использует «поток предоставления учетных данных клиента OAuth 2.0», чтобы получить токен доступа для вызова API Microsoft Graph. Приложение проходит проверку подлинности как само по себе, а не от имени пользователя, вошедшего в систему.

Я основал свой код на этом примере от Microsoft.

Вот как я инициализирую GraphServiceClient:

     // Read application settings from appsettings.json (tenant ID, app ID, client secret, etc.)
    AppSettings config = AppSettingsFile.ReadFromJsonFile();

    // Initialize the client credential auth provider
    var scopes = new[] { "https://graph.microsoft.com/.default" };
    var clientSecretCredential = new ClientSecretCredential(config.TenantId, config.AppId, config.ClientSecret);
    var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
 

И вот как я позже использую его (например):

 var users = await graphClient.Users.Request().GetAsync();
 

Мое приложение представляет собой API. Это не приложение, которое запускается один раз и готово. Он будет непрерывно выполняться в течение длительного времени. Поэтому я обеспокоен тем, что произойдет, когда истечет срок действия токена доступа. Как мне убедиться, что при необходимости использования graphClient срок действия токена доступа не истечет?

Комментарии:

1. В вашем вопросе не показано, как вы используете класс или токен. Используете ли вы токен доступа независимо от класса? В противном случае GraphServiceClient получит новые токены доступа по мере необходимости. Метод класса AcquireTokenSilentAsync обновит токен, если это необходимо.

2. Спасибо. Я не использую токен доступа независимо от класса. Просто используя класс. Я обновил свой пост, чтобы показать, как я использую GraphServiceClient. Не могли бы вы указать мне на какую-либо документацию, которая объясняет этот процесс автоматического обновления токена AcquireTokenSilentAsync?

Ответ №1:

Согласно приведенному выше фрагменту кода, я думаю, что вы используете graph SDK и используете поток учетных данных клиента в качестве аутентификации.

Таким образом, нам не нужно генерировать токен доступа здесь, а просто использовать graphClient для вызова graph api и сбора необходимой информации. И из-за этого режима ситуация не будет отображаться token expired , поскольку каждый раз, когда вы вызываете api, вы будете new clientSecretCredential перед ним.

И давайте вернемся к refresh , azure ad предоставляет токен обновления для обновления токена доступа, когда срок его действия истек, поскольку токен обновления истекает намного дольше, чем токен доступа, когда мы пытаемся получить токен обновления, нам нужно добавить offline_access в область при создании доступа. Но использование потока учетных данных клиента означает, что ваше приложение запрашивает новый токен с его собственными учетными данными, поэтому нет необходимости использовать токен обновления, чтобы избежать повторного входа пользователя в систему. Использование потока учетных данных не должно возвращать токен обновления.

введите описание изображения здесь

Тогда у вас могут возникнуть некоторые идеи, на которых вы настаиваете на использовании refresh the expired token process, тогда единственное, что вы можете сделать, это сначала сгенерировать токен доступа и сохранить токен с истекшим временем в каком-либо месте и использовать токен доступа в качестве заголовка http-запроса и вызова graph api. Тогда коду должно понравиться это, но я не думаю, что вы готовы использовать такой код, вы также можете обратиться к этому документу для получения более подробной информации:

 var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenant_name.onmicrosoft.com";
var clientId = "your_azuread_clientid";
var clientSecret = "corresponding_client_secret";
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret);
var tokenRequestContext = new TokenRequestContext(scopes);
var token = clientSecretCredential.GetTokenAsync(tokenRequestContext).Result.Token;

//using http sender with the token
httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token );
// Call the web API.
HttpResponseMessage response = await _httpClient.GetAsync(apiUri);
...
}
 

Комментарии:

1. Вы говорите: «поскольку каждый раз, когда вы вызываете api, перед ним появляется новый ClientSecretCredential()». Однако в настоящее время я делаю это не так. Я не создаю новый ClientSecretCredential() каждый раз, когда вызываю graph API. Вместо этого фрагмент кода в моем вопросе взят из конструктора одноэлементной службы в моем ASP.NET веб-api. Итак, я создаю экземпляр ClientSecretCredential() и GraphServiceClient() один раз, а затем каждый раз, когда я получаю запрос, требующий от меня вызова graph api, я использую this.graphClient . Это нормально? Или я должен создавать новый ClientSecretCredential() каждый раз, когда я вызываю graph api?

2. @gonzaleznicolas Спасибо за ваш ответ, и я думаю, вы должны create a new ClientSecretCredential() each time I call graph api , как вы сказали. Если вы хотите продолжать использовать токен доступа до истечения срока его действия, вам необходимо написать код для получения и сохранения токена доступа, а также написать код для проверки истечения срока действия токена доступа, написав код для повторного создания токена доступа, когда истечет срок действия предыдущего.

3. Спасибо. Итак, вы предполагаете, что каждый раз, когда мне нужно вызвать MS graph API, я создаю a new ClientSecretCredential() и a new GraphServiceClient(clientSecretCredential, scopes); ? Допустимо ли создавать новый GraphServiceClient для каждого запроса?

4. Конечно, по крайней мере, я думаю, что это приемлемо, и я не нашел ни одного официального документа, в котором говорилось бы, что это не рекомендуется.