Multiple user accounts implementation

603
2
Jump to solution
05-18-2020 04:36 AM
SerhiiKyrylenko
New Contributor III

Hi,

Let's assume the application need to store multiple user accounts and to be able to switch between them without re-login. Just like in any Mail app, etc. What is the best approach for achieving this?

To be specific: users should be logged in using OAuth mechanism via Authentication Manager (AGSAuthenticationManager). In order to store and use multiple users credentials in the keychain, I'm using enableAutoSyncToKeychain(withIdentifier: , accessGroup:, acrossDevices:) method call with unique keychain identifier for each user. It works fine but with limitations to switch between stored user credentials.

While switching between accounts, calling AGSAuthenticationManager.shared().credentialCache.disableAutoSyncToKeychain() and than AGSAuthenticationManager.shared().credentialCache.enableAutoSyncToKeychain() with a keychain identifier for new user doesn't perform the trick and mess things up.

Also, setting the portal.credential to nil doesn't help. The application still have access to the user specific data. Looks like credentials in some way cached in the RAM. So the only way to actually switch between stored user credentials I've found so far, is to recreate the AGSPortal object from scratch and to call .enableAutoSyncToKeychain() with new identifier after.

To summarise: is it possible to switch between user/credentials_in_keychain without recreating AGSPortal object? Or what is the suggested way of achieving work with multiple accounts using SDK?

Thanks.

0 Kudos
1 Solution

Accepted Solutions
NimeshJarecha
Esri Regular Contributor

When you call `AGSAuthenticationManager.shared().credentialCache.enableAutoSyncToKeychain`, the in-memory AGSAuthenticationManager.shared().credentialCache is being stored in the Keychain with unique identifier. When you call AGSAuthenticationManager.shared().credentialCache.disableAutoSyncToKeychain() it just breaks the link between in-memory credentialCache and entry in the Keychain but in-memory credentialCache is still there. The steps to successfully achieve what you want are,

1. AGSAuthenticationManager.shared().credentialCache.disableAutoSyncToKeychain() 

2. AGSAuthenticationManager.shared().credentialCache.removeAllCredentials()

3. Create new AGSPortal instance for the new user. This is important because, the portal.credential will be there as well as all portal has other properties and content specific to the user.

So when you want to switch user, you can call it is SignOut/LogOut and in that you do,

1. DisableAutoSyncToKeychain

2. RemoveAllCredentials

3. Set portal = nil

Hope this helps!

Regards,

Nimesh

View solution in original post

2 Replies
NimeshJarecha
Esri Regular Contributor

When you call `AGSAuthenticationManager.shared().credentialCache.enableAutoSyncToKeychain`, the in-memory AGSAuthenticationManager.shared().credentialCache is being stored in the Keychain with unique identifier. When you call AGSAuthenticationManager.shared().credentialCache.disableAutoSyncToKeychain() it just breaks the link between in-memory credentialCache and entry in the Keychain but in-memory credentialCache is still there. The steps to successfully achieve what you want are,

1. AGSAuthenticationManager.shared().credentialCache.disableAutoSyncToKeychain() 

2. AGSAuthenticationManager.shared().credentialCache.removeAllCredentials()

3. Create new AGSPortal instance for the new user. This is important because, the portal.credential will be there as well as all portal has other properties and content specific to the user.

So when you want to switch user, you can call it is SignOut/LogOut and in that you do,

1. DisableAutoSyncToKeychain

2. RemoveAllCredentials

3. Set portal = nil

Hope this helps!

Regards,

Nimesh

SerhiiKyrylenko
New Contributor III

Thank you, Nimesh

With those inputs I'm able to achieve exactly what I need by following such steps:

  1. disableAutoSyncToKeychain()
  2. removeAllCredentials()
  3. portal.credential = nil

At least for my use case, it's not necessary to setting AGSPortal to nil. Now setting portal credentials to nil works, because in addition I've removed credentials from cache(missing step from my first approach)