Auth0 Home Blog Docs

Xamarin.Form OAuth2 login

xamarin
xamarin-forms
oauth2

#1

Hello,

I’m trying to do this using the Oauth2Authenticator in Xamarin.Auth:

            authenticator = new OAuth2Authenticator(
        clientId: "myAuth0ClientID", // your OAuth2 client id
        scope: "", // the scopes for the particular API you're accessing, delimited by "+" symbols
        authorizeUrl: new Uri("https://mycompany.auth0.com"), // the auth URL for the service
        redirectUrl: new Uri("com.mycompany.app://mycompany")
        ) // the redirect URL for the service
        {
            AllowCancel = true,
        };

Can I do this connecting to Auth0?
Can someone please clarify the authorizeUrl for me?

thanks


#2

:wave: @lindsaymiles have you had a chance to take a look at our Xamarin quickstart?

The authorizeUrl for the OAuth2Authenticator in Xamarin.Auth is the URL where the authorization code will be obtained from. For example, if you were using Facebook login (note this is not making use of Auth0) it would be authorizeUrl: new Uri ("https://m.facebook.com/dialog/oauth/")


#3

Finally back at this… other projects took precedence.

Yes, I’ve looked through quick starts. Got the FaceBook auth working just fine but I’ve selected 5 different auth providers - FB, LinkedIn, Google, Live and Instagram.

Google just won’t work. Not through Auth0 or any other way because it won’t launch into a webview. Calling back from the browser is proving problematic where it sometimes works and sometimes doesn’t (no code change) and I can’t get back to the app itself. So, dropping Google. For now.

As for Auth0, it works fine in Android and login through FB too. Problem is once logged in, I can’t seem to see which provider the user login with…the args returned to Authentication_Completed don’t indicate which.

In iOS, the webview won’t even show up.

So, I don’t think this is all that clear implementing in Xamarin Forms.

I don’t have time to sort this out. I need to put aside and use FB directly with OAuth2Authenticator and worry about this Auth0 implementation later. To cryptic, too many constant changes in all providers, too many technical challenges which seem to result in hacks to make work which makes for unreliable coding.

Dropping Auth0 for now. Unfortunately. Because in theory, this would have been great!


#4

What I really should ask is this from another thread (also unresolved):

I have reviewed the QuickStart for Xamarin but they are for native iOS and Android, not Xamarin.Forms. The implementations in each project seem different enough that it would likely not be possible to move the code to the shared Xamarin.Forms project (at least using the OIDC client).

Also thought about adding a DepenencyService and building the concrete implementations in each platform specific project but I am not sure how I would pass in the UIViewController (iOS) or Activity (Android) since I would be using Xamarin Pages in the shared project.

Add another quickstart for THAT and I think it’ll help a lot of Auth0 potential clients.


#5

It would be great to use a page renderer in each platform and handle all in that renderer.

This already works in a facebook login and page renderer I created. Separate page renderers in iOS and Android and both work for FaceBook authentication.

Here’s the page renderer, hopefully someone can make head or tail out of that. I’ve added code I’ve tried for Auth0 using the Auth0Client as well as suggestions commented out. I’m sure someone at Auth0 could adapt this to make something work in a Xamarin.Form SHARED project…

using System;
using Android.App;
using Xamarin.Forms.Platform.Android;
using Xamarin.Auth;
using MyCompany.Views;
using MyCompany.Droid;
using Xamarin.Forms;
using System.Threading.Tasks;
using System.Net.Http;
using Newtonsoft.Json;
using MyCompany.Authentication;
using Auth0.OidcClient;

[assembly: ExportRenderer(typeof(LoginPageAO), typeof(LoginPageRendererAO))]
namespace MyCompany.Droid
{
public class LoginPageRendererAO : Xamarin.Auth.XamarinForms.XamarinAndroid.AuthenticatorPageRenderer
{

