当前位置: 首页 > 知识库问答 >
问题:

AWS:如何根据Cognito池正确验证用户,并将其用于Cognito联合身份?

汪弘毅
2023-03-14

我正在开发一个应用程序,它将使用两个身份验证提供商:

  • Facebook
  • Cognito用户池

与前者,我没有问题,一切正常。然而,在使用Cognito用户池设置身份验证时,我遇到了一堵又一堵墙。我使用的是AWS SDK 2.4.9、XCode 8和Swift 3。

我意识到已经有人问了很多问题,而且有很多“指南”。然而,其中很多都是为过时的文档和SDK回答/制作的。甚至官方的AWS留档也过时了。

我正在经历的身份验证步骤如下:

1.配置初始cognito池

///  Set the default service configuration
let serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.usEast1, credentialsProvider: nil)
AWSServiceManager.default().defaultServiceConfiguration = serviceConfiguration

/// Create a pool configuration and register it for a specific key to use later
let poolConfiguration = AWSCognitoIdentityUserPoolConfiguration(clientId: appClientID, clientSecret: appClientSecret, poolId: poolID)  
AWSCognitoIdentityUserPool.registerCognitoIdentityUserPool(with: poolConfiguration, forKey: poolKey)

/// Create a pool for a specific predefined key
pool = AWSCognitoIdentityUserPool(forKey: poolKey)

2.根据Cognito用户池验证用户

  user.getSession(username, password: password, validationData: nil).continue({ (task) -> AnyObject? in

        if let error = task.error as? NSError {
            completionHandler(error)
            return nil
        }

        let session = task.result! as AWSCognitoIdentityUserSession
        let token = session.idToken!.tokenString

        let tokens : [NSString:NSString] = ["cognito-idp.us-east-1.amazonaws.com/\(self.poolID!)" as NSString : token as NSString]
        let identityProvider = CognitoPoolIdentityProvider(tokens: tokens)

        let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .usEast1, identityPoolId: self.identityPoolID, identityProviderManager: identityProvider)

        ///  Set the default service configuration
        let serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.usEast1, credentialsProvider: credentialsProvider)
        AWSServiceManager.default().defaultServiceConfiguration = serviceConfiguration

        credentialsProvider.getIdentityId().continue({ (task) -> AnyObject? in
            completionHandler(task.error as NSError?)
            return nil
        })

        return nil
    })

3.CognitoPoolIdentityProvider类

    class CognitoPoolIdentityProvider : NSObject, AWSIdentityProviderManager {

      var tokens : NSDictionary = [:]

      init(tokens: [NSString : NSString]) {
           self.tokens = tokens as NSDictionary
      }

      @objc func logins() -> AWSTask<NSDictionary> {
           return AWSTask(result: tokens)
      }

    }

4.将数据存储到Cognito联合身份

这一切都毫无差错地过去了。然而,现在我想存储我从Cognito池中提取到特定的Cognito联合身份数据集的数据,所以我调用:userProfile.synchronize()。继续,我得到以下结果:

