Aws-sdk-ios: AWSCognitoIdentityProvider: Unauthenticated identities

Created on 31 May 2016  路  26Comments  路  Source: aws-amplify/aws-sdk-ios

I'm trying to implement unauthenticated identities using the new Cognito User Pools. Here's my goal:

  • User first opens the app, they are unauthenticated and have an unauth identity id
  • After the user signs in using AWSCognitoIdentityProvider, I want the unauth identity to be converted to an auth identity
  • Authentication in my app is optional, only required for certain features

From what I can tell, unauth identities don't work with AWSCognitoIdentityProvider out-of-the-box. When I set my user pool as the identityProviderManager in my credentialsProvider, it complains that I don't have an authentication delegate set (remember I want an optional login to the app), and the attempt to get an identity id without logging in throws an error.

I've tried detecting whether the user is logged in or not, and using a default credentialsProvider to obtain an unauth identity id (which works), but when I do authenticate with AWSCognitoIdentityProvider, the unauth identity is not converted to an auth identity (no linked logins).

Is there a way to get unauth identities working in this way? Is it possible to manually convert an unauth identity to an auth? I can obtain the logins map from the user pool.

closing-soon-if-no-response cognito

All 26 comments

The way that you have set AWSCognitoIdentityProvider as the identityProviderManager on your credentialsProvider only works if you expect your users only be authenticated. If you want to support both authenticated and unauthenticated you need to create your own implementation of AWSIdentityProviderManager. When you want the user to be unauthenticated return an empty logins map, when you want them to be authenticated you can return the logins from AWSCognitoIdentityProvider. If you start out unauthenticated then the user signs up, call clearCredentials on your credentialsProvider and start returning the logins from AWSCognitoIdentityProvider.

Thanks for the response, I feel like I'm on the right track but I need to clarify a couple of things. I was able to use an unauth identity and then create an auth identity by implementing my own AWSIdentityProviderManager, however I haven't been able to merge those identities or convert the unauth to auth. To clarify, is that even possible? If so, could you provide me more direction on how to achieve it?

Also, I had to use clearKeychain instead of clearCredentials; otherwise it wasn't linking the login to any identity.

@stephencroberts calling clearKeychain can cause your client to not reuse the auth identityId next time you log in. It's possible that it causes a new identity id to be created each time you log in. But again I'm not 100% sure. one way to check is to log in a few times and see if the identity pool browser shows an incrementing number of entries.

It shouldn't (and isn't for me) cause new identities. Since the identity has the linked logins, it should always use the same identity for the authenticated user.

sounds good. thanks for confirming. I'm too interested to know how to merge unauth and auth. but I think depending on your needs, you might need to implement it yourself. It is mentioned that the merge happens automatically, but you might have local data that you need to transfer over. (ref: http://docs.aws.amazon.com/cognito/latest/developerguide/switching-identities.html)

First, you add an identity change delegate handler:

