Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 58056

Azure Mobile Service AD login with Xamarin iOS acquireToken error

$
0
0

I have configured a Xamarin Forms iOS app to use Azure Active Directory authentication. I successfully get the login prompt (using ADAL_iPhone_storyboard.storyboard obtained online). When I log in with a new user I even get the "first time change password" screens which is good and means its connecting to my Azure Mobile Service. The problem is once I have clicked submit, Visual Studio quits with the following error:

System.InvalidOperationException: Error during authentication: The user is currently prompted for credentials as result of another acquireToken request. Please retry the acquireToken call later.

I am fairly stumped with this. I have the following classes included in the iOS project. This first one is called by the Xamarin Forms master project which is here (App.cs);

public static Page GetMainPage()
{
    return new LoginPage();
}

Now these classes are in the iOS project itself;

[assembly: ExportRenderer(typeof(LoginPage), typeof(LoginPageRenderer))]

namespace mynamespace
{
    public class LoginPageRenderer : PageRenderer
    {
    private AccountService accountService;

    public override async void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);

        accountService = AccountService.DefaultService;

        if (accountService.User == null)
        {
            await accountService.Authenticate();
        }
    }
}
}

It runs to the "await accountService.Authenticate() call, and the user goes through entering the Azure account name and password in the UI. The Authenticate() method is here in the AccountService class;

    public class AccountService
{
    private static AccountService accountServiceInstance = new AccountService();
    public static AccountService DefaultService { get { return accountServiceInstance; } }
    private MobileServiceClient client;
    private IMobileServiceTable<AccountSummary> todoTable;

    public List<AccountSummary> Items { get; private set; }

    private MobileServiceUser user;
    public MobileServiceUser User { get { return user; } }

    protected AccountService()
    {
        CurrentPlatform.Init ();

        Items = new List<AccountSummary>();

        client = new MobileServiceClient (Constants.ApplicationURL, Constants.ApplicationKey);
        todoTable = client.GetTable<AccountSummary>();
    }

    public async Task Authenticate()
    {
        var aadAuthority = @" *.onmicrosoft.com";
        var aadResource = @"*/login/aad";
        var aadClientId = @"*";
        var aadRedirect = @"*/login/done";

        ADAuthenticationError error;
        var aadContext = ADAuthenticationContext.AuthenticationContextWithAuthority(aadAuthority, out error);
        if (error != null)
        {
            throw new InvalidOperationException("Error creating the AAD context: " + error.ErrorDetails);
        }

        var tcs = new TaskCompletionSource<string>();
        aadContext.AcquireTokenWithResource(aadResource, aadClientId, new NSUrl(aadRedirect), result =>
        {
            if (result.Status == ADAuthenticationResultStatus.SUCCEEDED)
            {
                tcs.SetResult(result.AccessToken);
            }
            else
            {
                string errorDetails;
                if (result.Status == ADAuthenticationResultStatus.USER_CANCELLED)
                {
                    errorDetails = "Authentication cancelled by user";
                }
                else
                {
                    errorDetails = result.Error.ErrorDetails;
                }

                tcs.SetException(new InvalidOperationException("Error during authentication: " + errorDetails));
            }
        });
        string accessToken = await tcs.Task;

        var token = new JObject(new JProperty("access_token", accessToken));

        try
        {
            user = await this.client.LoginAsync(MobileServiceAuthenticationProvider.WindowsAzureActiveDirectory, token);
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine(@"ERROR - AUTHENTICATION FAILED {0}", ex.Message);
        }
    }
}

Then it throws the error as the result.Status is FAILED. It has the info;

System.InvalidOperationException: Error during authentication: The user is currently prompted for credentials as result of another acquireToken request. Please retry the acquireToken call later.

The user account is configured in Azure and they are not blocked. Any help or pointers would be greatly appriciated!


Viewing all articles
Browse latest Browse all 58056

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>