Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception: Failure to parse missing json on first login #1052

Closed
1 of 7 tasks
rickykaare opened this issue Apr 9, 2019 · 3 comments
Closed
1 of 7 tasks

Exception: Failure to parse missing json on first login #1052

rickykaare opened this issue Apr 9, 2019 · 3 comments
Assignees
Milestone

Comments

@rickykaare
Copy link

Which Version of MSAL are you using ?
MSAL 3.0.3-preview

Platform
Xamarin Android and Xamarin iOS

What authentication flow has the issue?

  • Desktop / Mobile
    • Interactive
    • Integrated Windows Auth
    • Username Password
    • Device code flow (browserless)
  • Web App
    • Authorization code
    • OBO
  • Web API
    • OBO

Other? - please describe;

Is this a new or existing app?
a. The app is in production, and I have upgraded to a new version of MSAL

Production app is based on 2.7.1, but the issue was introduced when upgrading from 3.0.1-preview

Repro

ClientApplication = PublicClientApplicationBuilder
    .Create(ClientId)
    .WithB2CAuthority(SignInAuthority)
    .WithRedirectUri($"msal{ClientId}://auth")
    .WithIosKeychainSecurityGroup("com.nilfisk.msalcache")
    .WithLogging((level, msg, pii) => Trace.WriteLine($"{level}: {msg}"),
        logLevel: LogLevel.Verbose,
        enablePiiLogging: true,
        enableDefaultPlatformLogging: true)
    .Build();

//Login logic
ClientApplication
    .AcquireTokenInteractive(Scopes, Parent)
    .WithUseEmbeddedWebView(true)
    .WithPrompt(Prompt.ForceLogin)
    .ExecuteAsync();

//Getting current token when needed
var account = await GetAccountAsync();
ClientApplication
    .AcquireTokenSilent(Scopes, account)
    .WithForceRefresh(forceRefresh)
    .ExecuteAsync();

Expected behavior
After a successful login the AquireTokenSilent should return the current access token.

Actual behavior
After a clean installation of the app, the first time the AquireTokenSilent is called it fails on both Android and iOS.

On Android we get the following exception thrown:

Error: (True) MSAL 3.0.3.0 MSAL.Xamarin.Android 28 [04/09/2019 12:17:04 - e7196397-35b5-4593-a65a-32cfd578a6be] System.ArgumentNullException: Value cannot be null.
Parameter name: s
  at System.IO.StringReader..ctor (System.String s) [0x00009] in <58604b4522f748968296166e317b04b4>:0 
  at (wrapper remoting-invoke-with-check) System.IO.StringReader..ctor(string)
  at Microsoft.Identity.Json.Linq.JObject.Parse (System.String json, Microsoft.Identity.Json.Linq.JsonLoadSettings settings) [0x00000] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 
  at Microsoft.Identity.Json.Linq.JObject.Parse (System.String json) [0x00000] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 
  at Microsoft.Identity.Client.Cache.Items.MsalRefreshTokenCacheItem.FromJsonString (System.String json) [0x00000] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 
  at Microsoft.Identity.Client.Platforms.Android.AndroidTokenCacheAccessor.GetRefreshToken (Microsoft.Identity.Client.Cache.Keys.MsalRefreshTokenCacheKey refreshTokenKey) [0x00012] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 
  at Microsoft.Identity.Client.TokenCache+<>c__DisplayClass55_0.<Microsoft.Identity.Client.ITokenCacheInternal.FindRefreshTokenAsync>b__1 (Microsoft.Identity.Client.Cache.Keys.MsalRefreshTokenCacheKey key) [0x00000] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 
  at System.Linq.Utilities+<>c__DisplayClass2_0`3[TSource,TMiddle,TResult].<CombineSelectors>b__0 (TSource x) [0x00012] in <ba85ba5122c3499483c4d8a7ac6f7e5a>:0 
  at System.Linq.Enumerable+SelectListIterator`2[TSource,TResult].MoveNext () [0x00048] in <ba85ba5122c3499483c4d8a7ac6f7e5a>:0 
  at System.Linq.Enumerable.TryGetFirst[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] predicate, System.Boolean& found) [0x0004f] in <ba85ba5122c3499483c4d8a7ac6f7e5a>:0 
  at System.Linq.Enumerable.FirstOrDefault[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] predicate) [0x00000] in <ba85ba5122c3499483c4d8a7ac6f7e5a>:0 
  at Microsoft.Identity.Client.TokenCache.Microsoft.Identity.Client.ITokenCacheInternal.FindRefreshTokenAsync (Microsoft.Identity.Client.Internal.Requests.AuthenticationRequestParameters requestParams, System.String familyId) [0x0022a] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 
  at Microsoft.Identity.Client.Internal.Requests.SilentRequest.FindRefreshTokenOrFailAsync () [0x00074] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 
  at Microsoft.Identity.Client.Internal.Requests.SilentRequest.ExecuteAsync (System.Threading.CancellationToken cancellationToken) [0x001bd] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 
  at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync (System.Threading.CancellationToken cancellationToken) [0x00163] in <376e2ef9d794423f9ade4ab6bfa1859a>:0 

On iOS we get the following exception:

