dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.22k stars 1.76k forks source link

[WebAuthenticator] [Android 14] The redirection does not work after authentication #24904

Closed jbm-sg closed 1 month ago

jbm-sg commented 1 month ago

Description

I'm integrating a custom enterprise OAuth2 SSO. The SSO URL is, for example: https://sso.entreprise.com/redirectTo=https://api.prestataire.com/oauthredirect/ The redirection URL is: https://api.prestataire.com/oauthredirect/ I've followed the Microsoft documentation: https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/communication/authentication?view=net-maui-8.0&tabs=android My WebAuthenticatorCallbackActivity class:

[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter([AndroidContentIntent.ActionView],
              Categories = [AndroidContentIntent.CategoryDefault, AndroidContentIntent.CategoryBrowsable],
              DataScheme = MyAppDataScheme, DataHost = MyAppDataHost, DataPath = MyAppDataPath)]
public sealed class WebAuthenticationCallbackActivity : WebAuthenticatorCallbackActivity
{
    private const string MyAppDataScheme = "https";
    private const string MyAppDataHost = "api.prestataire.com";
    private const string MyAppDataPath = "/oauthredirect/";
}

My AndroidManifest.xml :

<?xml version=‘1.0’ encoding=‘utf-8’?>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
  <!--Use for web authentication, see docs : https://learn.microsoft.com/en-us/dotnet/maui/platform-integration/communication/authentication-->
  <queries>
    <intent>
      <action android:name="android.support.customtabs.action.CustomTabsService" />
    </intent>
  </queries>
</manifest>

My function that triggers authentication :

private static Func<myEntrepriseSso, Task<string>> LaunchWebAuthenticator()
{
    return async (myEntrepriseSso) =>
    {
        WebAuthenticatorOptions options = new()
        {
            Url = myEntrepriseSso.Url,
            CallbackUrl = myEntrepriseSso.RedirectUrl,
            PrefersEphemeralWebBrowserSession = true
        };
        WebAuthenticatorResult authenticatorResult = await WebAuthenticator.Default.AuthenticateAsync(options);
        if (authenticatorResult.Properties.TryGetValue(SsoParameterKey.Code, out string? code))
        {
            return code ?? string.Empty;
        }
        return string.Empty;
    };
}

Authentication works great on Android 11 but on Android 14 it doesn't.

In-app step:

Have I forgotten something in the authentication configuration?

Steps to Reproduce

No response

Link to public reproduction project repository

No response

Version with bug

8.0.3 GA

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

Android, I was not able test on other platforms

Affected platform versions

android 34.0.113/8.0.100 VS 17.11.35312.102

Did you find any workaround?

No

Relevant log output

dotnet workload list :

Bienvenue dans .NET 8.0 !
---------------------
Version du kit SDK : 8.0.400

--------------------------------------------------------------------------------------
ID de la charge de travail installée      Version de manifeste      Source de l’installation
--------------------------------------------------------------------------------------------
maui-windows                              8.0.82/8.0.100            VS 17.11.35312.102
maccatalyst                               17.5.8030/8.0.100         VS 17.11.35312.102
ios                                       17.5.8030/8.0.100         VS 17.11.35312.102
android                                   34.0.113/8.0.100          VS 17.11.35312.102
aspire                                    8.1.0/8.0.100             VS 17.11.35312.102
github-actions[bot] commented 1 month ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

jbm-sg commented 1 month ago

A small additional detail: The redirect URL contains parameters, for example: https://api.prestataire.com/oauthredirect/?code=abcdef&ClientId=qwerty

En complément : There are no breakpoints in the OnCreate method on Android 14, unlike on Android 11 :

[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true)]
[IntentFilter([AndroidContentIntent.ActionView],
              Categories = [AndroidContentIntent.CategoryDefault, AndroidContentIntent.CategoryBrowsable],
              DataScheme = MyAppDataScheme, DataHost = MyAppDataHost, DataPath = MyAppDataPath)]
public sealed class WebAuthenticationCallbackActivity : WebAuthenticatorCallbackActivity
{
    private const string MyAppDataScheme = "https";
    private const string MyAppDataHost = "api.prestataire.com";
    private const string MyAppDataPath = "/oauthredirect/";

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

        var uri = Intent.Data;
        if (uri != null)
        {
            Console.WriteLine($"===== DEBUG - Redirect URI: {uri}");
        }
    }
}
Redth commented 1 month ago

There's a lot of details that could affect this working properly. While your description is great, we really need a sample project that reproduces the issue to effectively help identify the problem.

Thanks!

jbm-sg commented 1 month ago

Hi! Unfortunately this is a business project. I can't share the sources. I will try to reproduce the bug with an alternative to enterprise SSO. Thanks @Redth for your reply!

I will update the issue as soon as possible with the project.

jbm-sg commented 1 month ago

Until I find an anonymised project, here are a few additions: when I run the command : adb shell am start -W -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d https://api.prestataire.com/oauthredirect/

On Android 11, the system suggests opening the link with Google Chrome or my application.

On Android 14, the system opens the browser directly.

Microsoft docs : https://learn.microsoft.com/en-us/dotnet/maui/android/app-links?view=net-maui-8.0#test-an-app-link

jbm-sg commented 1 month ago

Another possibility is that my environment is missing the App Link check: https://developer.android.com/training/app-links/verify-android-applinks

jbm-sg commented 1 month ago

OK, I think I found the problem. It was about the App Link configuration. My setup is fine, but as long as the JSON isn't on my server and it's not approved by Google, the redirect won't work.

The workaround is to go to App Info > Open by default > Add Link then select my URL.

I will confirm after the JSON is on my server and Google has approved my app.

Thank you!

Redth commented 1 month ago

Ahh yes, good finding, you definitely cannot handle intent filters with http/https based urls unless you have done the work to prove ownership of the pattern with google, otherwise anyone could pretend to be the app for your domain and handle the callbacks.

Appreciate the detailed info and follow up on the fix, thanks!