Вызовы MSAL, Azure MobileService и Auto REST получают 401 несанкционированный
У меня есть приложение (в настоящее время в UWP), которое использует MobileServiceClient и AutoRest для приложения API службы приложений Azure. Я успешно использовал winfbsdk и могу через него пройти аутентификацию, а затем получить его для входа в MobileService.LoginAsync с маркером доступа FB в качестве JObject. Я также беру этот JObject и отправляю его в заголовке x-zumo-auth при вызовах приложения API через AutoRest в приложении. То, что я хотел бы сделать, это иметь возможность аутентификации с использованием MicrosoftAccount. Если я использую MobileService.LoginAsync, я не могу получить правильный токен и передать его AutoRest - он всегда возвращается как 401 Unauthorized. Я попытался использовать MSAL, но он возвращает токен на предъявителя, и его передача также возвращается как 401 Несанкционированный. Есть ли хороший способ сделать это? Я начал по маршруту MSAL, поскольку он будет поддерживать рабочий стол Windows, UWP и Xamarin Forms, которые будут идеальными. Мне просто нужна информация о том, как получить из него правильный токен, который будет передаваться в AutoRest HttpClient, который восходит к приложению API службы приложений Azure.
Обновление: если я использую следующий поток, он работает с Facebook, но не с MicrosoftAccount.
-Azure App Service с WebAPI (и swagger для тестирования через браузер)
-Установка безопасности через панель управления Azure на службе и настроена для разрешения Facebook или MicrosoftAccount
1. В моем приложении UWP, используя winfbsdk, я захожу с Facebook, затем беру FBSession.AccessTokenData.AccessToken и вставляю его в JObject:
JObject token = JObject.FromObject
(new{access_token = fbSession.AccessTokenData.AccessToken});
2. Войти в MobileServiceClient
user = await App.MobileService.LoginAsync
(MobileServiceAuthenticationProvider.Facebook, token);
Войдите в приложение API с помощью HttpClient и получите токен для использования в X-ZUMO-AUTH
using (var client = new HttpClient()) { client.BaseAddress = App.MobileService.MobileAppUri; var jsonToPost = token; var contentToPost = new StringContent( JsonConvert.SerializeObject(jsonToPost), Encoding.UTF8, "application/json"); var asyncResult = await client.PostAsync( "/.auth/login/" + provider.ToString(), contentToPost); if (asyncResult.Content == null) { throw new InvalidOperationException("Result from call was null."); return false; } else { if (asyncResult.StatusCode == System.Net.HttpStatusCode.OK) { var resultContentAsString = asyncResult.Content.AsString(); var converter = new ExpandoObjectConverter(); dynamic responseContentAsObject = JsonConvert.DeserializeObject<ExpandoObject>( resultContentAsString, converter); var applicationToken = responseContentAsObject.authenticationToken; ApiAppClient.UpdateXZUMOAUTHToken(applicationToken); } } }
Вызов ApiAppClient.UpdateXZUMOAUTH просто делает следующее:
if (this.HttpClient.DefaultRequestHeaders.Contains("x-zumo-auth") == true) { this.HttpClient.DefaultRequestHeaders.Remove("x-zumo-auth"); } this.HttpClient.DefaultRequestHeaders.Add("x-zumo-auth", applicationToken);
Любые последующие вызовы с использованием ApiAppClient (созданные с помощью AutoRest из swagger json моего Azure AppService WebAPI) содержат заголовок x-zumo-auth и проходят надлежащую проверку подлинности.
Проблема возникает при попытке использовать MicrosoftAccount. Я не могу получить правильный токен для использования в x-zumo-auth от MSAL или LoginWithMicrosoftAsync.
Для № 1 выше, когда я пытался использовать MicrosoftAccount, я использовал MSAL следующим образом:AuthenticationResult result = await MSAuthentication_AcquireToken(); JObject token = JObject.FromObject(new{access_token = result.Token});
А MSAuthentication_AcquireToken определен ниже с использованием интерфейсов и классов, как предлагается в примерах Azure: https://github.com/Azure-Samples/active-directory-xamarin-native-v2
private async Task<AuthenticationResult> MSAuthentication_AcquireToken()
{
IMSAcquireToken at = new MSAcquireToken();
try
{
AuthenticationResult res;
res = await at.AcquireTokenAsync(App.MsalPublicClient, App.Scopes);
return res;
}
}
Обновление - нормально с MobileServiceClient, но все еще не работает с MSAL
Я получил его работать с MobileServiceClient следующим образом:
1. Используйте MobileService.LoginAsync
2. Возьмите возвращенный User.MobileServiceAuthenticationToken
3. Установите заголовок X-ZUMO-AUTH для содержания User.MobileServiceAuthenticationToken.
user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);
applicationToken = user.MobileServiceAuthenticationToken;
ApiAppClient.UpdateAppAuthenticationToken(applicationToken);
MSAL все еще не работает!
Таким образом, оригинальный вопрос все еще остается: какую часть токена, возвращенного из MSAL, нам нужно передать X-ZUMO-AUTH или какому-либо другому заголовку, чтобы вызовы приложения Azure App Service WebAPI проходили аутентификацию?
1 ответ
У меня есть приложение (в настоящее время в UWP), которое использует MobileServiceClient и AutoRest для приложения API службы приложений Azure. Я успешно использовал winfbsdk и могу через него пройти аутентификацию, а затем получить его для входа в MobileService.LoginAsync с маркером доступа FB в качестве JObject. Я также беру этот JObject и отправляю его в заголовке x-zumo-auth при вызовах приложения API через AutoRest в приложении.
Согласно вашему описанию, я предположил, что вы используете управляемую клиентом аутентификацию. Вы напрямую связываетесь с провайдером идентификации и затем предоставляете токен во время входа в систему с помощью своего мобильного бэк-энда, после чего вы можете использовать MobileServiceClient.InvokeApiAsync
вызвать ваше приложение API, которое добавит X-ZUMO-AUTH
заголовок со значением authenticationToken
после того, как вы вызываете MobileServiceClient.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);
То, что я хотел бы сделать, это иметь возможность аутентификации с использованием MicrosoftAccount. Если я использую MobileService.LoginAsync, я не могу получить правильный токен и передать его AutoRest - он всегда возвращается как 401 Unauthorized. Я попытался использовать MSAL, но он возвращает токен на предъявителя, и его передача также возвращается как 401 Несанкционированный. Есть ли хороший способ сделать это?
AFAIK, для шаблонов аутентификации потока клиента (AAD, Facebook, Google), token
параметр для LoginAsync
будет выглядеть {"access_token":"{the_access_token}"}
,
Для аутентификации клиентского потока (учетная запись Microsoft) вы можете использовать MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}")
Также вы можете использовать LoginAsync
с token
параметр значения {"access_token":"{the_access_token}"}
или же {"authenticationToken":"{Live-SDK-session-authentication-token}"}
, Я проверил LoginAsync
с access_token
из MSA и получить зарегистрированную информацию следующим образом:
В итоге, когда вы получаете authentionToken
после того, как вы вошли в систему с помощью своего мобильного бэкенда, вы можете добавить X-ZUMO-AUTH
заголовок для каждого из ваших запросов API API с authentionToken
,
Для получения более подробной информации, вы можете обратиться к этому официальному документу о проверке подлинности в службе приложений.
ОБНОВИТЬ
Я проверил этот https://github.com/Azure-Samples/active-directory-xamarin-native-v2 и использовал fiddler для захвата сетевых пакетов при аутентификации пользователя и получения токена доступа. Я обнаружил, что MSAL работает против Microsoft Graph и REST, и когда пользователь вошел в систему, вы можете только получить access_token
а также id_token
и оба они не могут быть использованы для единой регистрации с вашим мобильным бэкэндом.
Официальный пример кода для управляемой клиентом проверки подлинности для мобильных приложений Azure с MSA использует Live SDK. Как упоминалось в API-интерфейсе Live SDK REST о подписании пользователей, вы можете получить токен доступа и токен аутентификации, который используется для сценария единого входа. Кроме того, я проверил управляемую сервером аутентификацию и обнаружил, что аутентификация / авторизация службы приложений для MSA также использует REST API Live SDK. Таким образом, вы не можете использовать MSAL для управляемой клиентом аутентификации с MSA, для управляемой клиентом аутентификации вам нужно использовать Live SDK для получения authentication_token
затем вызвать MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}")
чтобы получить authenticationToken
с вашего мобильного бэкэнда. Или вы можете просто использовать управляемую сервером аутентификацию для MSA. Для получения более подробной информации о Live SDK вы можете обратиться к LiveSDK.