Доступ к MS Graph из API от имени пользователя, вошедшего в данный момент в отдельный веб-клиент

Я разрабатываю API(ASP.NET Core), доступ к которому осуществляется через отдельно размещенный веб-клиент (React), оба из которых размещаются на Azure в качестве служб приложений. Клиентское приложение должно иметь аутентификацию на основе Azure Ad(один клиент, предпочтительно защищенный с помощью Azure Auth на основе aad). Когда пользователь входит в клиент, API должен иметь доступ к MS Graph от имени пользователя. Очевидно, что оба ресурса должны быть защищены, я пытался использовать Azure Auth на основе AAD в обеих службах приложения, но я не смог получить токен для MsGraph в этом подходе с токеном, полученным из auth для ADD на стороне API.

Вопрос в том, как избежать передачи токена в MsGraph с токеном для azure aad auth от клиента и получения токена для msGraph, основанного только на токене из aad auth, в то время как у пользователей есть только одно место для входа в систему и обеспечения безопасности обеих служб приложений?

Я использую самородок для MsGraph на стороне Api для взаимодействия с MsGraph. Я не нашел образец, который ссылается на этот конкретный случай.

2 ответа

Сценарий. Веб-API вашего приложения (защищенный Azure AD) получает токен авторизации от клиентского приложения (React) и должен вызывать нисходящий веб-API (Microsoft Graph) от имени вошедшего в систему пользователя.

Концептуальная документация по документам Microsoft: ваш сценарий точно соответствует потоку "от имени" OAuth 2.0, как описано в документе "Документы Microsoft для Azure AD", здесь вызовы между сервисами, использующие делегированный идентификатор пользователя в потоке "от имени"

Образцы кода:

Пожалуйста, взгляните на следующие образцы:

Важные части кода из API

Чтобы получить токен из своего веб-API, позвоните в Microsoft Graph API от имени пользователя, используя уже переданный токен.

Подготовка утверждения пользователя

ClientCredential clientCred = new ClientCredential(clientId, appKey);
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
string userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
string userAccessToken = bootstrapContext.Token;
UserAssertion userAssertion = new UserAssertion(userAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);

Получение токена для Microsoft Graph

 result = await authContext.AcquireTokenAsync(graphResourceId, clientCred, userAssertion);

В итоге я использовал только проверку подлинности Azure Ad + по коду (без проверки подлинности Azure). API использует поток OBO, клиентское приложение использует неявный поток.

В основном две отдельные регистрации приложений на aad: клиент, имеющий разрешение access_as_user для API, и другой для API, который имеет разрешения для MsGraph. Вы настраиваете это в приложениях регистрации (предварительный просмотр) / API разрешений. (Для подробного руководства следуйте приведенным ниже примерам, начните с API)

Для веб-клиента я также использовал области: "access_as_user", "offline_access", "openid" в запросе на токен, добавил true для "oauth2AllowImplicitFlow" в манифесте и перенаправил на yourdomainname.azurewebsites.com, остальная часть конфигурации аналогична родной клиент в примере ниже.

Полезные ресурсы:

API:

https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2 https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-on-behalf-of-flow

(Я рекомендую сначала протестировать с собственным клиентом, чтобы проверить, правильно ли он настроен, конфигурация API останется неизменной для отдельного веб-клиента)

Веб-клиент:

https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-oauth2-implicit-grant-flow

Это решение, которое мне подходит на данный момент, возможно, будет лучше адаптировать его.