AppSync Multi-Auth not working (iOS)

0

I'm currently utilizing API-Key as my default auth method and it is working as expected. I am working to convert over to using CognitoUserPools by adding an "Additional authorization provider" via the AppSync console. The goal is to allow users to update their apps before flipping the switch and disabling the API key.

If I set my AppSync API Settings to utilize the Cognito Pool as the default method in the AWS Console and also set the Cognito Pool as the Default in the awsconfiguration.json file, I am able to authenticate through. I am also able to authenticate through when using the API key, as I have been.

However, if I use multiple auth methods (per https://docs.amplify.aws/sdk/api/graphql/q/platform/ios/#authorization-modes) I get 401 auth errors for the Cognito config. The API key still works (with Swift code adjusted). I have confirmed that the appSyncConfig is indeed using the correct Cognito service config from the json file. I cannot figure out why it will not let me auth. API responses will return errors for being unable to auth, as well.

AWSAppSync ver. 3.6.1

Not working:

            let serviceConfigCognito = try AWSAppSyncServiceConfig(forKey: "friendly_name_AMAZON_COGNITO_USER_POOLS")
            let cacheConfigCognito = try AWSAppSyncCacheConfiguration(
                useClientDatabasePrefix: true,
                appSyncServiceConfig: serviceConfigCognito
            )
            let clientConfigCognito = try AWSAppSyncClientConfiguration(
                appSyncServiceConfig: serviceConfigCognito,
                userPoolsAuthProvider: MyCognitoUserPoolsAuthProvider(),
                cacheConfiguration: cacheConfigCognito
            )

            appSyncClient = try AWSAppSyncClient(appSyncConfig: appSyncConfig)
 "AppSync": {
    "Default": {
      "ApiUrl": "https://xyz.us-west-2.amazonaws.com/graphql",
      "Region": "us-west-2",
      "AuthMode": "API_KEY",
      "ApiKey": "da2-xyz",
      "ClientDatabasePrefix": "friendly_name_API_KEY"
    },
    "friendly_name_AMAZON_COGNITO_USER_POOLS": {
      "ApiUrl": "https://xyz.us-west-2.amazonaws.com/graphql",
      "Region": "us-west-2",
      "AuthMode": "AMAZON_COGNITO_USER_POOLS",
      "ClientDatabasePrefix": "friendly_name_AMAZON_COGNITO_USER_POOLS"
    }
  }

Working:

            let cacheConfiguration = try AWSAppSyncCacheConfiguration()
            let appSyncConfig = try AWSAppSyncClientConfiguration(appSyncServiceConfig: AWSAppSyncServiceConfig(),
                                                                  userPoolsAuthProvider: MyCognitoUserPoolsAuthProvider(),
                                                                  cacheConfiguration: cacheConfiguration)

            appSyncClient = try AWSAppSyncClient(appSyncConfig: appSyncConfig)
 "AppSync": {
    "Default": {
      "ApiUrl": "https://xyz.us-west-2.amazonaws.com/graphql",
      "Region": "us-west-2",
      "AuthMode": "AMAZON_COGNITO_USER_POOLS",
    }
  }

Support class required:

class MyCognitoUserPoolsAuthProvider : AWSCognitoUserPoolsAuthProvider {
    
    func getLatestAuthToken() -> String {
     let pool = AWSCognitoIdentityUserPool(forKey: CognitoPoolID)
     let session =  pool?.currentUser()?.getSession()
        if let token = session?.result?.idToken {
            return token.tokenString
        } else {
            return ""
        }
    }
}
2 Answers
0
Accepted Answer

Figured it out.

To make this work this must be added to each query, mutation, type, etc, in the Schema. Adding this to queries is not shown consistently in docs or in various other help articles, but it is found here: https://aws.amazon.com/blogs/mobile/secure-aws-appsync-with-iam-permissions-using-the-aws-cdk/.

@aws_api_key @aws_cognito_user_pools

type Query {
  listUsers(limit: Int, nextToken: String): UserConnection
      @aws_iam
      @aws_cognito_user_pools
}
KapKerm
answered 10 months ago
0

Hey there,

great question to be honest. I think the AppSync documentation does a bad job here - but I believe with a 80% confidence in myself that when you have multiple authorization modes you will need to specify which authorization mode should be used within the schema itself.

So the "problem" you have is most probably within your GraphQL schema and not within your clients code.

Let me know if that worked. Johannes

profile picture
answered 10 months ago
  • Thanks for the input. I have attempted adding "@aws_api_key @aws_cognito_user_pools" to the first Type in my query sequence and am still receiving a 401. This page (at the bottom) states it must have both. https://repost.aws/knowledge-center/aws-appsync-graphql-request-unauth-error

    Interestingly, If I reload the application a few times, I'm able to get a failure on the query itself. "Unauthorized" "Not Authorized to access getData on type Query"

    The query currently has a simple resolver with 1 input parameter. There are no limitations on resolver output.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions