Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Android 12 issue - Xamarin.Auth.AuthenticatorCompletedEventArgs return null account object and IsAuthenticated flag false #462

Open
3 tasks
jhaprasun opened this issue Mar 7, 2022 · 9 comments

Comments

@jhaprasun
Copy link

jhaprasun commented Mar 7, 2022

Xamarin.Auth Issue

In Android 12 OS devices, after successful login and allowed google drive consent our callback account object is null and IsAuthenticated flag is false. Though it is working fine for Android version below 12. For us this issue is a release blocker. Let us know if there is any workaround. Many thanks in advance.

Version

  • nuget version = Xamarin.Auth (1.7.0)
  • component version =
  • sample

Steps to reproduce

void IGoogleOAuthSignIn.ShowGoogleAuthSignInPage()
{
CloudSettings.Authenticator = new OAuth2Authenticator(
clientId: Constants.ClientId,
clientSecret: string.Empty,
scope: this.DriveService.Scope.Drive + " " + DriveService.Scope.DriveAppdata + " " + "https://www.googleapis.com/auth/userinfo.email",
authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/auth"),
redirectUrl: new Uri("com.xx.xxxxxx:/oauth2redirect"),
accessTokenUrl: new Uri("https://www.googleapis.com/oauth2/v4/token"),
isUsingNativeUI: true);

        CloudSettings.Authenticator.Completed += this.OnOAuthCompleted;
        CloudSettings.Authenticator.Error += this.OnOAuthError;
        Intent intent = CloudSettings.Authenticator.GetUI(CurrentActivity);
        intent.SetFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop);
        CurrentActivity.StartActivity(intent);

}
2.
private void OnOAuthCompleted(object sender, AuthenticatorCompletedEventArgs eventArgs)
{
if (CloudSettings.Authenticator != null)
{
CloudSettings.Authenticator.Completed -= this.OnOAuthCompleted;
CloudSettings.Authenticator.Error -= this.OnOAuthError;
}

        if (eventArgs.IsAuthenticated)
        {
            if (CloudSettings.IsCalledFromSettingsPage)
            {
                MessagingCenter.Send<object>(false, Constants.FinishButtonVisible);
            }
            else
            {
                MessagingCenter.Send<object, bool>(this, Constants.DisplayActivityIndicator, true);
            }

            this.GetLoggedInUserData(eventArgs);
        }
        else
        {
            MessagingCenter.Send<object>(false, Constants.DisableBackupToggle);
            AppCenterHelper.LogEvent("Error: OAuth Sign-In", "OAuthSignIn.OnOAuthCompleted", "Authentication failed.");
        }
    }

Platform:

  • [] .NET version = Visual Studio for Mac Professional (8.10.19(build 2))
  • [] mono version = Mono 6.12.0.162

Expected behaviour

Account object shouldn't be null and IsAuthenticated should be true

Tell us what should happen

Actual behaviour

Account object is null and IsAuthenticated flag is false

Tell us what happens instead
Can you also include a screen shot?
Correct behavior with ANDROID version below 10
InCorrectbehaviourWith ANDROID-12

IF IT IS A NEW FEATURE REQUEST, INCLUDE THIS PART:

Feature description

Write a description of the feature. How should it work? How should it look?
Include some graphics if this could help!

@jhaprasun jhaprasun changed the title Xamarin.Auth.AuthenticatorCompletedEventArgs return null account object and IsAuthenticated flag false for Android12 Android 12 issue - Xamarin.Auth.AuthenticatorCompletedEventArgs return null account object and IsAuthenticated flag false Mar 7, 2022
@jhaprasun
Copy link
Author

Any workaround for above mentioned issue?

@cristiproj
Copy link

I am interested in this as well. @jhaprasun Have you found a workaround?

@jhaprasun
Copy link
Author

Not yet... waiting for fix

@tolyg
Copy link

tolyg commented Apr 11, 2022

I'm waiting for fix too.
It may be related to this issue and fix

@jhaprasun
Copy link
Author

Not really. Here callback account object is null and IsAuthenticated flag is false

@michaelstonis
Copy link

I found a workaround that is good enough.

You may have an activity that has an IntentFilter on it to listen for some custom DataScheme that functions as a listener for the OAuth result. Grab the attribute from that class and copy it to your MainActivity or whatever you use as the main activity entry point to your app.

image

In your main activity, update the Activity attribute and add LaunchMode = LaunchMode.SingleTask.

image

In your activity that had the IntentFilter originally, copy the code that is currently in the OnResume method. In your main activity, we will override the OnNewIntent(Intent intent) method, paste in the code. We need to remove any code around managing activities and just want to keep the pieces related to OAuth. The code should look something like the below example. The way that you are resolving the page variable is very likely different though, so just do whatever you are doing today to get the object, so you can call into OnPageLoading.

image

At this point, comment out or delete the other activity that originally had the IntentFilter on it.

Open the Properties/AndroidManifest.xml file using a text editor. Inside the manifest attribute, make sure you have the following queries element.

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
	...
	<queries>
		<!-- Required for API Level 30 to make sure we can detect browsers
        (that don't support custom tabs) -->
		<intent>
			<action android:name="android.intent.action.VIEW" />
			<category android:name="android.intent.category.BROWSABLE" />
			<data android:scheme="https" />
		</intent>
		<!-- Required for API Level 30 to make sure we can detect browsers that support custom tabs -->
		<!-- https://developers.google.com/web/updates/2020/07/custom-tabs-android-11#detecting_browsers_that_support_custom_tabs -->
		<intent>
			<action android:name="android.support.customtabs.action.CustomTabsService" />
		</intent>
	</queries>
</manifest>

That should do it for you.

Basically, what is happening on Android 12 is that you are leaving your application, then starting up everything fresh again and it is losing the context that it needs. This should continue to work on older versions, but I haven't thoroughly tested it.

@mwisnicki0
Copy link

@michaelstonis thanks man, just tested it in own app and working very well

@jhaprasun
Copy link
Author

I followed all the steps mentioned for resolution but its not working for me and getting an error- "Error Authenticating - Invalid grant"

@michaelstonis
Copy link

I followed all the steps mentioned for resolution but its not working for me and getting an error- "Error Authenticating - Invalid grant"

This is almost certainly to do with the OAuth endpoint. It could be that you are requesting access for an invalid user or permissions that are not available or one of a lot of other things. If you are getting that response though, you are at least further along as you would not have any values before.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants