简体   繁体   中英

Azure AD B2C for Xamarin.forms "Safari cannot open the page because the address is invalid"?

Following along with the Xamarin native sample , the sample itself seems to work fine on ios, but when I put in my own credentials, after entering user name and password I an popup that says "Safari cannot open the page because the address is invalid". This is my main problem, if anybody can advise that would be very grateful.

The bigger issue though is I don't understand what is actually going on in the code. I'm not looking for a redirect after authentication anyway. I'm just trying to get a token back to my app's code, so I would like to dismiss the webform and return control to my code. But instead I am stuck with the popup. (This all works fine and as expected in the sample, but when I put in my own credentials, as best as I can figure them out based on the notes in the sample, I get this error.)

I'm thinking it must have to do something with the scopes or redirect settings on the Tenant, but its all very opaque on the page and in the documentation what any of this means Eg what is a "scope?" in the first place, and why is the value as the scope argument in thhe sample a url?

From what I can tell, what I want the scope to be is "OpenId" since I am using local authentication, but if you set "scopes" to the { "OpenId" } you get an error saying those scopes are already included. But if you leave it blank, you also get an error saying scopes are required. So what up with that?

With respect to tenant setting page, if I am only building something to service logins on my app, why do I need to answer "yes" to the question "Include web app/web api?". Why is the reply url set to non-existent value " https://myapi "? Why is the App ID Uri set to " https://[applicationName]/onmicrosoft.com/demoapi ? and what is its purpose?

In the "Native Client" section, the registration provides pre-populated fields "Redirect Uri" and "custom redirect uri". The Redirect URI looks like "urn:ietf:wg:oauth:2.0:oob". What is that? the pop up says it's a

"Unique identifier which B2C will redirect the user agent in an Oath2.0 response"

but it doesnt look like there are enough letters here to possibly be unique ID.

The there is a thing called "the "custom" redirect uri, which I guess is different than the plain old "Redirect URI" and that one looks like

msal3b4c7038-694a-42d6-bab0-43d5b1f86106://auth

So why is one "custom" and why is the other apprarently not custom?

Sorry for all the questions but I can't find good documentation explaining any of this. Much appreciated, and if anyone from Azure is listening, maybe they could point to some Xamarin/Azure documentation that would help me understand this.

Many thanks!

PS Maybe this post has too many questions, and not sure if I am supposed to split these up into separate questions. If so, please let me know. My main question is the first one.

Relevant Code below:

    public static string Tenant = "crowdwisdom.onmicrosoft.com";
        public static string ClientID = "3b4c7038-694a-44c6-bab0-43d5b1f86106";
        public static string PolicySignUpSignIn = "B2C_1_susi";
        public static string PolicyEditProfile = "B2C_1_edit_profile";
        public static string PolicyResetPassword = "B2C_1_reset";

        public static string[] Scopes = { "https://crowdwisdom.onmicrosoft.com/demoapi/demo.read" };
        public static string ApiEndpoint = "https://crowdwisdom.azurewebsites.net";

        public static string AuthorityBase = $"https://login.microsoftonline.com/tfp/{Tenant}/";
        public static string Authority = $"{AuthorityBase}{PolicySignUpSignIn}";
        public static string AuthorityEditProfile = $"{AuthorityBase}{PolicyEditProfile}";
        public static string AuthorityPasswordReset = $"{AuthorityBase}{PolicyResetPassword}";

        public static UIParent UiParent = null;

...

async void OnSignInSignOut(object sender, EventArgs e)
    {
        try
        {
            if (btnSignInSignOut.Text == "Sign in")
            {
                AuthenticationResult ar = await App.PCA.AcquireTokenAsync(App.Scopes, GetUserByPolicy(App.PCA.Users, App.PolicySignUpSignIn), App.UiParent);
                UpdateUserInfo(ar);
                UpdateSignInState(true);
            }
            else
            {
                foreach (var user in App.PCA.Users)
                {
                    App.PCA.Remove(user);
                }
                UpdateSignInState(false);
            }
        }
        catch(Exception ex)
        {
            // Checking the exception message 
            // should ONLY be done for B2C
            // reset and not any other error.
            if (ex.Message.Contains("AADB2C90118"))
                OnPasswordReset();
            // Alert if any exception excludig user cancelling sign-in dialog
            else if (((ex as MsalException)?.ErrorCode != "authentication_canceled"))
                await DisplayAlert($"Exception:", ex.ToString(), "Dismiss");
        }
    }

Here's the Azure B2C tenant settings:

在此处输入图片说明

I'll break down my answer into two posts since there are two different sets of questions here.

Redirect URI's ( how to return to your app )

Leaving the browser and returning to your app is mostly done using the redirect uri. The MSALxxxxxx://oauth is the redirect uri path that you (according to your screenshot) have registered with B2C. That looks good. When you're making the call to Azure AD B2C, you need to make sure the redirect URI is set to that value. When Azure AD B2C generates a token, it will send it forward to that redirect URI.

Now, the app needs to receive that token. This is done by listening to a uri scheme, which is everything before the colon. In this case, the URI scheme is MSALxxxxxx. To configure your xamarin app to listen to that URI scheme, follow step 6 in this sample . That steps helps you configure the return URI for each kind of platform. Now, whenever the browser detects a redirect to MSALxxxx, it will send the message forward to your app. In this case, you will receive a B2C token in your message.

By the way, "urn:ietf:wg:oauth:2.0:oob" is just a default redirect URI that we provide. We recommend you only use it for testing purposes, and that you create a unique redirect URI scheme for your app.

See my other answer above or below that answers the question regarding redirect URI's.

Scopes:

Scopes are mostly necessary when you're calling an API. Think of them like permissions. For example, you could have a "tasks list" api that stores your tasks for the day. Suppose you want your app to be able to "read" from the API. So you call Azure AD B2C, and request an access token that gives you the ability to "read" from the API. You would do this by inserting "read" as one of the scopes in your request.

The problem is, any API can have a read scope, so to distinguish which API you are referring to, you use the App ID URI. So in Azure AD B2C, you set the App ID URI as " https://tenantName.onmicrosoft.com/tasksList ". Then when you're making the request, you specify the scope as " https://tenantName.onmicrosoft.com/tasksList/read " (notice that 'read' was added to the end of that "URL")

As neither of the answers helped me solved this I'll put my answer here as the libraries have been updated since this post.

The new way to add a redirect URI to the Azure AD B2C Application is like so:

在此处输入图片说明

But I can't find instructions on how to configure the app correctly to make this work. So I had to configure the redirect in the old way like so:

在此处输入图片说明

This stopped the error in Safari which I worked out from adding logging to the Microsoft.Identity library, copying the URL it was trying to load from the logs, and pasting it into Safari. This showed that the error from Azure was a missing redirect.

在此处输入图片说明

I hope this helps someone else and if you know why the new way is not working please post it here too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM