Следует ли использовать TokenCache для автономного доступа с помощью MSAL? - PullRequest
0 голосов
/ 06 декабря 2018

Я внедряю аутентификацию с использованием MSAL, и мне нужно некоторое руководство для обработки токенов обновления.

Мое Angular Web App проходит проверку подлинности с помощью моего ASP.NET Web API с использованием MSAL.Для доступа к Microsoft Graph веб-API требуются определенные области, поэтому он использует поток OAuth 2.0 «От имени» для получения токена доступа для вызова MS Graph.Эта часть сделана и работает.

Проблема в том, что MS Graph будет вызываться через некоторое время моим приложением .NET-демоном (с использованием потока OBO), когда истечет токен доступа.

Что яМне нужно получить токен обновления с помощью моего веб-API и кэшировать его (например, в базе данных SQL), чтобы он мог быть прочитан приложением-демоном и использован для получения действительного токена доступа.

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

Вот код моего приложения-демона, который я хочу использоватьчтобы получить токен доступа из AAD:

var userAssertion = new UserAssertion(
    <accessToken>,
    "urn:ietf:params:oauth:grant-type:jwt-bearer");
var authority = authEndpoint.TrimEnd('/') + "/" + <tenant> + "/";
var clientCredencial = new ClientCredential(<clientSecret>);
var authClient = new ConfidentialClientApplication(<clientId>, authority, <redirectUri>, 
    clientCredencial, <userTokenCache>, null);

try
{
    var authResult =
        await authClient.AcquireTokenOnBehalfOfAsync(<scopes>, userAssertion, authority);
    activeAccessToken = authResult.AccessToken;
}
catch (MsalException ex)
{
    throw;
}

Должен ли я предоставить <userTokenCache> для получения кэша формы обновления маркера?Если да, UserAssertion требует предоставления <accessToken>, но я не знаю, какое значение следует использовать.

Или я должен сделать запрос токена самостоятельно иполучить токен обновления из ответа, поскольку он не поддерживается MSAL?Затем я мог бы сохранить токен обновления в базе данных и использовать его как <accessToken> с null как <userTokenCache> в приложении демона.

Я думал, что можно получить токен обновления с помощью MSAL, но янайдено это не .

Обновление

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

Почему бы не поток учетных данных клиента?

Связь с MS Graph может быть выполнена в Web API (с использованием потока OBO), но задача может быть отложена пользователем, напримеротправлять почту через 8 часов (веб-API будет хранить задачи в базе данных).Решением для этого случая является приложение (демон), которое запускается по расписанию, получает задачи из базы данных и выполняет вызовы MS Graph.Я предпочитаю не давать согласия администратора ни на одно из моих приложений, потому что очень важно получить согласие от пользователя .Если согласие отозвано, вызов MS Graph не должен выполняться.Вот почему приложение-демон должно использовать токен обновления, чтобы получить токен доступа из AAD для доступа к MS Graph (используя поток OBO).

Надеюсь, теперь все ясно.Возможно, я не должен делать это таким образом.Любое предложение будет оценено.

1 Ответ

0 голосов
/ 07 декабря 2018

MSAL сам обрабатывает токен обновления, вам просто нужно обработать сериализацию кэша.- userTokenCache используется вызовом OBO, и вы используете токен обновления, сначала вызывая AcquireTokenSilentAsycn (вот что обновляет токены) - applicationTokenCache используется потоком учетных данных клиента (AcquireTokenForApplication).

Я бы посоветовал вам взглянуть на следующий пример, иллюстрирующий OBO: https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2,, в частности TodoListService / Extensions / TokenAcquisition.cs # L275-L294

код:

var accounts = await application.GetAccountsAsync();
try
{
 AuthenticationResult result = null;
 var allAccounts = await application.GetAccountsAsync();
 IAccount account = await application.GetAccountAsync(accountIdentifier);
 result = await application.AcquireTokenSilentAsync(scopes.Except(scopesRequestedByMsalNet), account);
 return result.AccessToken;
}
catch (MsalUiRequiredException ex)
{
 ...

Теперь сам кеш инициализируется из токена-носителя, который отправляется вашим клиентом в ваш веб-API.См.

TodoListService / Extensions / TokenAcquisition.cs # L305-L336

private void AddAccountToCacheFromJwt(IEnumerable<string> scopes, JwtSecurityToken jwtToken, AuthenticationProperties properties, ClaimsPrincipal principal, HttpContext httpContext)
{
 try
 {
  UserAssertion userAssertion;
  IEnumerable<string> requestedScopes;
  if (jwtToken != null)
  {
   userAssertion = new UserAssertion(jwtToken.RawData, "urn:ietf:params:oauth:grant-type:jwt-bearer");
   requestedScopes = scopes ?? jwtToken.Audiences.Select(a => $"{a}/.default");
  }
  else
  {
   throw new ArgumentOutOfRangeException("tokenValidationContext.SecurityToken should be a JWT Token");
   }

   var application = CreateApplication(httpContext, principal, properties, null);

   // Synchronous call to make sure that the cache is filled-in before the controller tries to get access tokens
   AuthenticationResult result = application.AcquireTokenOnBehalfOfAsync(scopes.Except(scopesRequestedByMsalNet), userAssertion).GetAwaiter().GetResult();
  }
  catch (MsalUiRequiredException ex)
  {
   ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...