繁体   English   中英

将DynamoDB与Cognito一起使用:令牌不是来自此身份池的受支持提供商

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

我正在以这个项目为例,为我的iOS应用程序实现注册和登录:

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

以前,我的应用程序能够通过使用AppDelegate的didFinishLaunchingWithOptions方法中设置的凭据提供程序来访问DynamoDB资源。 但是,在更改项目以包括登录和功能(如示例)之后,我看到了错误:

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

该代码设置credentialsProvider在AppDelegate中目前看起来是这样的:

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)

我也无法通过我的应用程序访问任何DynamoDB数据。

根据控制台的输出,尽管我不确定登录过程,但注册过程似乎可以正常工作。 我突然想到将区域从存储DynamoDB资源的EU-West-1更改为US-East-1。 为了解决此更改,我重复了我最初允许我的应用访问DynamoDB的相同步骤:

  • 我创建了Auth和Unauth角色,这两个角色都可以访问与以前工作的角色相同的动作,但是使用的是EU-West-1资源。
  • 我将这些角色设置为在“未经身份验证的角色”和“经过身份验证的角色”下设置注册时创建的用户池。

如果有所作为,请注意,我没有使用我链接的示例项目中概述的完全相同的登录过程。 相反,我使用了显式登录过程,如下所示:

    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
    })

方法lock()unlock()sendErrorPopup()是与我完全相关的与UI相关的方法,因此登录过程的开始和结束将在视觉上更加清晰。 控制台输出始终显示“成功登录”,但是我想知道此代码是否真正正确地登录了用户,因为错误消息使用户听起来好像未得到正确的授权。

我想到美国西部表可能没有正确设置,但是即使试图创建新表,我也遇到同样的问题,所以我认为这不是问题。 就授予用户访问DynamoDB的权限而言,我可能还缺少一些步骤吗? AWS Cognito的新beta用户池系统是否改变了流程?

编辑2:

我修复了上一个问题,有一段时间,我的应用程序运行良好。 但是,当我登录时,它突然停止加载DynamoDB数据,并显示错误消息: invalid login token. Can't pass in a Cognito token. invalid login token. Can't pass in a Cognito token. 目前,我的AppData代码如下所示:

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

...而我的登录代码如下所示:

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
    })

在我的应用程序正常工作与不正常工作之间,我没有进行任何更改。 在测试密码重置功能时,确实导致了“密码重置次数过多”错误,但是即使在我的应用上创建了新的用户帐户后,该问题仍然存在,因此我认为这不是原因。 我是否正确处理登录? 如果是这样,我应该在哪里寻找导致此问题的其他原因?

如果您为Cognito提供了登录名但未启用身份池使用该登录名提供者,通常会抛出该异常。 如果还没有,请转到Cognito联合身份控制台,然后打开要尝试使用的任何提供程序(看起来像“用户池”),并且此错误应该消失。

如果您确定已进行设置,是否可以提供有关如何设置登录名的代码段?

在登录名中设置ID令牌所针对的密钥,其格式应为cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>而不是您的USER_POOL_NAME。 该博客以及您的开发人员指南中的链接应说明您需要的步骤和代码。

至于过时的登录字典的解决方案,您需要使用此构造函数来创建凭据提供程序。 这里的identityProviderManager应该是AWSIdentityProviderManager协议的实现,并且logins方法应该将您的提供者名称的字典映射返回给令牌。 凭证提供者每次需要身份提供者令牌时都会调用此方法。 检查此答案以获取更多详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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