auth0 / auth0-oidc-client-net

OIDC Client for .NET Desktop and Mobile applications
https://auth0.github.io/auth0-oidc-client-net/
Apache License 2.0
86 stars 49 forks source link

JsonSerializationException in .Net 7 for iOS Project #298

Open justinwojo opened 1 year ago

justinwojo commented 1 year ago

Checklist

Description

In a .Net 7 for iOS project during a standard browser login flow, after logging in successfully in the browser, an exception is thrown from the Auth0 LoginAsync method. This only happens on iOS, and doesn't happen on Android with the same Core library version (3.4.1).

Versions of SDKs: OidcClient.Core: 3.4.1 OidcClient.AndroidX: 3.5.0 OidcClient.iOS: 3.6.0

Full stack trace below:

System.InvalidOperationException: IDX20803: Unable to obtain configuration from: 'System.String'. ---> Microsoft.IdentityModel.Json.JsonSerializationException: Error setting value in extension data for type 'Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration'. Path 'device_authorization_endpoint', line 1, position 264. ---> System.ExecutionEngineException: Attempting to JIT compile method '(wrapper delegate-invoke) System.Collections.Generic.IDictionary2<string, object> :invoke_callvirt_IDictionary`2<string, object>_OpenIdConnectConfiguration (Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.

at System.Linq.Expressions.Interpreter.FuncCallInstruction2[[Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration, Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=6.12.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[System.Collections.Generic.IDictionary2[[System.String, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Object, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Run(InterpretedFrame ) at System.Linq.Expressions.Interpreter.Interpreter.Run(InterpretedFrame ) at System.Linq.Expressions.Interpreter.LightLambda.Run(Object[] ) at System.Dynamic.Utils.DelegateHelpers.FuncThunk1[Object,Object](Func2 handler, Object t1) at Microsoft.IdentityModel.Json.Serialization.DefaultContractResolver.<>c__DisplayClass44_1.<SetExtensionDataDelegates>b__0(Object o, String key, Object value) at Microsoft.IdentityModel.Json.Serialization.JsonSerializerInternalReader.SetExtensionData(JsonObjectContract contract, JsonProperty member, JsonReader reader, String memberName, Object o) --- End of inner exception stack trace --- at Microsoft.IdentityModel.Json.Serialization.JsonSerializerInternalReader.SetExtensionData(JsonObjectContract contract, JsonProperty member, JsonReader reader, String memberName, Object o) at Microsoft.IdentityModel.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Microsoft.IdentityModel.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Microsoft.IdentityModel.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Microsoft.IdentityModel.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Microsoft.IdentityModel.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Microsoft.IdentityModel.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) at Microsoft.IdentityModel.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) at Microsoft.IdentityModel.Json.JsonConvert.DeserializeObject[OpenIdConnectConfiguration](String value, JsonSerializerSettings settings) at Microsoft.IdentityModel.Json.JsonConvert.DeserializeObject[OpenIdConnectConfiguration](String value) at Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfigurationRetriever.GetAsync(String address, IDocumentRetriever retriever, CancellationToken cancel) at Microsoft.IdentityModel.Protocols.ConfigurationManager1.d26[[Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration, Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=6.12.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]].MoveNext() --- End of inner exception stack trace --- at Microsoft.IdentityModel.Protocols.ConfigurationManager`1.d26[[Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration, Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=6.12.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]].MoveNext() at Microsoft.IdentityModel.Protocols.ConfigurationManager1.<GetConfigurationAsync>d__25[[Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectConfiguration, Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=6.12.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]].MoveNext() at Auth0.OidcClient.Tokens.JsonWebKeys.GetForIssuer(String issuer) at Auth0.OidcClient.Tokens.AsymmetricSignatureVerifier.ForJwks(String issuer) at Auth0.OidcClient.Tokens.IdTokenValidator.AssertTokenMeetsRequirements(IdTokenRequirements required, String rawIDToken, Nullable1 pointInTime, ISignatureVerifier signatureVerifier) at Auth0.OidcClient.Auth0ClientBase.LoginAsync(Object extraParameters, CancellationToken cancellationToken)`

WORKAROUND

We did find a workaround by forcing the transitive dependency of Microsoft.IdentityModel.Protocols.OpenIdConnect to the latest version (7.0.3 as of this post). This fixed the exception and allowed us to log in fine on iOS.

Reproduction

  1. Create a .Net 7 for iOS project (this likely would happen with a MAUI project as well, but haven't validated that)
  2. Setup the Auth0Client as normal in the iOS project, setting a Domain, ClientId, and Scope.
  3. Utilize the IAuth0Client interface from the created Auth0Client to call the LoginAsync() method, passing in any relevant parameters and a cancellation Token.
  4. Login to your Auth0 tenant inside the browser shown by the Auth0 SDK. Should look like: var loginResult = await _auth0Client.LoginAsync(extraParameters, cancellationToken);
  5. Either wrap that call in a try/catch to see the exception, or it'll crash the app if it's not in a try/catch, in which you'll be able to see the exception provided in the description.

Additional context

No response

auth0-oidc-client-net version

3.4.1

.NET version

7

Platform

iOS

Platform version(s)

3.6.0

frederikprijck commented 1 year ago

Thanks for reporting, i can see how that can cause issues and how pinning to that version solves it.

Will look into it and see if we can provide a fix. Good to Know you have a workaround for the time being!

Blinchik91 commented 6 months ago

Thanks for reporting, i can see how that can cause issues and how pinning to that version solves it.

Will look into it and see if we can provide a fix. Good to Know you have a workaround for the time being!

same problem after Login here but with Android (13 API 33 .net 8) with example https://github.com/auth0-blog/dotnet-maui-auth0-app

System.InvalidOperationException Message=IDX20803: Unable to obtain configuration from: 'System.String'.

    0xFFFFFFFFFFFFFFFF in Android.Runtime.RuntimeNativeMethods.monodroid_debugger_unhandled_exception   C#
    0x1A in Android.Runtime.JNINativeWrapper._unhandled_exception at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:13,5 C#
    0x1D in Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:27,26    C#
    0x17 in System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw    C#
    0x6 in System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0 C#
    0xC in Android.App.SyncContext. at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36,19 C#
    0xE in Java.Lang.Thread.RunnableImplementor.Run at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36,6 C#
    0x8 in Java.Lang.IRunnableInvoker.n_Run at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Java.Lang.IRunnable.cs:84,4    C#
    0x8 in Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:26,5  C#
SuperCorks commented 3 months ago

Would love if you guys could fix this for .net maui.

AliKarimiENT commented 3 months ago

@SuperCorks Hello How do you launch the login web page on iOS? I have set everything but when I call the LoginAsync method nothing happens. I have also added <key>CFBundleURLTypes</key> with its details to the info.plists. I have two info.plist one for DEV and one for PROD. My payment redirection is working but this authentication process doesn't on iOS whether worked on android.

My project is based on .NET8 and I have used this version <PackageReference Include="Auth0.OidcClient.MAUI" Version="1.0.1" />