getCredentialsWithCognito:authenticated:customRoleArn:_block_invoke | GetCredentialsForIdentity失败。错误为[Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=8”(null)“UserInfo={{uuuu type=NotAuthorizedException,message=Access-Identity'us-east-1:xxxxxxxxxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx'被禁止。}]

2016-11-10 10:27:16.947365xxxxxxxx[19867:5614838]AWSiOSSDK v2.4.11[错误]AWS标识符提供程序. m line: 304|__52-[AWSCognitoCreentialsProviderHelper getIdtyId]_block_invoke.255|GetId失败。错误是[Error Domain=com.amazonaws.AWSCognitoIdtyErrorDomain Code=8"(null)"UserInfo={__type=NotAuthorizedExc0019,消息=此标识池不支持未经身份验证的访问。}]2016-11-10 10:27:16.947726xxxxxxxx[19867:5614838]AWSiOSSDK v2.4.11[错误]

行:577|__44-[AWSCognitoCre的提供者凭据]_block_invoke.352|无法刷新。错误是[Error Domain=com.amazonaws.AWSCognitoIdtyErrorDomain Code=8"(null)"UserInfo={__type=NotAuthorizedExc0019,消息=此标识池不支持未经验证的访问。}]2016-11-10 10:27:16.948452xxxxxxxx[19867:5614838]AWSiOSSDK v2.4.11[错误]

AWSCognitoDataset. m line: 352|__30-[AWSCognitoDataset syncPull:]_block_invoke|无法列出记录:Error Domain=com.amazonaws.AWSCognitoIdtyErrorDomain Code=8"(null)"UserInfo={__type=NotAuthorizedExc农田,消息=此标识池不支持未经身份验证的访问。}[10:27:16]:保存设置AWS任务错误:操作无法完成。(com.amazonaws.AWSCognito标识符错误域错误8。)

更改日志级别后,我可以看到以下内容:

//请求

2016-11-10 10:33:08.095735 xxxxxxxx[19874:5616142]AWSIOSDK v2.4.11[Debug]AWSURLSessionManager.m行:543 |-[AWSURLSessionManager printHTTPHeadersAndBodyForRequest:|请求主体:{“IdentityId:”us-east-1:XXXXXXXXXXXXXXXX-xxxx-xxxx-xxxx-xxxx-xxxxxxxx-XXXXXXXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXX”}

//响应

2016-11-10 10:33:08.714268xxxxxxxx[19874:5616154]AWSiOSSDK v2.4.11[Debug]AWSURLSessionManager. m line: 553|-[AWSURLSessionManager printHTTPHeadersFor响应:]|响应报头:{连接="保持活力";"内容长度"=129;"内容类型"="应用程序/x-amz-json-1.1";日期="Thu,10 Nov2016 09:33:08GMT";"x-amzn-错误消息"="禁止访问身份'us-East-1: xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx'.";"x-amzn-错误类型"="NotAuthorizedExcture:";"x-amzn-请求ID"="b0ac6fb0-a728-11e6-8413-1fdb846185bb";}

上面的请求是getIDAPI调用。显然,它与AWS文档中的请求格式不匹配:http://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html.

根据AWSServiceManager类,我们有:

/**
 The default service configuration object. This property can be set only once, and any subsequent setters are ignored.
 */
@property (nonatomic, copy) AWSServiceConfiguration *defaultServiceConfiguration;

这意味着设置新的服务配置毫无意义,但我认为没有其他方法可以刷新通过Cognito用户池身份验证获得的凭据。

差不多就是这样。有什么想法吗?

谢谢

共有1个答案

上官景铄
2023-03-14

从你所犯的错误来看

  Access to Identity 'us-east-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' is forbidden

您在第一部分中获得的凭据无法访问您进行同步调用的身份,因此您的身份可能已更改。

 类似资料:
  • 所以我已经成功地验证了用户与Cognito中的用户池。根据我的理解,现在在我们利用任何AWS服务(Dynamodb,S3等)之前,我们需要再次从AWS Cognito Credential提供商获得。 Cognito用户池(验证)用户登录 通过配置AWSCOgnitoRedentialsProvider获取CognitoID 为我们想要与之交互的任何服务制作AWS CAL 从用户PoolID委托成

  • 我正在使用vue3,并且已经建立了一个AWS用户池(amazoncognito.com)。目标是根据Cognito使用用户名和密码对用户进行身份验证,并接收OAuth2令牌以验证针对AWSAPI网关发出的API请求。 挑战:AWS amplify似乎不适用于最新的vue3版本。它只显示用户未登录,但未显示任何登录或注销按钮,无论配置如何。 我感兴趣的潜在解决方案(优先顺序) main.js 和内部

  • 我是AWS的新手,正在学习Cognito池。 我计划使用与Cognito联合身份池连接的Cognito用户池。我不想使用带有托管用户界面功能的登录或任何其他登录用户界面登录。 以下情况是否属实/可能:- 从后端使用用户名和密码调用一些Cognoto API时,它可以自动调用配置的用户池联合身份提供程序来验证用户,然后生成JWT令牌。如果是,请您为我指点/指导。 我真的很感激任何帮助。提前谢谢。

  • 我的代码在这里:代码重新发布是因为我想问一个更直接的问题。如何在未经身份验证的用户和经过身份验证的用户之间切换?我的未经验证的文件似乎已缓存,我使用了以下方法: 在我剩下的api代码之前,它仍然不能工作。谢谢你的帮助 注意:我知道它不起作用,因为我在切换配置/凭据提供程序后立即使用lambda进行调用,并且只有授权用户才能调用此方法。 编辑@behrooziAWS答案: API代码: 完整错误:B

  • 我在Node.JS中使用AWS Cognito。 我正在成功注册和验证用户,但身份验证返回“未知错误,fetch的响应主体未定义” 我使用节点获取模块随着亚马逊-认知-身份-js(设置为var AWSCognito在下面的代码)。用户未处于需要更改密码并已验证的状态。 其他人是否经历过这种情况?您是如何解决此问题的?感谢您提前给予指导。。。。 这是我的代码,我的完整模块作为iditawsutils

  • 我刚刚开始和AWS一起工作,学习AWS。我正在使用AWS移动中心的服务,到目前为止已经设置了登录 一切正常,现在我正在处理忘记密码和更新密码。 问题是,AWS设置忘记密码的方式是: 首先输入用户名,然后在用户输入用户名后,AWS通过SMS向与该用户名关联的电话号码发送验证码。 这是一个问题,因为这意味着任何人都可以输入任何用户名,并会发送一条短信,导致我的短信付款增加,老实说,这看起来很草率。 我