    protected override async void OnElementChanged(ElementChangedEventArgs<Page> e)
    {

        var client = new Auth0Client(new Auth0ClientOptions
        {
            Domain = "MyCompany.auth0.com",
            ClientId = "abcdefg..."
        });
        var loginResult = await client.LoginAsync();


        //OR Use the OAuth2Authenticator and handle the "completed" and "error" methods            
        //We would need a return of which provider the user chose so that user details can be retrieved from that provider with the given access credentials            

        //_authenticator = new OAuth2Authenticator(                
        //clientId: "abcdefg...", // your OAuth2 client id
        //scope: "", // the scopes for the particular API you're accessing, delimited by "+" symbols
        //authorizeUrl: new Uri("https://MyCompany.auth0.com/authorize"), // the auth URL for the service
        //redirectUrl: new Uri("com.MyCompany.MyCompany://MyCompany")
        //) // the redirect URL for the service
        //{
        //    AllowCancel = true,
        //};

        //_authority = "AO";

        //_authenticator.Completed += Authentication_Completed;
        //_authenticator.Error += Authentication_Error;

        //var intent = auth.GetUI(activity);
        //activity.StartActivity(intent);


    }

    private void OnAuthenticationCompleted(object sender, AuthenticatorCompletedEventArgs e)
    {
        if (e.IsAuthenticated)
        {

            var accessToken = e.Account.Properties["access_token"];

            //NOTE: Using Auth0, we'd need to know what provider the client chose so as to get user details unless this is already retrieved

            //OPTION 1 (I've not included all the FB client and service code)
            var facebookClient = new FacebookClient();
            var facebookService = new FacebookService(facebookClient);
            var getAccountTask = facebookService.GetAccountAsync(accessToken);
            //getAccountTask.Wait();
            //Task.WaitAll(getAccountTask);
            //var account = getAccountTask.Result;
            //Settings.UserId = account.Id;

            //OPTION 2
            //Task<string> s = GetUserIDAsync(accessToken);
            //Task.WaitAll(s);
            //s.ContinueWith(null);
            //string s = GetUserID(accessToken);

            //OPTION 3
            //JObject obj = new JObject();
            //var request = new OAuth2Request("GET", new Uri("https://graph.facebook.com/me"), null, e.Account);
            //request.GetResponseAsync().ContinueWith(t => {
            //    t.Wait();
            //    if (t.IsFaulted)
            //    {
            //        //App.UnSuccessfulLoginAction.Invoke();
            //    }
            //    else
            //    {
            //        obj = JObject.Parse(t.Result.GetResponseText());
            //        string userId = (string)obj["id"];
            //        Settings.UserId = userId;
            //    }
            //});

            //This will hide the login screen and start the MainPage
            App.SuccessfulLoginAction.Invoke();

        }
        else
        {
            // The user is not authenticated
        }
    }

    private void OnAuthenticationFailed(object sender, AuthenticatorErrorEventArgs e)
    {
        //this.Dispose();
    }

    public string GetUserID(string accessToken)
    {
        var httpClient = new HttpClient();
        var userIdjson = httpClient.GetStringAsync($"https://graph.facebook.com/v2.12/me?fields=id&access_token=" + accessToken);

        return userIdjson.ToString();
    }

    public async Task<string> GetUserIDAsync(string accessToken)
    {
        var httpClient = new HttpClient();
        var userIdjson = await httpClient.GetStringAsync($"https://graph.facebook.com/v2.12/me?fields=id,name&access_token=" + accessToken);

        var userId = JsonConvert.DeserializeObject(userIdjson);
        return userId.ToString();
    }
}

}


#6

Anyone at Auth0 going to both commenting or helping with this?

@kim.noel ? Anyone else?

Need help implementing your authoraztion solution in a Xamari.Forms SHARED project.
Not only me, but many potential customers could do with help in this.

Thank You


#7

Kim, could you kindly revisit this post, take a look at what I’ve added and offer some further help?

Thank you