Add Authentication to .NET MAUI Apps with Auth0

Hey @alexdevs16,
Welcome to the Auth0 Community!

I’m not able to reproduce your error. However, I’m running the emulator on a Mac, while I see you are running it on a Windows machine. I’m not a mobile developer, soI don’t know if this matters.
I would suggest asking for support in the MAUI community, where I’ve seen this error multiple times.

To follow up, if anyone has this issue where the web view/browser looks like a 90’s TV with a messed up video cable, for me it was a graphics rendering issue. Some kind of incompatibility with the gfx card in my new desktop. I changed the emulator hw.gpu.mode from auto (which was probably using host) to “angle” or “mesa”, either of these worked. Basically, using software instead of hardware to render the emulator graphics.

2 Likes

Cool. Thank you for sharing! :+1:

1 Like

i have a issue with scope when i changed the scope to this i get back endpoint not found error how can i changed the scope
image

Hello @hiromansofaoi,
Welcome to the Auth0 Community!

A few things in your request and in your configuration are not clear to me.

First, this blog post is about authentication in MAUI, but it seems that you are trying to configure your app for accessing an API. In this case, I suggest reading this article instead.

Second, since you need authentication in this kind of application, you must keep the openid scope.

Third, domain and client id parameters cannot be empty strings!

Maybe the best option to understand what’s happening is to share your full code to understand how it is configured (by removing your sensitive data, of course).

@alexdevs16 changing Auth Type helped me to fix this error:

But there are not many docs beside this article (thank you @andrea.chiarelli !! ). Keep in mind that most of the Auth0 docs are focused on Web applications. So when you read something assume this is for web.

1 Like

@andrea.chiarelli

Hello,

I have followed this code precisely. Maui app, targeting Android, iOS and Windows. All .Net7, latest OS on each.

This sets the callback:

        builder.Services.AddSingleton(new Auth0Client(new()
        {
            Domain = "mycompany.auth0.com",
            ClientId = "xxxxxxxxxxxxxxxxx",
            Scope = "openid profile email",
#if WINDOWS
            RedirectUri = "http://localhost/callback"
#else
      RedirectUri = "com.mycompany.mycompany://callback"
#endif
        }));

I keep getting this error:

One or more errors occurred. (You need to declare the windows.protocol usage of the protocol/scheme "http" in your AppxManifest.xml file)'

[External Code]
    mycompany.Auth0.WebBrowserAuthenticator.InvokeAsync(IdentityModel.OidcClient.Browser.BrowserOptions, System.Threading.CancellationToken) in WebBrowserAuthenticator.cs
    [External Code]
    mycompany.Auth0.Auth0Client.LoginAsync() in Auth0Client.cs
    mycompany.MainPage..ctor.AnonymousMethod__0() in MainPage.xaml.cs

Cannot find much on editing the AppxManifest.xml file and no access to it in VS either unless I’m missing something.
Wonder if this might be a local Windows issue as I try run this on my local/dev machine.

EDIT: And in Android I get this:

One or more errors occurred. (You must subclass the WebAuthenticatorCallbackActivity and create an IntentFilter for it which matches your callbackUrl.)'

This sample I think needs to be expanded to include some of this info as there are obviously some new/additional steps missing. It is hard to keep up with the pace of change and moving technical targets, I do realize that!

Thanks

Hi @lindsaymiles,
I have to start with a disclaimer: the .NET MAUI framework is constantly evolving so things may have changed since this article was written.
Have you tried downloading, configuring and running the sample project?

Related to your issues, the protocol/scheme declaration for Windows and the WebAuthenticatorCallbackActivity subclassing for Android should have been done as described in the Apply Platform-Specific Changes section of the article. Did you do apply these changes?

Hello, thanks for your response @andrea.chiarelli !

I have not run your sample, however, I do have a LIVE Xamarin.Forms app that does work and Users can login.

I’m recreating this in Maui (because I have to) and did follow platform specific changes too.
I now have the Android error fixed and callback issues seem to have gone away.

I was having an issue launching the browser as I don’t have a login btn on my app but call the await client.LoginAsync()); when launching the main screen. That works in Xamarin, wouldn’t do it in the Maui Android app.

I’ll likely have questions for the iOS version later…

Thanks for this example and code.
It really has helped a lot getting the Maui version moving along!

1 Like

I want to thank @andrea.chiarelli for the comprehensive blog as well as source code in github. It got me up and running in seconds.

I wanted to know whether anybody has an elegant way to handle the following scenario:
.Net Maui app running on iOs:
When I run the sample and go through the happy path everything works. But when I click on the login button and then click cancel on the window asking whether I want to use auth0.com to sign in I get an empty error message. The same happens if I click continue and go the welcome page, but there click cancel.

Has anybody seen this behaviour and if so, how do you handle it?

Please ignore the question I posted. I found that the reason I was getting a blank error is that whenever the loginResult.Error = “UserCancel” the loginResult.ErrorDescription is null. I added a check for this in the OnLoginClicked event handler

1 Like

