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

Unable To Clear Accounts: "Multiple accounts found in cache." #923

Closed
AnthonyUccello opened this issue May 5, 2020 · 15 comments
Closed
Assignees
Labels

Comments

@AnthonyUccello
Copy link

AnthonyUccello commented May 5, 2020

Hello

I have an app where 2 users logged in (on subsequent app launches). Now when I invoke application.getCurrentAccount I get the error:

Couldn't query current account with error: Err domain:MSALErrorDomain code:-50000 userInfo:{ MSALErrorDescriptionKey = "Multiple accounts found in cache."; MSALInternalErrorCodeKey = "-42102"; }

I figured the issue then was to clear the cache however there is no api on the cache config. My next idea was to get all accounts and sign out the users one by one. However, when I get the accounts object, it crashes when I try to inspect the array or access it in any fashion.

    func signOutAllAccounts()
    {
                guard let applicationContext = self.applicationContext else { return }
        
                let msalParameters = MSALAccountEnumerationParameters()
                msalParameters.completionBlockQueue = DispatchQueue.main
                    
                // TODO implement for multi
                applicationContext.accountsFromDevice(for: msalParameters)
                    { (accounts, error) in
        
                    if let error = error {
                        print("Couldn't query current account with error: \(error)")
                        return
                    }
                    
                    var acts:[MSALAccount] = accounts ?? [] 
                     // acts has 2 objects in it
                    var first = acts.first // crash on access
                }
    }

I tried to iterate the accounts but it says it fails to conform

Screen Shot 2020-05-05 at 1 16 13 PM

Even just printing the returned object fails:

Screen Shot 2020-05-05 at 1 27 40 PM

Can you advise what else I can do to either log out the accounts or clear the cache? I am unable to getCurrentAccount anymore so login always has to be done manually. (Also note I have cleared my safari cache and that didnt work either)

@rohitnarula7176
Copy link
Contributor

@AnthonyUccello Can you please specify whether you are trying to build a single account application or a multiple account application. Because the api getCurrentAccount is only intended for single account application. The crash you mentioned shouldn't happen if the accounts array is non-empty. Can you please paste the crash log as well.

@AnthonyUccello
Copy link
Author

AnthonyUccello commented May 6, 2020

I might not have the terminology right but I think the goal was a single but users could change. If single means one and only one user ever as the login per app instance then I would say ours was multiple in this case.

My solution to logout was to do an interactiveLogin() and do a logout call as soon as the login completed with the account. Using the accounts() would always crash. There is no log for this just the EXE Breakpoint and the Protocol non-compliance messages I showed in the screens.

