Transition to Claimed HTTPS URIs

On Android, everything works as expected with https scheme. Unfortunately, we have some issues on iOS side. The logout process never closes the browser, it hangs on the callback site.

For the login, there are some cases when, after pressing “Continue”, the page remains on the “universal login”. Is there something wrong with the setup? Is there something wrong with the auth0 client?

I’m using Auth0.OidcClient.MAUI v1.4.0 and *.auth0.com tenant.

There are no errors in dashboard, all operations are successful. My app is always opening when I’m tapping on the callback link from notes, so I don’t think this is related to universal link. I’ve tested this on iOS 18.7.7 and 26.4.

1 Like

Hi @gluten

Welcome to the Auth0 Community!

I believe the issue is caused by an architectural clash between Apple’s underlying authentication API (ASWebAuthenticationSession ) and https Universal Links. Apple explicitly designed ASWebAuthenticationSession to listen for a Custom URL Scheme (e.g., myapp:// ) to know when to dismiss its modal window.

When you use an https scheme for an OAuth callback, iOS successfully routes the link to your app, but it fails to notify the authentication session to close, leaving the browser window hanging permanently on the screen.

  1. In your Auth0 Dashboard → Applications → [Your App] → Settings, add a custom scheme to your Allowed Callback URLs and Allowed Logout URLs . A reverse-DNS format is recommended (e.g., com.yourcompany.app://callback ).
  2. Register your new custom scheme in your MAUI project’s Platforms/iOS/Info.plist file so the OS knows your app owns it:
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>Auth0</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>com.yourcompany.app</string>
        </array>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
    </dict>
</array>
  1. Inside your MAUI code, you will need to conditionally use the Custom Scheme for iOS while retaining your https link for Android (if you prefer to keep Android on App Links):
#if IOS
    var redirectUri = "com.yourcompany.app://callback";
#else
    var redirectUri = "https://yourcompany.com/callback";
#endif

Let me know if that does the trick for you!

Kind Regards,
Nik

1 Like

Hi @nik.baleca , the only issue with your fix is the fact that we’ve been receiving warnings from Auth0 saying:

This notice reminds you of Auth0 changes to login flows that use custom URI schemes or loopback URIs as callbacks. Starting April 28, 2026, Auth0’s default behavior changes for these login flows, and a new login confirmation prompt may be displayed to users.
Small Link
How are you affected?
Between February 26 and March 19, at least one of your tenants received login requests using a custom URI scheme or a loopback URI (localhost) callback.

What action do you need to take?
Review Measures Against Application Impersonation and, before April 28, 2026, configure your tenant using one of the options below. Consider the security risks. Attackers can exploit custom URI schemes and loopback URIs for application impersonation and unauthorized access.

Option A - Skip the end-user confirmation prompt

This option preserves the original behavior. You do not need to change your applications, and the user experience stays the same.

Follow the steps in the Opt out of new login confirmation prompt section of the migration guide, specifically the steps to opt out at the tenant level.

Option B - Adopt the end-user confirmation prompt or transition to claimed HTTPS URIs

This option strengthens security but requires you to update your applications or change the user experience.

Follow the steps in the Opt in to new login confirmation prompt section of the migration guide to adopt the confirmation prompt and update applications to use a claimed HTTPS URI for callbacks.

Additionally, if the logout process is performed through the custom scheme, we’ll still receive the warning.

1 Like

I see. Thanks for the update.

I have completely overlooked the fact that custom uri schemes are not recommended due to the risk of application impersonation. You can read more about that here.

Otherwise, going back to the issue, to use the secure https Universal Links and completely resolve both the Auth0 warning and the hanging browser, try following these steps:

  1. You must intercept the NSUserActivity (the Universal Link) and pass it to MAUI’s WebAuthenticator . Open your Platforms/iOS/AppDelegate.cs file and add the ContinueUserActivity method:
using Foundation;
using UIKit;
using Microsoft.Maui.Authentication; // Required for WebAuthenticator

namespace YourAppNamespace;

[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
    protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();

    [Export("application:continueUserActivity:restorationHandler:")]
    public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
    {
        if (userActivity.ActivityType == NSUserActivityTypeBrowsingWeb)
        {
            var url = userActivity.WebPageUrl;
            if (url != null)
            {
                WebAuthenticator.Default.OnResume(url);
            }
        }
        
        return base.ContinueUserActivity(application, userActivity, completionHandler);
    }
}
  1. Revert Auth0 Configuration to HTTPS
  • Change your Auth0ClientOptions Redirect URI and Post Logout URI back to your https domains.
  • Ensure those https URLs are correctly listed in your Auth0 Dashboard > Applications > Allowed Callback / Logout URLs.

With this code in place, when Auth0 redirects to your https link, iOS should open the app, trigger ContinueUserActivity , pass the URL to OnResume() , and the browser will instantly vanish, completing the login/logout process.

Let me know if this works or not!

Kind Regards,
Nik

2 Likes

@nik.baleca I’ve tried like this, as OnResume isn’t part of WebAuthentication. I’ve put a breakpoint into this and it never hits on logout, only on login

[Export(“application:continueUserActivity:restorationHandler:”)]

public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)

{

    if (userActivity.ActivityType == NSUserActivityType.BrowsingWeb)

    {

        var url = userActivity.WebPageUrl;

        if (url != null)

        {

            return WebAuthenticator.Default.OpenUrl(url);

        }

    }

        

    return base.ContinueUserActivity(application, userActivity, completionHandler);

}
2 Likes

I have a similar situation. My app (android and ios) worked like the Maui quickstart documentation but we should now move away from the custom uri scheme. Android works with https now, but still strugling with iOS.

I tried the same as suggested here (also no Onresume in WebAuthentication) and see the same results (the browser stays open after logging in, saying ‘Not found‘, so not returning to the app.

The last two weeks i have had help with this through a support ticket (by Emil) where we doublechecked each setting in Auth0 and the Maui iOS code, but could not find a solution unfortunately.

I’ll be keeping an eye on any pointer you guys may have :slight_smile:

1 Like

Hi again!

Sorry for the delayed reply and thanks for providing more info on the matter!

When iOS refuses to trigger ContinueUserActivity for a specific URL, it means the OS routing engine decided to treat the logout redirect as a standard web page rather than a deep link into your app. This usually happens for one of two reasons: either the specific logout path is missing from your domain’s Apple App Site Association (AASA) file, or iOS WebKit is aggressively blocking the automatic HTTP 302 redirect issued by Auth0’s logout endpoint.

To force iOS to respect the Universal Link on logout and close the browser, try to follow these steps:

  • Update your AppDelegate.cs to use MAUI’s dedicated auth callback manager. This is the specific method designed to close the ASWebAuthenticationSession modal:
[Export("application:continueUserActivity:restorationHandler:")]
public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
    if (userActivity.ActivityType == NSUserActivityType.BrowsingWeb)
    {
        var url = userActivity.WebPageUrl;
        if (url != null)
        {
            Microsoft.Maui.Authentication.WebAuthenticationCallbackManager.Authenticate(url);
            return true;
        }
    }
        
    return base.ContinueUserActivity(application, userActivity, completionHandler);
}
  • If your AASA file is the culprit, the fastest way to test and fix this is to use the exact same URL for both login and logout.

  • Since iOS has already proven it trusts your login URL and triggers the breakpoint, tell Auth0 to route the logout there as well:
    → In your MAUI Auth0ClientOptions , set PostLogoutRedirectUri = "https://yourdomain.com/callback"
    ->The OIDC client will simply drop the local session and close the browser when it hits this URL, regardless of whether it was a login or logout.

  • If you unify the URLs and iOS still ignores the Universal Link on logout, you have hit the WebKit 302 redirect bug.

  • To bypass this, you must stop Auth0 from directly redirecting to your Universal Link. Instead, have Auth0’s returnTo parameter point to a standard, static HTML page hosted on your website (e.g., https://yourdomain.com/logout-success.html ).
    On that HTML page, include a tiny snippet of JavaScript:

<!DOCTYPE html>
<html>
<head><title>Logging out...</title></head>
<body>
  <p>Returning to app...</p>
  <script>
    window.location.href = "https://yourdomain.com/callback";
  </script>
</body>
</html>

  • When Auth0 logs the user out, it safely redirects to this webpage. The webpage loads, the JavaScript executes, and iOS instantly recognizes the Universal Link, triggering your ContinueUserActivity breakpoint and closing the browser.

If the above does not fix the issue, let me know and I will dig deeper into the iOS MAUI implementation!

Kind Regards,
Nik

@nik.baleca Hi, I couldn’t find anything related to Microsoft.Maui.Authentication.WebAuthenticationCallbackManager.Authenticate(url), also if ContinueUserActivity is never hit on logout, I think this will never be useful. On the other hand, my RedirectUri and PostLogoutRedirectUri were always the same. I’ve also tried the html hack, but the browser remains on /callback

Hi Nic, there is no WebAuthenticationCallbackManager in Microsoft.Maui.Authentication.

The RedirectUri and PostLogoutRedirectUri are the same.

I will not be able to test for the webkit redirect bug until tuesday. I assume the returnTo parameter is set by setting the PostLogoutRedirectUri in the wrapper client Auth0ClientOptions.

Kind regards, Ed

For completeness I just did the check with the static html page, redirecting to the logout url. I set the postLogoutRedirectUri to that page url, and added that page url to the allowed logout urls.
This all made no difference. After logging in the browser stays open (saying ‘not found‘) without returning to the app.

Hi again.

I am sorry for the delayed response, I was still investigating the matter.

Could you let me know how did you AppDelegate file was looking like before attempting to transition to the claimed HTTPS URIs?

WAs it anything similar to what our documentation and sample applications provide?

using Auth0.OidcClient;
using Foundation;
using UIKit;

[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
    private Auth0Client auth0Client;

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        // Initialize Auth0 client
        auth0Client = new Auth0Client(new Auth0ClientOptions
        {
            Domain = "{yourDomain}",
            ClientId = "{yourClientId}"
        });

        return true;
    }

    public override bool OpenUrl(UIApplication application, NSUrl url,
        string sourceApplication, NSObject annotation)
    {
        ActivityMediator.Instance.Send(url.AbsoluteString);
        return true;
    }
}

OR

using Auth0.OidcClient;
using Foundation;
using UIKit;

namespace iOSTestApp
{
    [Register("AppDelegate")]
    public class AppDelegate : UIApplicationDelegate
    {
        public override UIWindow Window
        {
            get;
            set;
        }

        public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
        {
            ActivityMediator.Instance.Send(url.AbsoluteString);
            return true;
        }
    }
}

For some referenced, you can visit:

Going back to the issue, it appears that the functions I have mentioned above are quite deprecated. After some investigation in regards to the Microsoft MAUI documentation, could you try using WebAuthenticator.Default OR WebAuthenticator.AuthenticateAsync( {{URL}}, {{CALLBACK_URL}} and let me know if you notice any change in behaviour?

As @Ed156 has mentioned regarding his opened ticket, this might be a limitation of the MAUI SDK not supporting claimed HTTPS URIs at this time and it should be under investigation. Whenever an update is given regarding the matter, I will let you know under this thread!

Looking forward to your replies.

Kind Regards,
Nik

Hi @nik.baleca ,

There was only protected override MauiApp CreateMauiApp() in AppDelegate.

I’ve also tried with WebAuthenticator.AuthenticateAsync( {{URL}}, {{CALLBACK_URL}} and there is no difference.

Thank you!

Hi Nic,

Note that Maui app ‘s iOS AppDelegate inherits from MauiUIApplicationDelegate, not UIApplicationDelegate. This below is from a recent Maui template made with VS2026, and is also the base of my code.

using Foundation;

namespace MauiApp1
{
[Register(“AppDelegate”)]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
}

Kind regards, Ed