Error: (True) MSAL 3.0.3.0 MSAL.Xamarin.iOS 12.2 [04/09/2019 12:21:02 - 5e787ccf-5791-42c5-bdac-00fd32094521] Microsoft.Identity.Json.JsonReaderException: Error reading JObject from JsonReader. Path '', line 0, position 0.
  at Microsoft.Identity.Json.Linq.JObject.Load (Microsoft.Identity.Json.JsonReader reader, Microsoft.Identity.Json.Linq.JsonLoadSettings settings) [0x00026] in <9660d4460f2c4014888898979d9b402a>:0 
  at Microsoft.Identity.Json.Linq.JObject.Parse (System.String json, Microsoft.Identity.Json.Linq.JsonLoadSettings settings) [0x0000c] in <9660d4460f2c4014888898979d9b402a>:0 
  at Microsoft.Identity.Json.Linq.JObject.Parse (System.String json) [0x00000] in <9660d4460f2c4014888898979d9b402a>:0 
  at Microsoft.Identity.Client.Cache.Items.MsalRefreshTokenCacheItem.FromJsonString (System.String json) [0x00000] in <9660d4460f2c4014888898979d9b402a>:0 
  at Microsoft.Identity.Client.Platforms.iOS.iOSTokenCacheAccessor.GetRefreshToken (Microsoft.Identity.Client.Cache.Keys.MsalRefreshTokenCacheKey refreshTokenKey) [0x00007] in <9660d4460f2c4014888898979d9b402a>:0 
  at Microsoft.Identity.Client.TokenCache+<>c__DisplayClass55_0.<Microsoft.Identity.Client.ITokenCacheInternal.FindRefreshTokenAsync>b__1 (Microsoft.Identity.Client.Cache.Keys.MsalRefreshTokenCacheKey key) [0x00000] in <9660d4460f2c4014888898979d9b402a>:0 
  at System.Linq.Utilities+<>c__DisplayClass2_0`3[TSource,TMiddle,TResult].<CombineSelectors>b__0 (TSource x) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.25/src/Xamarin.iOS/external/corefx/src/System.Linq/src/System/Linq/Utilities.cs:72 
  at System.Linq.Enumerable+SelectListIterator`2[TSource,TResult].MoveNext () [0x00036] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.25/src/Xamarin.iOS/external/corefx/src/System.Linq/src/System/Linq/Select.cs:349 
  at System.Linq.Enumerable.TryGetFirst[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] predicate, System.Boolean& found) [0x0004f] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.25/src/Xamarin.iOS/external/corefx/src/System.Linq/src/System/Linq/First.cs:92 
  at System.Linq.Enumerable.FirstOrDefault[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Func`2[T,TResult] predicate) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/12.6.0.25/src/Xamarin.iOS/external/corefx/src/System.Linq/src/System/Linq/First.cs:37 
  at Microsoft.Identity.Client.TokenCache.Microsoft.Identity.Client.ITokenCacheInternal.FindRefreshTokenAsync (Microsoft.Identity.Client.Internal.Requests.AuthenticationRequestParameters requestParams, System.String familyId) [0x0022a] in <9660d4460f2c4014888898979d9b402a>:0 
  at Microsoft.Identity.Client.Internal.Requests.SilentRequest.FindRefreshTokenOrFailAsync () [0x00074] in <9660d4460f2c4014888898979d9b402a>:0 
  at Microsoft.Identity.Client.Internal.Requests.SilentRequest.ExecuteAsync (System.Threading.CancellationToken cancellationToken) [0x001bd] in <9660d4460f2c4014888898979d9b402a>:0 
  at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync (System.Threading.CancellationToken cancellationToken) [0x00163] in <9660d4460f2c4014888898979d9b402a>:0 
Thread finished: <Thread Pool> #9

After this exception is thrown we perform a logout by executing the following code:

var accounts = await ClientApplication.GetAccountsAsync();
foreach (var account in accounts)
    await ClientApplication.RemoveAsync(account);

After user performs another login, everything seems to work again.

Possible Solution

Additional context/ Logs / Screenshots
Add any other context about the problem here, such as logs and screebshots. Logging is described at https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/logging

@jmprieur
Copy link
Contributor

jmprieur commented Apr 9, 2019

@rickykaare
Do I understand that you migrated your app from MSAL 2.x to 3.0.3-preview ?

For .NET Framework and .NET desktop, if that's the case and you want to keep your token cache, you 'd want to do a one-time migration:
https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/MSAL.NET-3-released#example-of-code-showing-how-to-migrate-from-msalnet-v2-to-msalnet-v3

try
 {
  args.TokenCache.DeserializeMsalV3(serializedData);
 }
 catch (MsalUnexpectedCacheFormatException)
 {
  args.TokenCache.DeserializeMsalV2(serializedData);
 }

but here this is Xamarin apparently, so the token cache serialization is not customizable.

@jennyf19 @trwalke @bgavrilMS @MarkZuber

@jmprieur jmprieur added this to the 3.0.4 milestone Apr 9, 2019
@rickykaare
Copy link
Author

Thanks for the feedback @jmprieur!
It might make sense for us to take a look at the migration code you shared to avoid our users logging in again once we put the new MSAL v3 app to production.

However, I don't think it makes a difference for the issue posted here, as we experience this error on completely fresh installations of our app using the v3.0.3-preview.

It looks to me like there is a missing null check when getting the refresh token.

@MarkZuber
Copy link
Contributor

#1060

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

No branches or pull requests

5 participants