In your init function, add a notification:

        NSNotificationCenter.defaultCenter()
            .addObserver(self, selector: #selector(self.identityIdDidChange), name: AWSCognitoIdentityIdChangedNotification, object: nil)

Your handler:

func identityIdDidChange(notification: NSNotification) {
        let userInfo: NSDictionary = notification.userInfo!
        let before = userInfo.objectForKey(AWSCognitoNotificationPreviousId)
        let after = userInfo.objectForKey(AWSCognitoNotificationNewId)
        print("### Identity changed from \(before) to \(after)")

        // your application logic here to handle the identity change.
}

When the identity changes, you will need to move the data linked to your previous identity to the new one, if any.

That's very close to what I'm working on at the moment. I have a dynamodb that stores some user interaction data (via api gateway + lambda) and uses their Cognito identity id to link it to the user. I want the user to be able to perform these interactions without authenticating, but after they authenticate, I want to make sure the interactions stay linked to the user, so the ideal situation would be for the unauth identity to be converted to an auth identity and maintain the same identity id. Otherwise I'll have to update dynamodb with the new identity id to keep the data intact.

But as it stands, I'm using very similar code to what you posted to perform the dynamodb updates.

That's exactly what I want to end up doing. Except that for now I'm still handling signup and user profile completion with gets stored in the the identity id's data store (powered by dynamodb) available through identity pools. I'll be happy to collaborate.

If you want to keep the same unauth identity, do not call clearKeychain or clearCredentials, otherwise the unauth ID will _not_ become authenticated. Instead you will get a new Identity ID that is authenticated.

Agreed, but without clearing the keychain, nothing happens -- no identity becomes authenticated. Have you been able to get it to work?

invalidateCachedTemporaryCredentials will clear credentials without removing the identity id

@behrooziAWS clearCredentials and invalidateCachedTemporaryCredentials are the same function.

@simoami yes you are correct, I should have said don't call both clearKeychain and clearCredentials if you want to transition from unauth to auth with the same identity id, just call clearCredentials.

So I am following this as well, using clearCredentials instead of clearKeyChain, what this results in though is that if you log out and log in as a different user (on the same device), the new authenticated id is the same as the last logged in user's authenticated id.
if I do use clearKeychain, the user gets a new authenticated id each time... even if it's the same user logging in again.
If I don't clearKeyChain, is the authenticated id tied to the device rather than the user?

Edit: My fault... the same id for every user was happening because on resume, I was not refreshing the credentials.
Edit 2: Nope... that doesn't help. It is still creating a new cognito Id for every login (same user) if I clearKeyChain. and same Id for every user that logs into the same phone if I don't clearKeychain... this is a problem.

Did anyone get this working? I too have been unable to get the transition to authenticated users / attaching the login with the identity id. So it seems like I can't use the Managed User Pools in conjunction with Analytics & CognitoSync seeing I could have any number of users authenticate on the device and they still end up linked to the same identity id. It is unclear how to go about mapping the authenticated user from the User Pool with the Federated Identity Id.

@stephencroberts @simoami @xaksis Hi! Did you find the solution for this issue? I need use unauthenticated user and after convert to authenticated. Thank you

Unfortunately, no, I was never able to get it working properly where an unauth identity is converted to auth. Would love to get some guidance from AWS on this use-case.

Same here, I wasn't able to get the transition working either. In my case, I ended up using clearKeychain - which creates a new authenticated id each time a user logs in. at this point i disregard the authenticated id (which is different each time user logs in) and use the Userpool username as key for everything user. This creates orphan authenticated ids everytime user logs out (which is not a lot if you think about an app). This is definitely not the best way to go about it... but that's the closest i could get to having different users log into the same device.

My concern in using the clearKeychain approach and new authenticated ids is that Sync data is tied to the authentication id - so each time the user is assigned the new authentication id they loose their previous sync data values.

Additionally, I encounter mobile solutions that require multiple users to share a tablet. But our requirements are to have each user use their own account. If this login/logout happens day over day, the generated authentication ids will get out of hand.

I also loose the ability to truly track analytics successfully. Each new identity shows as a new user in analytics - though they may not truly be a new user if I am generating a new authentication id each time.

@stephencroberts @xaksis @mnolanjr98 Thank you for your comments and advices. For now i use this solution. It's not clean but it works. I hope ios Aws will improve soon this library.

Has there been an updated solution to this at all? Still trying to figure out how to store unauthenticated user data on cognito and transfer that data over to an authenticated user when they log in.

I'm curious as well. Any updates?

mobile hub has now updated the SDKs which include user pool in the generated project. Using the projects signIn/userpools bits as is, I was able to have both federated identities + user pool users authenticate and log in along with their respective cognito

@xaksis Thank you for the info. Does it automatically handle the merging of a federated identity and user pool user (if they correspond to the same user)? I can't seem to find the documentation for this.

@xaksis can you maybe provide a gist with your solution please?
I'm struggling for a while now to move from unauthenticated to authenticated as well.
I used the sample from AWS, but I don't want to use a popup as a sign-in controller, but a custom one

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mohab2014 picture mohab2014  路  4Comments

anbarasu0504 picture anbarasu0504  路  3Comments

aTylerRice picture aTylerRice  路  3Comments

victorleungtw picture victorleungtw  路  4Comments

kshrikant picture kshrikant  路  4Comments