amplify-swift: SignInWithAppleButton bug

Describe the bug

I am following these instructions:

https://aws.amazon.com/blogs/mobile/federating-users-using-sign-in-with-apple-and-aws-amplify-for-swift/

Federation fails and the output doesn’t help me to debug

Steps To Reproduce

Steps to reproduce the behavior:
1. Setup Amplify like this... https://docs.amplify.aws/lib/auth/social/q/platform/ios/
2. Set up swift code like this... https://aws.amazon.com/blogs/mobile/federating-users-using-sign-in-with-apple-and-aws-amplify-for-swift/
3. Run app from xcode simulator
4. Try to login with apple credentials

Expected behavior

I would expect to see the xcode console message “Successfully federated user to identity pool with result: ###”

Amplify Framework Version

12.2.3

Amplify Categories

Auth

Dependency manager

Swift PM

Swift version

4

CLI version

12.2.3

Xcode version

14.3.1

Relevant log output

<details>
<summary>Log Messages</summary>


Successfully configured Amplify
2023-08-04 15:00:34.819094+0100 Peakflow[4756:104392] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InitializeAuthConfiguration.swift Starting execution
2023-08-04 15:00:34.819175+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configuringAuth" =     {
    };
}
2023-08-04 15:00:34.820257+0100 Peakflow[4756:104392] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/MigrateLegacyCredentialStore.swift Starting execution
2023-08-04 15:00:34.821534+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] Credential Store state change:

migratingLegacyStore
2023-08-04 15:00:34.859901+0100 Peakflow[4756:104392] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/MigrateLegacyCredentialStore.swift Sending event CredentialStoreEvent.loadCredentialStore
2023-08-04 15:00:34.860040+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Credential Store state change:

loadingStoredCredentials
2023-08-04 15:00:34.860102+0100 Peakflow[4756:104393] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/LoadCredentialStore.swift Starting execution
2023-08-04 15:00:34.861079+0100 Peakflow[4756:104393] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/LoadCredentialStore.swift Retreiving credential amplifyCredentials
2023-08-04 15:00:34.864344+0100 Peakflow[4756:104393] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/LoadCredentialStore.swift Sending event CredentialStoreEvent.throwError
2023-08-04 15:00:34.864463+0100 Peakflow[4756:104393] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/IdleCredentialStore.swift Starting execution
2023-08-04 15:00:34.864480+0100 Peakflow[4756:104392] [AWSCognitoAuthPlugin] No existing session found.
2023-08-04 15:00:34.864539+0100 Peakflow[4756:104393] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/IdleCredentialStore.swift Sending event CredentialStoreEvent.moveToIdleState
2023-08-04 15:00:34.864659+0100 Peakflow[4756:104392] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InitializeAuthConfiguration.swift Sending event AuthEvent.validateCredentialAndConfiguration
2023-08-04 15:00:34.864840+0100 Peakflow[4756:104397] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/ValidateCredentialsAndConfiguration.swift Starting execution
2023-08-04 15:00:34.864872+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.validatingCredentialsAndConfiguration" =     {
    };
}
2023-08-04 15:00:34.864943+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Credential Store state change:

error(KeychainStoreError: Unable to find the keychain item
Recovery suggestion: This should not happen. There is a possibility that there is a bug if this error persists. Please take a look at https://github.com/aws-amplify/amplify-ios/issues to see if there are any existing issues that match your scenario, and file an issue with the details of the bug if there isn't. Issue encountered at:
file: /####/SourcePackages/checkouts/amplify-swift/AmplifyPlugins/Core/AWSPluginsCore/Keychain/KeychainStoreError.swift
function: recoverySuggestion
line: 69)
2023-08-04 15:00:34.864948+0100 Peakflow[4756:104397] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/ValidateCredentialsAndConfiguration.swift Sending event AuthEvent.configureAuthentication
2023-08-04 15:00:34.865019+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Credential Store state change:

