Социальная / корпоративная аутентификация не работает с мобильными приложениями Azure и Xamarin Forms - PullRequest
0 голосов
/ 12 июня 2019

У меня есть приложение Xamarin.forms с бэкэндом мобильных приложений Azure, в котором я пытался использовать корпоративную и социальную аутентификацию, следуя этому руководству https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/.

Мне удалось настроить оба сервера и проверить, что они работают. Это можно проверить на этих страницах

https://tasklistsync2.azurewebsites.net/.auth/login/google https://MyMobileApps.b2clogin.com/MyMobileApps.onmicrosoft.com/oauth2/v2.0/authorize?p=B2C_1_emailPolicy&client_id=9ec9bcd1-ee5f-4abb-9908-8d63a24b6165&nonce=defaultNonce&redirect_uri=https%3A%2F%2Ftasklistsync2.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback&scope=openid&response_type=id_token&prompt=login

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

Вот что происходит, когда я нажимаю кнопку входа в систему.

async Task ExecuteLoginCommand()
        {
            if (IsBusy)
                return;
            IsBusy = true;

            try
            {
                var cloudService = ServiceLocator.Instance.Resolve<ICloudService>();

                //Login methods

                await cloudService.LoginAsync();           //Social/enterprise
                //await cloudService.LoginAsync(User);      //Custom login

                Application.Current.MainPage = new NavigationPage(new Pages.TaskList());
            }
            catch(Exception ex)
            {
                Debug.WriteLine($"[Login] Error = {ex.Message}");
            }
            finally
            {
                IsBusy = false;
            }
        }

Это относится к cloudService.LoginAsync (), который реализован в моем классе AzureCloudService.

public Task LoginAsync()
        {
            var loginProvider = DependencyService.Get<ILoginProvider>();
            return loginProvider.LoginAsync(client);
        }

Также реализовано в проекте android.

public async Task LoginAsync(MobileServiceClient client)
        {            
            await client.LoginAsync(context, MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, "tasklistsync2");
        }

Таким образом, весь этот процесс выполняется, и я могу ввести свои учетные данные, но затем приложение остается там с пустой страницей входа и новым NavigationPage (new Pages.TAskList ()); линия никогда не подвергается Если я закрываю страницу входа, она переходит в блок finally в Try and Catch.

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

Ответный URL-адрес для процессов аутентификации, настроенных в конфигурации Azure, как описано в руководстве, приведен ниже. https://tasklistsync2.azurewebsites.net/.auth/login/google/callback https://tasklistsync2.azurewebsites.net/.auth/login/aad/callback

1 Ответ

0 голосов
/ 14 июня 2019

Вам необходимо реализовать интерфейсы входа в систему для платформы, специфичной для iOS и Android.

 public class iOSPlatform : IPlatform {

            public UIViewController RootView => UIApplication.SharedApplication.KeyWindow.RootViewController;

            public AccountStore AccountStore { get; private set; }

            public iOSPlatform()
            {
                AccountStore = AccountStore.Create();
            }
  public async Task<MobileServiceUser> LoginAsync(MobileServiceClient client)
        {
            var accessToken = await LoginADALAsync();
            var zumoPayload = new JObject();
            zumoPayload["access_token"] = accessToken;
            if (accessToken != null)
                return await client.LoginAsync("aad", zumoPayload);
            else
                return null;
        }

#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
        public async Task LogoutAsync()
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
        {
            // Do nothing
            var authContext = new AuthenticationContext(Constants.authority);
            if (authContext.TokenCache.ReadItems().Any())
            {
                authContext.TokenCache.Clear();
            }

            //In addition to clearing the token cache, you should also clear the cookies in the web view.
            //Otherwise, the session cookies come into play and that is why you are seeing the web view come up and disappear immediately.
            foreach (var cookie in NSHttpCookieStorage.SharedStorage.Cookies)
            {
                NSHttpCookieStorage.SharedStorage.DeleteCookie(cookie);
            }
        }

        private async Task<string> LoginADALAsync()
        {
            var authContext = new AuthenticationContext(Constants.authority);
            if (authContext.TokenCache.ReadItems().Any())
            {
                authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);
            }
            var authResult = await authContext.AcquireTokenAsync(
                Constants.resourceId,
                Constants.clientId,
                new Uri(Constants.redirectUri),
                new PlatformParameters(RootView));
            return authResult.AccessToken;
        }
}

Аналогично для Android, за исключением того, что Android использует Context вместо UIViewController

public Context RootView { get; private set; }

        public AccountStore AccountStore { get; private set; }

        public void Init(Context context)
        {
            RootView = context;
            AccountStore = AccountStore.Create(context);
        }
...