来自未授权以开发交换机认证cognito用户 - AWS的iOS SDK交换机、用户、cognito、SDK

2023-09-11 12:02:37 作者:温文尔雅

总体问题: 我使用的是开发者认证的身份与我的前端(IOS)中的问题。我知道我的后端产生正确的标记和identityID但我的刷新方法不会被调用。我也看了看样品,但我得到稍微困惑的一切事情。 流程说明: 目前,我有,有一个登录按钮的登录画面。用户presses登录按钮,然后我的API类需要的凭据,对密码进行加密并将其存储在钥匙串(注释掉现在,因为它不能在模拟器工作)。我DeveloperAuthenticatedIdentityProvider被称为我的应用程序BusytimeAuthenticated。我已经完成了所有的方法(我使用AWS的Lambda和DynamoDB验证用户身份的话)我开始与认证的访问,让我访问只有两个方法,登录和注册。然后,我要承担我的身份验证的用户,让我打电话给我的其他方法。

Overall Problem: I have a problem using a developer authenticated identity with my front end (iOS). I know my backend produces the correct token and identityID but my refresh method never gets called. I've also looked at the sample but I get slightly confused with everything going on. Flow Explanation: Currently I have a login screen that has a login button. The user presses the login button, then my api class takes the credentials, encrypts the password and stores it in keychain (commented out for now since it doesn't work on simulator). My DeveloperAuthenticatedIdentityProvider is called my app BusytimeAuthenticated. I have completed all the methods (I'm using AWS lambda and DynamoDB to authenticate users so) I start with unauthenticated access which allows me to access only two methods, login and signup. Then I want to assume my authenticated user which allows me to call my other methods.

我的API code:

my API Code:

[AWSLogger defaultLogger].logLevel = AWSLogLevelVerbose;
id<AWSCognitoIdentityProvider> identityProvider = [[BusytimeAuthenticated alloc] initWithRegionType:AWSRegionUSEast1
                                                                                                          identityId:nil
                                                                                identityPoolId:@"SOMEIDENTITYPOOLID"
                                                                                logins:@{@"SOMEPROVIDERNAME": @"SOMEUSERNAME"}
                                                                                       providerName:@"SOMEPROVIDERNAME"
                                                                                                          ];

credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
                                                                    identityProvider:identityProvider
                                                                       unauthRoleArn:nil
                                                                         authRoleArn:nil];

configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1
                                                                     credentialsProvider:self.credentialsProvider];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
[[credentialsProvider refresh] continueWithBlock:^id(BFTask *task){
    [self testAuth];
    return nil;
}];

我DeveloperAuthenticatedIdentityProvider code(BusytimeAuthenticated):

my DeveloperAuthenticatedIdentityProvider code (BusytimeAuthenticated) :

#import "BusytimeAuthenticated.h"

@interface BusytimeAuthenticated()
@property (strong, atomic) NSString *providerName;
@property (strong, atomic) NSString *token;
@end

@implementation BusytimeAuthenticated
@synthesize providerName=_providerName;
@synthesize token=_token;



- (instancetype)initWithRegionType:(AWSRegionType)regionType
                        identityId:(NSString *)identityId
                    identityPoolId:(NSString *)identityPoolId
                            logins:(NSDictionary *)logins
                      providerName:(NSString *)providerName{
    if (self = [super initWithRegionType:regionType identityId:identityId accountId:nil identityPoolId:identityPoolId logins:logins]) {
        self.providerName = providerName;
    }
    return self;
}

// Return the developer provider name which you choose while setting up the
// identity pool in the Amazon Cognito Console

- (BOOL)authenticatedWithProvider {
    return [self.logins objectForKey:self.providerName] != nil;
}


// If the app has a valid identityId return it, otherwise get a valid
// identityId from your backend.