idle
2023-08-04 15:00:34.865539+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configuringAuthentication" =     {
        "AuthenticationState.notConfigured" =         {
        };
    };
}
2023-08-04 15:00:34.865778+0100 Peakflow[4756:104397] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InitializeAuthenticationConfiguration.swift Starting execution
2023-08-04 15:00:34.865861+0100 Peakflow[4756:104397] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InitializeAuthenticationConfiguration.swift Sending event AuthenticationEvent.configure
2023-08-04 15:00:34.866889+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configuringAuthentication" =     {
        "AuthenticationState.configured" =         {
        };
    };
}
2023-08-04 15:00:34.866915+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/ConfigureAuthentication.swift Start execution
2023-08-04 15:00:34.867270+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/ConfigureAuthentication.swift Sending event AuthenticationEvent.initializedSignedOut
2023-08-04 15:00:34.867460+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/ConfigureAuthentication.swift Sending event AuthEvent.authenticationConfigured
2023-08-04 15:00:34.867550+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configuringAuthentication" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
    };
}
2023-08-04 15:00:34.867792+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InitializeAuthorizationConfiguration.swift Starting execution
2023-08-04 15:00:34.867971+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InitializeAuthorizationConfiguration.swift Sending event AuthorizationEvent.configure
2023-08-04 15:00:34.867978+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configuringAuthorization" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.notConfigured" =         {
        };
    };
}
2023-08-04 15:00:34.870767+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/ConfigureAuthorization.swift Starting execution
2023-08-04 15:00:34.870849+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configuringAuthorization" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.configured" =         {
        };
    };
}
2023-08-04 15:00:34.870870+0100 Peakflow[4756:104390] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/ConfigureAuthorization.swift Sending event AuthEvent.authorizationConfigured
2023-08-04 15:00:34.871003+0100 Peakflow[4756:104391] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.configured" =         {
        };
    };
}
Token string #### //obfuscated for security
2023-08-04 15:13:33.610042+0100 Peakflow[4756:115897] [AWSAuthFederateToIdentityPoolTask] Starting execution
2023-08-04 15:13:33.610864+0100 Peakflow[4756:115897] [AWSAuthTaskHelper] Check if authstate configured
2023-08-04 15:13:33.611002+0100 Peakflow[4756:115897] [AWSAuthTaskHelper] Auth state configured
2023-08-04 15:13:33.612954+0100 Peakflow[4756:115897] [AWSAuthFederateToIdentityPoolTask] Waiting for federation to complete
2023-08-04 15:13:33.613052+0100 Peakflow[4756:116347] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.federatingToIdentityPool" =         {
        };
        "AuthorizationState.federatingToIdentityPool" =         {
            "FetchSessionState.notStarted" =             {
            };
        };
    };
}
2023-08-04 15:13:33.613318+0100 Peakflow[4756:116348] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InitializeFederationToIdentityPool.swift Starting execution
2023-08-04 15:13:33.613398+0100 Peakflow[4756:116348] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InitializeFederationToIdentityPool.swift Sending event FetchAuthSessionEvent.fetchAuthenticatedIdentityID
2023-08-04 15:13:33.615995+0100 Peakflow[4756:116348] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/FetchAuthIdentityId.swift Starting execution
2023-08-04 15:13:33.616064+0100 Peakflow[4756:116347] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.federatingToIdentityPool" =         {
        };
        "AuthorizationState.federatingToIdentityPool" =         {
            "FetchSessionState.fetchingIdentityID" =             {
            };
        };
    };
}
2023-08-04T15:13:33+0100 info CognitoIdentityClient : [Logging] Request: POST https:443 
 Path: / 
 User-Agent: aws-sdk-swift/1.0 api/cognito-identity/1.0 os/iOS/16.4.0 lang/swift/5.8 lib/amplify-swift/2.11.4, 
Host: cognito-identity.eu-west-2.amazonaws.com, 
Content-Length: 884, 
x-amz-user-agent: aws-sdk-swift/1.0, 
Content-Type: application/x-amz-json-1.1, 
X-Amz-Target: AWSCognitoIdentityService.GetId 
 Optional([])
