From 97d65d79b3e5d519fea47239ab0e0d72beb6de00 Mon Sep 17 00:00:00 2001 From: Jonathan Dick Date: Fri, 26 May 2023 04:55:13 -0400 Subject: [PATCH] Fix Android WebAuth callback for system browser flows (#15187) * Fix Android WebAuth callback for system browser This adds a flag to track if the web authentication flow was launched via custom tabs or the fallback, system browser. We were assuming it was always via custom tabs, and so the intermediate activity would be started which is not necessary or designed to compatible with the flow using the system browser. This changes the callback activity to properly route back to the intermediate activity for custom tabs initialized flows, and to just call the OnResume callback for other flows (system browser). * Auto-format source code --------- Co-authored-by: GitHub Actions Autoformatter --- .../WebAuthenticator.android.cs | 8 +++++++- .../WebAuthenticator.shared.cs | 5 +++++ ...ebAuthenticatorCallbackActivity.android.cs | 20 ++++++++++++++----- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/Essentials/src/WebAuthenticator/WebAuthenticator.android.cs b/src/Essentials/src/WebAuthenticator/WebAuthenticator.android.cs index f66c15692180..48ca7384b329 100644 --- a/src/Essentials/src/WebAuthenticator/WebAuthenticator.android.cs +++ b/src/Essentials/src/WebAuthenticator/WebAuthenticator.android.cs @@ -13,6 +13,8 @@ partial class WebAuthenticatorImplementation : IWebAuthenticator, IPlatformWebAu Uri currentRedirectUri = null; WebAuthenticatorOptions currentOptions = null; + internal bool AuthenticatingWithCustomTabs { get; private set; } = false; + public bool OnResumeCallback(Intent intent) { // If we aren't waiting on a task, don't handle the url @@ -70,7 +72,11 @@ public async Task AuthenticateAsync(WebAuthenticatorOpti tcsResponse = new TaskCompletionSource(); currentRedirectUri = callbackUrl; - if (!(await StartCustomTabsActivity(url))) + // Try to start with custom tabs if the system supports it and we resolve it + AuthenticatingWithCustomTabs = await StartCustomTabsActivity(url); + + // Fall back to using the system browser if necessary + if (!AuthenticatingWithCustomTabs) { // Fall back to opening the system-registered browser if necessary var urlOriginalString = url.OriginalString; diff --git a/src/Essentials/src/WebAuthenticator/WebAuthenticator.shared.cs b/src/Essentials/src/WebAuthenticator/WebAuthenticator.shared.cs index b67a0f050231..2075cd6035a7 100644 --- a/src/Essentials/src/WebAuthenticator/WebAuthenticator.shared.cs +++ b/src/Essentials/src/WebAuthenticator/WebAuthenticator.shared.cs @@ -102,6 +102,11 @@ static IPlatformWebAuthenticatorCallback AsPlatformCallback(this IWebAuthenticat return platform; } +#if ANDROID + internal static bool IsAuthenticatingWithCustomTabs(this IWebAuthenticator webAuthenticator) + => (webAuthenticator as WebAuthenticatorImplementation)?.AuthenticatingWithCustomTabs ?? false; +#endif + /// /// Begin an authentication flow by navigating to the specified url and waiting for a callback/redirect to the callbackUrl scheme. /// diff --git a/src/Essentials/src/WebAuthenticator/WebAuthenticatorCallbackActivity.android.cs b/src/Essentials/src/WebAuthenticator/WebAuthenticatorCallbackActivity.android.cs index 62a9379b3567..c309c392bb29 100644 --- a/src/Essentials/src/WebAuthenticator/WebAuthenticatorCallbackActivity.android.cs +++ b/src/Essentials/src/WebAuthenticator/WebAuthenticatorCallbackActivity.android.cs @@ -10,11 +10,21 @@ protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); - // start the intermediate activity again with flags to close the custom tabs - var intent = new Intent(this, typeof(WebAuthenticatorIntermediateActivity)); - intent.SetData(Intent.Data); - intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop); - StartActivity(intent); + // Check how we launched the flow initially + if (WebAuthenticator.Default.IsAuthenticatingWithCustomTabs()) + { + // start the intermediate activity again with flags to close the custom tabs + var intent = new Intent(this, typeof(WebAuthenticatorIntermediateActivity)); + intent.SetData(Intent.Data); + intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop); + StartActivity(intent); + } + else + { + // No intermediate activity if we returned from a system browser + // intent since there's no custom tab instance to clean up + WebAuthenticator.Default.OnResume(Intent); + } // finish this activity Finish();