- (BFTask *)getIdentityId {
    // already cached the identity id, return it
    if (self.identityId) {
        return [BFTask taskWithResult:nil];
    }
    // not authenticated with our developer provider
    else if (![self authenticatedWithProvider]) {
        return [super getIdentityId];

    }
    // authenticated with our developer provider, use refresh logic to get id/token pair
    else {
        return [[BFTask taskWithResult:nil] continueWithBlock:^id(BFTask *task) {
            if (!self.identityId) {
                return [self refresh];
            }
            return [BFTask taskWithResult:self.identityId];
        }];
    }

}


// Use the refresh method to communicate with your backend to get an
// identityId and token.

- (BFTask *)refresh {
    if (![self authenticatedWithProvider]) {
        return [super getIdentityId];
    }else{
//        KeychainWrapper *keychain = [[KeychainWrapper alloc]init];
        AWSLambdaInvoker *lambdaInvoker = [AWSLambdaInvoker defaultLambdaInvoker];
        NSDictionary *parameters = @{@"username" : @"SOMEUSERNAME",
                                     @"password":@"SOMEENCRYPTEDPASS",
                                     @"isError" : @NO};
        NSLog(@"Here");
        [[lambdaInvoker invokeFunction:@"login" JSONObject:parameters] continueWithBlock:^id(BFTask* task) {
            if (task.error) {
                NSLog(@"Error: %@", task.error);
            }
            if (task.exception) {
                NSLog(@"Exception: %@", task.exception);
            }
            if (task.result) {
                self.identityId = [task.result objectForKey:@"IdentityId" ];
                self.token = [task.result objectForKey:@"Token" ];
//                [keychain mySetObject:[task.result objectForKey:@"Token" ] forKey:@"Token"];
//                [keychain mySetObject:[task.result objectForKey:@"IdentityId" ] forKey:@"IdentityId"];
                NSLog(@"Result: %@", task.result);

            }
            return [BFTask taskWithResult:self.identityId];
        }];



    }
    return NULL;
}

@end

总结问题: 不幸的是,当我测试我的新priveleges,我从错误中看到:Unauth_Role / CognitoIdentityCredentials无权执行:拉姆达:InvokeFunction。显然,我不会切换正常。我已经摆在我的刷新方法中设置断点,看它是否得到调用。不是。我不是很了解我是如何正常开关。任何帮助,得到这个工作是非常AP preciated。

Summary Problem: Unfortunately when I test my new priveleges, I see from the error: "Unauth_Role/CognitoIdentityCredentials is not authorized to perform: lambda:InvokeFunction". Clearly I'm not switching properly. I've placed a breakpoint in my refresh method to see if it's getting called. It's not. I'm not quite understanding how I switch properly. Any help with getting this to work is much appreciated.

注:一个大的变化我没有做,虽然是我带出来的DeveloperAuthenticationClient类,因为我认为我能做到这一点没有它。

Note: One big change I did make though is I took out the "DeveloperAuthenticationClient" class because I assumed I could do it without it.

推荐答案

最根本的问题是,你试图调用一个lambda函数(需要凭据),以获得证书。因为你使用的是默认客户端配置,当你的开发人员认证的客户回来了响应它要覆盖用于访问lambda表达式的凭据。此外,一旦ID已经被转移到验证,您将无法使用它来获得凭证的未授权流量,将需要产生一个新的未经验证的标识只是为了再次认证,然后回到你的身份验证标识。

The fundamental problem is that you are trying to call a Lambda function (which requires credentials) to get credentials. Because you are using the "default" client configuration, when your developer authenticated client comes back with a response it is going to override the credentials used to access your Lambda function. Additionally, once that id has been transitioned to authenticated, you won't be able to use it to get credentials in an unauth flow and would need to generate a new unauthenticated id just to authenticate again and then get back to your authenticated id.

我会强烈建议您安装 API网关在lambda函数前去除这种循环依赖。

I would strongly encourage you to setup API Gateway in front of your Lambda function to remove this circular dependency.

 
精彩推荐
图片推荐