2023-08-04T15:13:33+0100 info SerialExecutor : [Logging] Creating connection pool for Optional("https://cognito-identity.eu-west-2.amazonaws.com/?")with max connections: 50
2023-08-04T15:13:33+0100 info CRTClientEngine : [Logging] Connection was acquired to: Optional("https://cognito-identity.eu-west-2.amazonaws.com/?")
2023-08-04 15:13:34.201501+0100 Peakflow[4756:116349] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/FetchAuthIdentityId.swift Sending event FetchAuthSessionEvent.throwError
2023-08-04 15:13:34.201744+0100 Peakflow[4756:116348] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InformSessionError.swift Starting execution
2023-08-04 15:13:34.201835+0100 Peakflow[4756:116348] [AWSCognitoAuthPlugin] AWSCognitoAuthPlugin/InformSessionError.swift Sending event AuthorizationEvent.receivedSessionError
2023-08-04 15:13:34.203491+0100 Peakflow[4756:116347] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.federatingToIdentityPool" =         {
        };
        "AuthorizationState.federatingToIdentityPool" =         {
            "FetchSessionState.error" =             {
                error = "AWSCognitoAuthPlugin.FetchSessionError.notAuthorized";
            };
        };
    };
}
Failed to federate to identity pool with error: AuthError: Not authorized error
Recovery suggestion: Check whether the given values are correct and the user is authorized to perform the operation.
2023-08-04 15:13:34.208379+0100 Peakflow[4756:116347] [AWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.error" =         {
            Error = "AWSCognitoAuthPlugin.AuthenticationError.service(message: \"Session error: notAuthorized\")";
        };
        "AuthorizationState.error" =         {
            Error = "AWSCognitoAuthPlugin.AuthorizationError.sessionError(AWSCognitoAuthPlugin.FetchSessionError.notAuthorized, noCredentials)";
        };
    };
}

