microsoft-authentication-library-for-dotnet icon indicating copy to clipboard operation
microsoft-authentication-library-for-dotnet copied to clipboard

Handle null intent in SetAuthenticationContinuationEventArgs (MSAL 2.1.0)

Open nhsimarsden opened this issue 6 years ago • 25 comments

Is your feature request related to a problem? Please describe. SetAuthenticationContinuationEventArgs is the method used in when implementing MSAL for Xamarin Andorid, which handles the return from an interactive sign-in. It takes three arguments, requestCode (int), resultCode (Result) and data (Intent).

I am working with Xamarin.Forms and experiencing an issue on Android where the user triggers interactive sign-in (PublicClientApplication.AcquireTokenAsync), taps the home button, then launches the app again from the apps menu (rather than resuming from the overview). This results in the Intent being null and thus SetAuthenticationContinuationEventArgs fails.

Consider the example provided in the wiki:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode, resultCode, data);
}

Following the described steps, data will be null and, if unhandled, the app will crash.

Describe the solution you'd like It would be good to have MSAL throw an MsalException (or variant) so that I can handle this scenario gracefully within my sign in logic flow.

Describe alternatives you've considered Right now I am checking for a null intent within MainActivity.OnActivityResult and simply not calling SetAuthenticationContinuationEventArgs.

Additional context Steps to reproduce the scenario:

  1. Launch app and start interactive signin (where the browser is shown)
  2. Tap the device home button
  3. Open the apps menu and open the app from the menu

nhsimarsden avatar Oct 12 '18 14:10 nhsimarsden

Rather than not calling SetAuthenticationContinuationEventArgs, another workaround is to create a dummy intent:

if (data == null)
{
    data = new Intent("ReturnFromEmbeddedWebview");
}

This is better than not calling SetAuthenticationContinuationEventArgs (which is breaking my sign-in logic). The only problem I can see here is that the interaction doesn't continue (for example, a B2C password reset which requires the user to enter a verification code that they receive via email).

nhsimarsden avatar Oct 12 '18 15:10 nhsimarsden

@nhsimarsden - When you say that the app crashes when the intent is null, do you mean that MSAL throws a null reference exception or some other exception that causes the app to crash? If that is the case, then we should treat this as a bug.

bgavrilMS avatar Oct 19 '18 08:10 bgavrilMS

@bgavrilMS - Yes, you are correct. Below is the crash detail I pulled from App Center which led me to discover this issue:

System.NullReferenceException: Object reference not set to an instance of an object
  at Microsoft.Identity.Client.AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data) [0x00043] in <cab90e5acfec49d3967e0c2b916afc82>:0
  at MyApp.Droid.MainActivity.OnActivityResult (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data) [0x00009] in <37116bf06c794465b4f43f38136adf39>:0
  at Android.App.Activity.n_OnActivityResult_IILandroid_content_Intent_ (System.IntPtr jnienv, System.IntPtr native__this, System.Int32 requestCode, System.Int32 native_resultCode, System.IntPtr native_data) [0x00014] in <f31a0642206a4c38a61a3a5fda304db6>:0
  at (wrapper dynamic-method) System.Object.6(intptr,intptr,int,int,intptr)

nhsimarsden avatar Oct 19 '18 09:10 nhsimarsden

@bgavrilMS - any update on this one? I too am seeing these errors in App Center and Play Console.

WilliamWatterson86 avatar Feb 18 '19 11:02 WilliamWatterson86

@jennyf19 and @trwalke, FYI

jmprieur avatar Feb 18 '19 13:02 jmprieur

Any update on this one?

WilliamWatterson86 avatar May 07 '19 13:05 WilliamWatterson86

@WilliamWatterson86 Unfortunately no update. Will try to get a look at this asap.

jennyf19 avatar May 07 '19 22:05 jennyf19

Marking for 4.3. Validate if still relevant and explore options if it is.

henrik-me avatar Jul 23 '19 17:07 henrik-me

@nhsimarsden @WilliamWatterson86 Apologies for letting this issue slip through. :/ Can either of you confirm that this is still happening with the latest version of MSAL 4.2.1? I have not been able to reproduce it. Thanks so much.

jennyf19 avatar Jul 27 '19 09:07 jennyf19

@jennyf19 I haven’t seen it either, so looking good

WilliamWatterson86 avatar Jul 27 '19 16:07 WilliamWatterson86

