简体   繁体   中英

Using DynamoDB With Cognito: Token is not from a supported provider of this identity pool

I am in the process of implementing registration and login for my iOS app, using this project as an example:

https://github.com/awslabs/aws-sdk-ios-samples/tree/75ada5b6283b7c04c1214b2e1e0a6394377e3f2b/CognitoYourUserPools-Sample/Objective-C/CognitoYourUserPoolsSample

Previously, my app was able to access DynamoDB resources by using a credentials provider set up in my AppDelegate's didFinishLaunchingWithOptions method. However, after changing my project to include logging in and function like the example, I see the error:

"__type":"NotAuthorizedException","message":"Token is not from a supported provider of this identity pool."

The code setting the credentialsProvider in AppDelegate currently looks like this:

let serviceConfiguration = AWSServiceConfiguration(region: .USEast1, credentialsProvider: nil)
    let userPoolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId:APP_CLIENT_ID, clientSecret: APP_CLIENT_SECRET, poolId: USER_POOL_ID)
    AWSCognitoIdentityUserPool.registerCognitoIdentityUserPoolWithConfiguration(serviceConfiguration, userPoolConfiguration: userPoolConfiguration, forKey: USER_POOL_NAME)
    let pool = AWSCognitoIdentityUserPool(forKey:USER_POOL_NAME)
    pool.delegate = self
    self.storyboard = UIStoryboard(name: "Main", bundle: nil)
    let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: IDENTITY_POOL_ID, identityProviderManager:pool)
    let configuration = AWSServiceConfiguration(region:.USEast1, credentialsProvider:credentialsProvider)

I also cannot access any DynamoDB data through my app.

Based on the console output, the registration process seems to work correctly, although I'm unsure about the sign-in process. It occurred to me that I had changed the region from EU-West-1, where the DynamoDB resources were stored, to US-East-1. In order to account for this change, I repeated the same steps I had intially taken to allow my app to access DynamoDB:

  • I created Auth and Unauth roles, both with access to the same actions as the role which had previously worked, but for the EU-West-1 resources instead.
  • I set these roles to the user pool I created when setting up registration under "unauthenticated role" and "authenticated role".

In case it makes a difference, I should note that I did not use the exact same sign-in process outlined in the example project I linked. Instead, I used the explicit sign in process, like so:

    let name = usernameField.text!
    let user = pool!.getUser(name)
    lock()
    user.getSession(name, password: passwordField.text!, validationData: nil, scopes: nil).continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: {
        (task:AWSTask!) -> AnyObject! in
        if task.error != nil {
            self.sendErrorPopup("ERROR: Unable to sign in. Error description: " + task.error!.description)
        } else {
            print("Successful Login")
            dispatch_async(dispatch_get_main_queue()){
                self.performSegueWithIdentifier("mainViewControllerSegue", sender: self)
            }
        }
        self.unlock()
        return nil
    })

The methods lock() , unlock() , and sendErrorPopup() are strictly UI-related methods that I made so that the beginning and end of the sign-in process would be more visually clear. The console output always reads "successful login", but I am wondering if this code actually signs the user in correctly, since the error message makes it sound like the user might not be properly authorized.

It occurred to me that the US-West tables might not have been set up correctly, but I experience the same problem even when trying to create new tables, so I don't think that's the issue. Are there steps I might have missed as far as giving the user access to DynamoDB? Has the process changed with AWS Cognito's new beta user pool system?

EDIT 2:

I fixed the previous issue, and for a while, my app was working fine. However, it has suddenly stopped loading DynamoDB data when I sign in, and shows the error message: invalid login token. Can't pass in a Cognito token. invalid login token. Can't pass in a Cognito token. Currently, my AppData code looks like this:

let serviceConfiguration = AWSServiceConfiguration(region: .USEast1, credentialsProvider: nil)
    let userPoolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId:APP_CLIENT_ID, clientSecret: APP_CLIENT_SECRET, poolId: USER_POOL_ID)
    AWSCognitoIdentityUserPool.registerCognitoIdentityUserPoolWithConfiguration(serviceConfiguration, userPoolConfiguration: userPoolConfiguration, forKey: USER_POOL_NAME)
    let pool = AWSCognitoIdentityUserPool(forKey:USER_POOL_NAME)
    pool.delegate = self
    self.storyboard = UIStoryboard(name: "Main", bundle: nil)
    self.credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: IDENTITY_POOL_ID, identityProviderManager:pool)
    let manager = IdentityProviderManager(tokens: [NSString:NSString]())
    self.credentialsProvider = AWSCognitoCredentialsProvider(regionType: .USEast1, identityPoolId: IDENTITY_POOL_ID, identityProviderManager: manager)
    let configuration = AWSServiceConfiguration(region:.USEast1, credentialsProvider:credentialsProvider!)
    AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration

...and my sign-in code looks like this:

if locked { return }
    trimRegistrationValues()
    let name = usernameField.text!
    let user = pool!.getUser(name)
    lock()
    user.getSession(name, password: passwordField.text!, validationData: nil, scopes: nil).continueWithExecutor(AWSExecutor.mainThreadExecutor(), withBlock: {
        (task:AWSTask!) -> AnyObject! in

        if task.error != nil {
            self.sendErrorPopup("ERROR: Unable to sign in. Error description: " + task.error!.description)
        } else {
            print("Successful Login")

            let loginKey = "cognito-idp.us-east-1.amazonaws.com/" + USER_POOL_ID
            var logins = [NSString : NSString]()
            self.credentialsProvider!.identityProvider.logins().continueWithBlock { (task: AWSTask!) -> AnyObject! in

                if (task.error != nil) {
                    print("ERROR: Unable to get logins. Description: " + task.error!.description)

                } else {
                    if task.result != nil{
                        let prevLogins = task.result as! [NSString:NSString]
                        print("Previous logins: " + String(prevLogins))
                        logins = prevLogins
                    }
                    logins[loginKey] = name
                    let manager = IdentityProviderManager(tokens: logins)
                    self.credentialsProvider!.setIdentityProviderManagerOnce(manager)
                    self.credentialsProvider!.getIdentityId().continueWithBlock { (task: AWSTask!) -> AnyObject! in

                        if (task.error != nil) {
                            print("ERROR: Unable to get ID. Error description: " + task.error!.description)

                        } else {
                            print("Signed in user with the following ID:")
                            print(task.result)
                            dispatch_async(dispatch_get_main_queue()){
                                self.performSegueWithIdentifier("mainViewControllerSegue", sender: self)
                            }
                        }
                        return nil
                    }
                }
                return nil
            }
        }
        self.unlock()
        return nil
    })

I haven't changed anything between my app working and not working. I did cause a "too many password resets" error while testing the password reset functionality, but the issue persisted even when I created a new user account on my app, so I don't think that's the cause. Am I handling login correctly? If so, where should I look for other possible causes to this issue?

That exception is usually thrown if you've given Cognito a login but have not enabled your identity pool to consume that login provider. If you haven't, go to the Cognito Federated Identities console and turn on whichever provider you are trying to use (looks like User Pools), and this error should go away.

If you're certain you have set that up, can you give a code snippet of how you're setting the logins?

The key that you set the ID token against in logins should be of the format cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID> not your USER_POOL_NAME. This blog along with the link in your post for our dev guide should explain the steps and code you need.

As for the solution to deprecated logins dictionary, you need to use this constructor to create the credentials provider. The identityProviderManager here should be an implementation of AWSIdentityProviderManager Protocol and the logins method should return the dictionary mapping for your provider name to the token. The credentials provider will call this method every time it needs the identity provider token. Check this answer for more details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM