Закрыть .Auth / login / done после успешного входа в MSAL в приложении Xamarin - PullRequest
0 голосов
/ 14 января 2020

Я настраивал аутентификацию AD (MSAL), используя azure с моим приложением, но у меня проблема с закрытием окна, которое появляется после успешного входа. Страница, которая появляется во встроенном браузере со ссылкой, возвращающейся к моему API На домашней странице просто написано «Вы успешно вошли» со ссылкой ниже, чтобы вернуться на предыдущую страницу с переходом на мою домашнюю страницу API.

Ниже приведен мой код в моем App.xaml.cs

public partial class App : Application
{
    public static IPublicClientApplication PCA = null;

    public static string ClientID = "********-****-****-****-**********";

    public static string[] Scopes = { "User.Read" };
    public static string Username = string.Empty;

    public static object ParentWindow { get; set; }

    public App()
    {
        InitializeComponent();
    }

    protected override async void OnStart()
    {
        PCA = PublicClientApplicationBuilder.Create(ClientID)
            //.WithRedirectUri($"msal{ClientID}://auth")
            .WithRedirectUri("https://kpiapp-api-dev.azurewebsites.net/.auth/login/aad/callback")
            .WithIosKeychainSecurityGroup("com.microsoft.adalcache")
            .WithAuthority(AzureCloudInstance.AzurePublic, "********-****-****-****-**********") //TenantID
            .Build();

        MainPage = new NavigationPage(new LoginPage());

    }

    protected override void OnSleep()
    {
        // Handle when your app sleeps
    }

    protected override void OnResume()
    {
        // Handle when your app resumes
    }
}

И мой Loginpage.xaml.cs:

public partial class LoginPage : ContentPage
{
    public LoginPage()
    {
        InitializeComponent();
    }

    async void OnSignIn(object sender, EventArgs e)
    {
        AuthenticationResult authResult = null;
        IEnumerable<IAccount> accounts = await App.PCA.GetAccountsAsync();

        var current = Connectivity.NetworkAccess;
        bool connectionFound = false;

        if (current == NetworkAccess.Internet)
        {
            connectionFound = true;
        }

        string APIData = "";

        if(connectionFound == true)
        {

            try
            {
                if (SignInButton.Text == "Sign in")
                {
                    try
                    {
                        IAccount firstAccount = accounts.FirstOrDefault();
                        authResult = await App.PCA.AcquireTokenSilent(App.Scopes, firstAccount)
                                                .ExecuteAsync();

                    }
                    catch (MsalUiRequiredException ex)
                    {
                        try
                        {
                            authResult = await App.PCA.AcquireTokenInteractive(App.Scopes)
                                                        .WithParentActivityOrWindow(App.ParentWindow)
                                                        .ExecuteAsync();
                        }
                        catch (Exception ex2)
                        {
                            await DisplayAlert("Acquire token interactive failed. See exception message for details: ", ex2.Message, "Dismiss");
                        }
                    }

                    if (authResult != null)
                    {
                        var content = await GetHttpContentWithTokenAsync(authResult.AccessToken);

                        SignInButton.Text = "Sign out";
                    }
                }
                else
                {
                    while (accounts.Any())
                    {
                        await App.PCA.RemoveAsync(accounts.FirstOrDefault());
                        accounts = await App.PCA.GetAccountsAsync();
                    }
});
                    SignInButton.Text = "Sign in";

                }
            }
            catch (Exception ex)
            {
                await DisplayAlert("Authentication failed. See exception message for details: ", ex.Message, "Dismiss");
            }

            await Task.Yield();

            APIData = getAPIData();

        }
        else
        {
            await DisplayAlert("Connection Error", "Check your internet connection and try again", "Try again");
        }

        if (APIData != "ConnectionError")
        {
            await Navigation.PushAsync(new MainPage(APIData));
        }
        else
        {
            await Task.Delay(500);
            await DisplayAlert("API Download error", "Error connecting to API", "Try again");
        }
    //MainPage = new MainPage(APIData);
}

    public async Task<string> GetHttpContentWithTokenAsync(string token)
    {
        try
        {
            //get data from API
            HttpClient client = new HttpClient();
            HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/v1.0/me");
            message.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
            HttpResponseMessage response = await client.SendAsync(message);
            string responseString = await response.Content.ReadAsStringAsync();
            return responseString;
        }
        catch (Exception ex)
        {
            await DisplayAlert("API call to graph failed: ", ex.Message, "Dismiss");
            return ex.ToString();
        }
    }

    private string getAPIData()
    {
        string APIData = "";

        try
        {
            APIData = new WebClient().DownloadString("****/api/data");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
            APIData = "ConnectionError";
        }

        return APIData;
    }
}

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

Спасибо

1 Ответ

0 голосов
/ 14 января 2020

Мне удалось решить эту проблему, добавив .WithUseEmbeddedWebView (true) ко второму вызову authResult, чтобы он выглядел так:

catch (MsalUiRequiredException ex)
{
    try
    {
         authResult = await App.PCA.AcquireTokenInteractive(App.Scopes)
                                      .WithParentActivityOrWindow(App.ParentWindow)
                                      .WithUseEmbeddedWebView(true)
                                      .ExecuteAsync();
     }
     catch (Exception ex2)
     {
         await DisplayAlert("Acquire token interactive failed. See exception message for details: ", ex2.Message, "Dismiss");
     }
}
...