```

Is this a regression?

No

Regression additional context

No response

Platforms

iOS

OS Version

16.4

Device

iphone 14

Specific to simulators

No response

Additional context

here is my source code:

import SwiftUI
import Amplify
import AWSCognitoAuthPlugin

@main
struct MyApp: App {
    
    func configureAmplify() {
        do {
            try Amplify.add(plugin: AWSCognitoAuthPlugin())
            try Amplify.configure()
            Amplify.Logging.logLevel = .verbose
            print("Successfully configured Amplify")
        } catch {
            print("Failed to initialize Amplify:", error)
        }
    }
    
    init() {
        configureAmplify()
    }
    
    var body: some Scene {
        WindowGroup {
            SIWA()            
        }
    }
}

Content view

import SwiftUI
import AuthenticationServices
import Amplify
import AWSCognitoAuthPlugin

struct SIWA: View {
    
    func configureRequest(_ request: ASAuthorizationAppleIDRequest) {
        request.requestedScopes = [.email]
    }

    func handleResult(_ result: Result<ASAuthorization, Error>) {
        switch result {
        case .success(let authorization):
            guard
                let credential = authorization.credential as? ASAuthorizationAppleIDCredential,
                let identityToken = credential.identityToken
                    
            else { return }
            self.federateToIdentityPools(with: identityToken)            
        case .failure(let error):
            print("Line 29", error)
        }
    }
    
    func federateToIdentityPools(with token: Data) {
        guard
            let tokenString = String(data: token, encoding: .utf8),
            let plugin = try? Amplify.Auth.getPlugin(for: "awsCognitoAuthPlugin") as? AWSCognitoAuthPlugin
        else { return }
        
        print("Token string", tokenString)
        
        Task {
            do {
                let result = try await plugin.federateToIdentityPool(
                    withProviderToken: tokenString,
                    for: .apple
                )
                print("Successfully federated user to identity pool with result:", result)
            } catch {
                print("Failed to federate to identity pool with error:", error)
            }
        }
    }
    
    var body: some View {
        Text("Integrate Signin With Apple and AWS Cognito")
        SignInWithAppleButton(
            onRequest: configureRequest,
            onCompletion: handleResult
        )
        .frame(maxWidth: 300, maxHeight: 45)
    }
}

struct SIWA_Previews: PreviewProvider {
    static var previews: some View {
        SIWA()
    }
}

amplifyconfiguration.json

{
    "UserAgent": "aws-amplify-cli/2.0",
    "Version": "1.0",
    "auth": {
        "plugins": {
            "awsCognitoAuthPlugin": {
                "UserAgent": "aws-amplify/cli",
                "Version": "0.1.0",
                "IdentityManager": {
                    "Default": {}
                },
                "CredentialsProvider": {
                    "CognitoIdentity": {
                        "Default": {
                            "PoolId": "eu-west-2:###",
                            "Region": "eu-west-2"
                        }
                    }
                },
                "CognitoUserPool": {
                    "Default": {
                        "PoolId": "eu-west-2####,
                        "AppClientId": "####",
                        "Region": "eu-west-2"
                    }
                },
                "Auth": {
                    "Default": {
                        "OAuth": {
                            "WebDomain": "####auth.eu-west-2.amazoncognito.com",
                            "AppClientId": "####",
                            "SignInRedirectURI": "myapp://",
                            "SignOutRedirectURI": "myapp://",
                            "Scopes": [
                                "phone",
                                "email",
                                "openid",
                                "profile",
                                "aws.cognito.signin.user.admin"
                            ]
                        },
                        "authenticationFlowType": "USER_SRP_AUTH",
                        "socialProviders": [
                            "APPLE"
                        ],
                        "usernameAttributes": [
                            "EMAIL"
                        ],
                        "signupAttributes": [
                            "EMAIL"
                        ],
                        "passwordProtectionSettings": {
                            "passwordPolicyMinLength": 8,
                            "passwordPolicyCharacters": []
                        },
                        "mfaConfiguration": "OFF",
                        "mfaTypes": [
                            "SMS"
                        ],
                        "verificationMechanisms": [
                            "EMAIL"
                        ]
                    }
                }
            }
        }
    }
}

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

Hi! Experiencing this as well – also confident of my setup on the Apple + Cognito side.

Failed to federate to identity pool with error: The operation couldn’t be completed. (Amplify.AuthError error 4.)
2023-08-05 22:57:26.676834-0700 Waller[15593:1424041] [AuthenticationAWSCognitoAuthPlugin] Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.error" =         {
            Error = "AWSCognitoAuthPlugin.AuthenticationError.service(message: \"Session error: notAuthorized\")";
        };
        "AuthorizationState.error" =         {
            Error = "AWSCognitoAuthPlugin.AuthorizationError.sessionError(AWSCognitoAuthPlugin.FetchSessionError.notAuthorized, noCredentials)";
        };
    };
}

@howardkitto Thanks for all the information. I will try to repro this issue locally and get back to you as soon as we have more information.

Reiterating. Amplify ATM only supports federation to user pools using the signInWithWebUI API. Please follow https://github.com/aws-amplify/amplify-swift/issues/1121 for updates on supporting federation to user pools natively.

@howardkitto @adam-a

To add a Sign in with Apple identity provider (IdP)

  1. Choose Identity pools from the Amazon Cognito console. Select an identity pool.
  2. Choose the User access tab.
  3. Select Add identity provider.
  4. Choose Sign in with Apple.
  5. Enter your bundle identifier for the app as the Services ID.
  6. Provide a role. You can assign users from that IdP the Default role that you set up when you configured your Authenticated role, or you can Choose role with rules.
  7. To change the principal tags that Amazon Cognito assigns when it issues credentials to users who have authenticated with this provider, configure Attributes for access control. a. To apply no principal tags, choose Inactive. b. To apply principal tags based on sub and aud claims, choose Use default mappings. c. To create your own custom schema of attributes to principal tags, choose Use custom mappings. Then enter a Tag key that you want to source from each Claim that you want to represent in a tag.
  8. Click save.

You should be good to go.

If it still doesn’t work, could you please provide a screenshot of the identity pool provider, similar to what I am adding in this comment

image