Hey @adriaan.van.heerden,
Thank you for your kind feedback and welcome to the Auth0 Community!
Also, happy to learn you were able to solve your issue :slightly_smiling_face:

1 Like

Hi there ,
many many thanks for your amazing project Managing Tokens in .NET MAUI
. i got it all to work except for the logout . I am using windows platform and when calling logout it just hangs …I never get passed this row var browserResult = await oidcClient.Options.Browser.InvokeAsync(browserOptions); and on the next time I login It does not work since it remembers the data and the login process is mixed .can you have any idea what can cause the logout not to work . by the way for the login of my organization i added if (!string.IsNullOrEmpty(audience))
{
parametersDict.Add(“audience”, audience);
}

if (!string.IsNullOrEmpty(organization))
{
parametersDict.Add(“organization”, organization);
}

// Only create the LoginRequest if there are parameters to add.
if (parametersDict.Any())
{
loginRequest = new LoginRequest
{
FrontChannelExtraParameters = new Parameters(parametersDict)
};
} so maybe that is a lead… thanks

Hey @davidos,
Welcome to the Auth0 Community and thank you for appreciating my articles :slightly_smiling_face:

It’s hard to say why logout hangs without any context. Have you tried capturing the application’s HTTP requests? Having the HTTP requests sent to the Auth0 server may help to have more context and see what is happening, although I suspect the logout function is not communicating with the Auth0 server for some reason.

Honestly, I’m not sure if the changes you reported can have an impact on the app’s malfunction. Have you tried removing the organization part and testing the logout?

Let me know how I can help further.

Hi. There is one thing I dont understand in this tutorial - the callbacks

builder.Services.AddSingleton(new Auth0Client(new()
{
    Domain = "domain",
    ClientId = "id",
    RedirectUri = "myapp://callback/mainpage",
    PostLogoutRedirectUri = "myapp://callback/loginpage",
    Scope = "openid profile email"
}));

And on auth0 I’ve set:

  1. Allowed callback URLs
    myapp://callback/mainpage

  2. Allowed logout URLs
    myapp://callback/loginpage

So if user sucessfully logs in I want to redirect him to my mainpage, and if a user logs out, he should be redirected again to a login page. But I don’t know how to achieve it. I thought that these callbacks can be captured by my api controllers, but so far it doesn’t work.

Can anyone help me with that?
Thank you!

Hey @Morbid,
The RedirectUri and PostLogoutRedirectUri are not like web URLs. They are URIs with a custom scheme (myapp in the example) that are used by the operating system to pass some data back to your app. There is no API controller that captures these routes.

If you want to redirect the user to a specific page after authentication or logout, I think you can do it through code after LoginAsync() and LogoutAsync() are invoked.

Hi @andrea.chiarelli, thank you for your response.

It is true that I can redirect a user to a given page after LoginAsync() or LogoutAsync(), but this makes it even more confusing to me.

RedirectUri = "myapp://callback",
PostLogoutRedirectUri = "myapp://callback",

If both of these actions point to the same endpoint, then what can I even use them for in a native app context?

Other than that ChatGPT gave me an idea, how can I capture these uri callbacks, but I don’t know if this a good idea to handle it this way:

public class WebAuthenticationCallbackActivity : Microsoft.Maui.Authentication.WebAuthenticatorCallbackActivity
{
    const string CALLBACK_SCHEME = "myapp";

    protected override async void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Check if this activity was launched with the correct intent
        if (Intent.Action == Android.Content.Intent.ActionView && Intent.Data != null)
        {
            var uri = Intent.Data;
            if (uri.Scheme.Equals(CALLBACK_SCHEME))
            {
                // Handle the URI activation here
                // This method will be called when the app is activated via a URI, such as the redirect URI after authentication

                // Example: Extract token or other data from the URI and proceed with authentication flow
                await HandleUriActivated(uri);
            }
        }

        // Finish the activity
        Finish();
    }

    private async Task HandleUriActivated(Android.Net.Uri uri)
    {

        // Handle the URI activation here
        // This method will be called when the app is activated via a URI, such as the redirect URI after authentication

        // Example: Navigate to a specific page or perform an action based on the URI
        //await MainPage.DisplayAlert("URI Activated", $"URI: {uri}", "OK");
    }
}

What do you think?

Hey @Morbid,
Don’t consider RedirectUri and PostLogoutRedirectUri as endpoints (at least not in the web sense). They are just URIs used by the operating system to determine what application it should open. The interpretation of these URIs and their parameters is up to your application.

The activity you outlined shows a way to process and interpret these URIs, but this is a low level approach where you should take care of all the URI parsing, token validation, principal creation, etc. Actually, all this work is done by the OidcClient library, which the Auth0 MAUI SDK relies on.
If you want to learn how it works internally, take a look at the LoginAsync() implementation.

Disclaimer: I’m not a mobile developer nor a MAUI expert, so some technicalities may not be accurate, but the overall description of the URI management should be correct.

@andrea.chiarelli


any idea why am I getting this error ?

Hi @sish,
Make sure that the URI scheme you registered in your manifest is the same registered in the Auth0 dashboard as an Allowed Logout URL. In the article it’s myapp.