AWS Cognito iOS 开发人员身份验证

问题描述:

我正在尝试将 amazon cognito 与开发人员验证身份一起使用.我的 API 已成功返回 ID 和令牌.但是,当我使用这些令牌将内容上传到 S3 时,我收到以下错误:

I am trying to use amazon cognito with developer authenticated identities. My API is successfully returning an id and token. However, when I use these tokens to upload content to S3 I receive the following error:

Not authorized to perform sts:AssumeRoleWithWebIdentity

以下是我设置凭据提供程序的代码.

Below is my code for setting up the credentials provider.

ZGAWSIdentityProvider *identityProvider = [ZGAWSIdentityProvider new];
[identityProvider setIdentityPoolId:AWS_IDENTITY_POOL_ID];

AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc]
                                           initWithRegionType:AWSRegionUSEast1
                                           identityProvider:identityProvider
                                           unauthRoleArn:AWS_UNAUTH_ROLE_ARN
                                           authRoleArn:AWS_AUTH_ROLE_ARN];


AWSServiceConfiguration *configuration = [AWSServiceConfiguration configurationWithRegion:AWSRegionUSWest1
                                                                      credentialsProvider:credentialsProvider];

[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;

我正在使用 http://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#create-an-identity-pool-that-supports-developer-authenticated-identities 以创建身份提供者.

And I am using the template provided at http://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#create-an-identity-pool-that-supports-developer-authenticated-identities to create the identity provider.

@implementation ZGAWSIdentityProvider
@synthesize identityPoolId=_identityPoolId;
@synthesize identityId=_identityId;
@synthesize token=_token;


- (BFTask *)getIdentityId {
    // Should ensure that identityId property is valid. The below code can probably
    // be used for most use cases.

    if (self.identityId) {
        return [BFTask taskWithResult:nil];
    } else {
        return [[BFTask taskWithResult:nil] continueWithBlock:^id(BFTask *task) {
            if (!self.identityId) {
                return [self refresh];
            }
            return nil;
        }];
    }
}

- (BFTask *)refresh {

    BFTaskCompletionSource *task = [BFTaskCompletionSource taskCompletionSource];
    __weak __typeof(self)weakSelf = self;
    [[ZGAccountController sharedInstance] getAWSCredentialsWithCompletion:^(NSDictionary *credentials) {

        if (credentials && [credentials objectForKey:@"identity_id"] && [credentials objectForKey:@"identity_id"]) {
            __strong __typeof(weakSelf)strongSelf = weakSelf;
            strongSelf.identityId = [credentials objectForKey:@"identity_id"];
            strongSelf.token = [credentials objectForKey:@"token"];
            [task setResult:nil];
        } else {
            NSError *error = [NSError errorWithDomain:@"com.##.##" code:-1 userInfo:nil];
            [task setError:error];
        }

    }];

    return task.task;
}

@end

这似乎是角色信任的问题.我使用亚马逊 Web 界面创建了身份池,并仔细检查了身份池 ID 是否正确.我已经能够成功上传 w 个未经身份验证的身份,所以我认为不是角色权限问题​​.

It appears to be an issue with Role Trust. I created the identity pool using the amazon web interface and have double checked that the identity pool id is correct. I have been able to successfully upload w unauthenticated identities, so I believe is not a role permissions issue.

很抱歉给大家带来麻烦.

Sorry for all the trouble.

身份提供者和凭证提供者的交互方式存在一个小问题,没有正确记录或妥善处理.凭据提供程序使用 unauth 或 auth 角色 arn 根据提供程序上是否附加登录名进行透视.如果您没有在提供程序上存储任何其他登录信息,它会将其视为未经身份验证并使用 unauth 角色并导致您看到 STS 错误.您可以通过在身份提供者的刷新中执行以下操作来解决此问题:

There is a small issue with how the identity provider and credentials provider interact that is not properly documented or handled well. The credentials provider pivots using the unauth or auth role arn based on whether or not there are logins attached on the provider. If you aren’t storing any additional logins on the provider, it will treat it as unauthenticated and use the unauth role and result in the STS error you are seeing. You can work around this by doing something like the following in your identity provider’s refresh:

// add login to the map to make sure CredentialsProvider treats us as authenticated
NSMutableDictionary *temp = [NSMutableDictionary dictionaryWithDictionary:self.logins];
[temp setObject:@"temp" forKey:@"myprovider"];
self.logins = temp;

2015-03-10 更新:您可能需要考虑查看我们的 端到端示例 更好的处理方法.

Update 2015-03-10: You may want to consider looking at our end-to-end example for a better method for handling this.

在这个示例中,我们包含用户标识符的实际值,然后将 logins 属性的全部内容传递给后端.

This the sample, we include the the actual values for the user identifier, then pass the entire contents of the logins property to the backend.