Вызовы 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);
  1. Войдите в приложение 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);
                }
            }
        }
    
  2. Вызов 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);
    


  3. Любые последующие вызовы с использованием 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.

Другие вопросы по тегам