To reproduce this issue I believe you can do it with the following:
-Login a user interactively (don't log them out and close the app)
-Restart the app, log in as a second user also interactively (close the app)
-Restart the app and try to login silently and you will now get the cache error.
-Now that you are getting the cache error try to get all accounts --- this will fail

@jasoncoolmax
Copy link
Member

@AnthonyUccello Could you please reproduce the issue and send us the logs? such that we could take a closer look.
Guidance of collecting the logs is here: https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-logging?tabs=objc#msal-for-ios-and-macos-logging-objc

Regarding whether we should return nil accounts when there is none in the cache, we created a bug here for tracking: #929

@AnthonyUccello
Copy link
Author

@jasoncoolmax Sorry I am no longer working on the project that was using this sdk. However the steps I outlined should reproduce the issue.

@antrix1989
Copy link
Contributor

Closing since we cannot reproduce this.

@sudeepngeorge
Copy link

sudeepngeorge commented Sep 15, 2020

I also get the exact issue as @AnthonyUccello , witth the same steps mentioned above.

//Pasting the same steps reported by AnthonyUccello
Login a user interactively (don't log them out and close the app)
-Restart the app, log in as a second user also interactively (close the app)
-Restart the app and try to login silently and you will now get the cache error.
-Now that you are getting the cache error try to get all accounts --- this will fail

Error I get
Couldn't query current account with error: Error Domain=MSALErrorDomain Code=-50000 "(null)" UserInfo={MSALErrorDescriptionKey=Multiple accounts found in cache., MSALInternalErrorCodeKey=-42102}

@sudeepngeorge
Copy link

@AnthonyUccello Were you able to solve this?

@locksleyu
Copy link

locksleyu commented Sep 16, 2020

I am seeing the same issue. I can't give repro steps since I don't know exactly what I did, and I don't know how to un-do things so I can figure out the steps to repro.

Error Domain=MSALErrorDomain Code=-50000 "(null)" UserInfo={MSALErrorDescriptionKey=Multiple accounts found in cache., MSALInternalErrorCodeKey=-42102}

How can I clear things out? I tried removing the account in MS Authenticator (and device unregister) and deleted that app (and my app) as well.

@oldalton oldalton reopened this Sep 19, 2020
@oldalton
Copy link
Member

Reopening the issue.

@NerevarineRule NerevarineRule self-assigned this Sep 22, 2020
@stale
Copy link

stale bot commented Oct 7, 2020

This issue has been automatically marked as stale because it has not had recent activity. Please provide additional information if requested. Thank you for your contributions.

@stale stale bot added the stale-issue label Oct 7, 2020
@NerevarineRule
Copy link
Contributor

NerevarineRule commented Oct 12, 2020

Hi @sudeepngeorge & @locksleyu,

thank you for helping to highlight the issue.

MSALPublicClientApplication actually has a public API that allows you to query multiple accounts, and I believe @AnthonyUccello did not use the correct API to do so. Let me provide you a sample code to do so in Obj-C, assuming that you already have multiple accounts in the cache.

  1. First import MSALSilentTokenParameters.h in addition to the other core public libraries that are required to use the public APIs.
  2. Create config, then use it to initialize an application object.
  3. Also initialize MSALAccountEnumerationParameters object.
  4. Then invoke the API "accountsFromDeviceForParameters" from the application object using the enumeration parameter
  5. If you have multiple accounts in MSAL cache, you will be able to retrieve them. each MSALAccount object has a parameter called "identifier" which represents the unique account identifier associated with each MSAL account instance. We recommend using it as the primary criterion to query the MSAL account you are looking for.
  6. Once the MSAL account is retrieved, invoke acquire token silent operation.

===================

//import other key libraries  
#import "MSALSilentTokenParameters.h" //Additionally, import this library 


MSALPublicClientApplicationConfig *config = [[MSALPublicClientApplicationConfig alloc] initWithClientId:clientId
                                                                                               redirectUri:redirectUri
                                                                                                 authority:authority];

MSALPublicClientApplication *application = [[MSALPublicClientApplication alloc] initWithConfiguration:config error:&error];   
MSALAccountEnumerationParameters *parameters = [MSALAccountEnumerationParameters new];
parameters.returnOnlySignedInAccounts = YES;

NSArray<NSString *> *scopeArr = [[NSArray alloc] initWithObjects: @"https://graph.microsoft.com/.default",nil];
//Now that you have an instance of MSALPublicClientApplication object, you can do the following:

if (@available(iOS 13.0, *)) //Currently, this public API requires iOS version 13 or greater.   
{
    [application accountsFromDeviceForParameters:parameters
                                 completionBlock:^(NSArray<MSALAccount *> * _Nullable accounts, __unused NSError * _Nullable error)
    {
        if (accounts)
        {
            for (MSALAccount *object in accounts)
            {
                if ([object.identifier isEqualToString:@"61cd1446-f9b4-403b-b137-1ffc975e0319.d34a1bb7-3481-4d5f-8b94-f3cc27bf8eac"])
                {
                    MSALSilentTokenParameters *tokenParameters = [[MSALSilentTokenParameters alloc] initWithScopes:scopeArr account:object];

                    [application acquireTokenSilentWithParameters:tokenParameters
                                    completionBlock:^(MSALResult * _Nullable result, NSError * _Nullable error)
                     {
                        if (error)
                        {
                            //Log Error
                        }
                        if (result)
                        {
                                //process result
                        }
                    }
                     ];
                }
            }
        }
 
    }];
}

@JontyMC
Copy link

JontyMC commented Nov 3, 2021

I also have this issue. I can't see how getCurrentAccount is ever viable to use, since as soon as multiple users login, this method will always throw an exception?

To be clear, I want to use single account mode (only ever one user logged in).

@ramon26cruz
Copy link

I also encounter the same issue? What is the fixed for multiple account found issue

@danielemden
Copy link

Removing all accounts from the cache works for me, see https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-java-get-remove-accounts-token-cache

@asad-mehmood-vendian
Copy link

here is help on this we Single Account mode and Multiple account mode. https://azuread.github.io/microsoft-authentication-library-for-objc/

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

No branches or pull requests