@WilliamWatterson86 thanks for the quick reply.

@henrik-me I'll let you decide how to proceed on this.

jennyf19 avatar Jul 27 '19 20:07 jennyf19

Closing issue if it can't be reproduced. Please reopen if new information arises.

bgavrilMS avatar Jul 29 '19 08:07 bgavrilMS

@bgavrilMS @jennyf19

I am still getting this issue in app center.

I am using the latest version of the library 4.8.2

AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data)
MainActivity.OnActivityResult (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data)
Activity.n_OnActivityResult_IILandroid_content_Intent_ (System.IntPtr jnienv, System.IntPtr native__this, System.Int32 requestCode, System.Int32 native_resultCode, System.IntPtr native_data)
(wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.15(intptr,intptr,int,int,intptr)

soooraj avatar Feb 25 '20 08:02 soooraj

This is very easy to reproduce, repo attached: App1.zip

tipa avatar Mar 07 '20 13:03 tipa

Maybe add a try-catch-all in that method, it also throws other exceptions, like this one:

Java.Lang.RuntimeException: ClassNotFoundException when unmarshalling: com.google.android.apps.docs.cello.data.CelloEntrySpec

JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args)
JniPeerMembers+JniInstanceMethods.InvokeVirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
Intent.GetStringExtra (System.String name)
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data)
MainActivity.OnActivityResult (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data)

tipa avatar Mar 10 '20 20:03 tipa

We're seeing this issue for some users as well. Anyone know of a suitable work-around that doesn't break auth flow?

@bgavrilMS Any update on this by chance?

LanceKing-eLogic avatar Mar 13 '20 16:03 LanceKing-eLogic

@nhsimarsden Hey Ian, any chance you found a work-around for this that didn't break auth flow? I'm surprised this has gone under the MSAL team's radar this long.

LanceKing-eLogic avatar Mar 16 '20 15:03 LanceKing-eLogic

@nhsimarsden Hey Ian, any chance you found a work-around for this that didn't break auth flow? I'm surprised this has gone under the MSAL team's radar this long.

Try-catch the method call. When data contains data from the auth activity, it is not null and therefore shouldn't crash

tipa avatar Mar 16 '20 15:03 tipa

So a null check on data should be better than a trycatch. The problem is even worse when you start having other handlers (for other application logics) in the OnActivityResult. I'll try the null check workaround and wait for the fix.

nexxuno avatar Mar 30 '20 09:03 nexxuno

Raising to P1 as there are many people impacted by this.

bgavrilMS avatar May 05 '20 09:05 bgavrilMS

Looks like the broker can sometimes trigger this as well. We need to handle the null better.

bgavrilMS avatar May 14 '20 17:05 bgavrilMS

Also seeing this issue for quite a few users - we just pushed our app out to 2,500+ devices with a new MSAL auth flow and within minutes were getting these crash reports. Will handle the null for now, but it's not a very elegant solution for the long term!

mcrozier-ngn avatar May 29 '20 22:05 mcrozier-ngn

Current thinking on the solution for this to stop processing if intent is null, which I think some of the folks on this thread are doing now by catching the null ref?

Alternatively, we can throw an MSAL exception, but I am not sure there is enough information to make it a meaningful exception :(

bgavrilMS avatar Jun 09 '20 18:06 bgavrilMS

Resolved in 4.15

trwalke avatar Jun 18 '20 20:06 trwalke

This bug is still present in 4.39, at least the crash I reported here.

Maybe add a try-catch-all in that method, it also throws other exceptions, like this one:

Java.Lang.RuntimeException: ClassNotFoundException when unmarshalling: com.google.android.apps.docs.cello.data.CelloEntrySpec

JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args)
JniPeerMembers+JniInstanceMethods.InvokeVirtualObjectMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters)
Intent.GetStringExtra (System.String name)
AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data)
MainActivity.OnActivityResult (System.Int32 requestCode, Android.App.Result resultCode, Android.Content.Intent data)

A similar crash is:

Android.OS.BadParcelableException: 'ClassNotFoundException when unmarshalling: com.google.android.apps.docs.common.drivecore.data.CelloEntrySpec'

It happens after sharing content to the Google Drive app and then returning back to my app.

tipa avatar Jan 01 '22 16:01 tipa

Won't fix Xamarin issue. Please reopen if it happens on Maui.

bgavrilMS avatar Dec 22 '22 14:12 bgavrilMS