Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refresh token issues #3337

Closed
smclelland opened this issue Oct 31, 2023 · 9 comments
Closed

Refresh token issues #3337

smclelland opened this issue Oct 31, 2023 · 9 comments
Assignees
Labels
auth Issues related to the Auth category question General question

Comments

@smclelland
Copy link

smclelland commented Oct 31, 2023

We've been using Amplify/Cognito for several years without issue. We started noticing that users are suddenly being signed out after token refresh fails. We are using 2.21.1 of amplify-swift. I'm not seeing anything obvious on our end that might have caused this.

After calling:

Amplify.Auth.fetchAuthSession()

It throws:

The operation couldn’t be completed. (Amplify.AuthError error 6.)

@harsh62 harsh62 transferred this issue from aws-amplify/aws-sdk-ios Nov 1, 2023
@harsh62
Copy link
Member

harsh62 commented Nov 1, 2023

Transferred the issue from @aws-sdk-ios to @amplify-swift.

@harsh62 harsh62 added auth Issues related to the Auth category question General question labels Nov 1, 2023
@harsh62
Copy link
Member

harsh62 commented Nov 1, 2023

To help us debug further, would you be able to provide the following details?

  1. The entire verbose logs you see in the console when the issue happens . You can enable verbose logging to the console by doing this before calling Amplify.configure:
Amplify.Logging.logLevel = .verbose
  1. The contents of your amplifyconfiguration.json file with sensitive information removed.

@harsh62 harsh62 added the pending-community-response Issue is pending response from the issue requestor label Nov 1, 2023
@smclelland
Copy link
Author

After turning on verbose logging I noticed a few errors. Despite these errors my auth is still valid at this point. I haven't found a way to trigger the issue where the refresh fails consistently.

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: .../amplify-swift/AmplifyPlugins/Core/AWSPluginsCore/Keychain/KeychainStoreError.swift function: recoverySuggestion line: 69)

No existing device metadata found. AuthEnvironment(configuration: AWSCognitoAuthPlugin.AuthConfiguration.userPools(["region": "<REDACTED>", "hostedUI": "N/A", "clientSecret": "(nil)", "clientId": "29ni****0sjp", "pinpointAppId": "(nil)", "poolId": "us-w****6kM1", "endpoint": "N/A"]), userPoolConfigData: Optional(["region": "<REDACTED>", "hostedUI": "N/A", "clientSecret": "(nil)", "clientId": "29ni****0sjp", "pinpointAppId": "(nil)", "poolId": "us-w****6kM1", "endpoint": "N/A"]), identityPoolConfigData: nil, authenticationEnvironment: Optional(AWSCognitoAuthPlugin.BasicAuthenticationEnvironment(srpSignInEnvironment: AWSCognitoAuthPlugin.BasicSRPSignInEnvironment(srpAuthEnvironment: AWSCognitoAuthPlugin.BasicSRPAuthEnvironment(userPoolConfiguration: ["endpoint": "N/A", "poolId": "us-w****6kM1", "region": "<REDACTED>", "clientId": "29ni****0sjp", "hostedUI": "N/A", "clientSecret": "(nil)", "pinpointAppId": "(nil)"], cognitoUserPoolFactory: (Function), eventIDFactory: (Function), srpClientFactory: (Function), srpConfiguration: (nHexValue:

Here is amplifyconfiguration.json

{
    "auth": {
        "__Environment": "Dev",
        "plugins": {
            "awsCognitoAuthPlugin": {
                "IdentityManager": {
                    "Default": {}
                },
                "CognitoUserPool": {
                    "Default": {
                        "PoolId": "us-west-2_xxxxxxxxx",
                        "AppClientId": "xxxxxxxxxxxxxxxxx",
                        "Region": "us-west-2"
                    }
                },
            }
        }
    }
}

@smclelland
Copy link
Author

Here are the events leading up to that error:

`
AWSCognitoAuthPlugin/InitializeRefreshSession.swift Starting execution
AWSCognitoAuthPlugin/InitializeRefreshSession.swift Sending event RefreshSessionEvent.refreshCognitoUserPool
AWSCognitoAuthPlugin/RefreshUserPoolTokens.swift Starting execution
Auth state change:

{
"AuthState.configured" = {
"AuthenticationState.signedIn" = {
deviceMetadata = "["noData": "noData"]";
signInMethod = "AWSCognitoAuthPlugin.SignInMethod.apiBased(AWSCognitoAuthPlugin.AuthFlowType.userSRP)";
signedInDate = "2023-11-01 01:27:48 +0000";
tokens = "["idToken": "eyJw", "accessToken": "eyHw", "expiry": 2023-11-01 16:44:14 +0000, "refreshToken": "ey*****_Q"]";
userId = "1c********************************32";
userName = "li**********40";
};
"AuthorizationState.refreshingSession" = {
existing = userPoolOnly;
refreshState = {
"RefreshSessionState.refreshingUserPoolToken" = {
};
};
};
};
}

tcp_output [C2.1.1:3] flags=14 seq=2,860,365,088, ack=3,699,069,078, win=2,032 state=0 rcv_nxt=3,699,069,078, snd_una=2,860,365,064
AWSCognitoAuthPlugin/LoadCredentialStore.swift Starting execution
Credential Store state change:

loadingStoredCredentials
AWSCognitoAuthPlugin/LoadCredentialStore.swift Retreiving credential deviceMetadata(username: "lima.golf.8340")
AWSCognitoAuthPlugin/LoadCredentialStore.swift Sending event CredentialStoreEvent.throwError
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: /Users/steve2/Library/Developer/Xcode/DerivedData/Lightning-fsowyplhrvflemfzmjodghqvhztm/SourcePackages/checkouts/amplify-swift/AmplifyPlugins/Core/AWSPluginsCore/Keychain/KeychainStoreError.swift
function: recoverySuggestion
line: 69)
`

@harsh62
Copy link
Member

harsh62 commented Nov 1, 2023

These errors that you see are more of warnings.. I will work with my team to correct this logging type. Even if you see these errors, your Auth should just work fine. I see that your user pool config is also correct.

To help on this further, I would need the entire verbose logs when the refresh token issue happens.

@harsh62 harsh62 self-assigned this Nov 1, 2023
@smclelland
Copy link
Author

smclelland commented Nov 1, 2023

Ok it just happened. Had a valid signed in user yesterday. Launched the app today and it's signed out.

AWSCognitoAuthPlugin/InitializeAuthConfiguration.swift Starting execution
AWSCognitoAuthPlugin/MigrateLegacyCredentialStore.swift Starting execution
Credential Store state change:

migratingLegacyStore
AWSCognitoAuthPlugin/MigrateLegacyCredentialStore.swift Sending event CredentialStoreEvent.loadCredentialStore
Credential Store state change:

loadingStoredCredentials
AWSCognitoAuthPlugin/LoadCredentialStore.swift Starting execution
AWSCognitoAuthPlugin/LoadCredentialStore.swift Retreiving credential amplifyCredentials
AWSCognitoAuthPlugin/LoadCredentialStore.swift Sending event CredentialStoreEvent.throwError
AWSCognitoAuthPlugin/IdleCredentialStore.swift Starting execution
No existing session found.
AWSCognitoAuthPlugin/IdleCredentialStore.swift Sending event CredentialStoreEvent.moveToIdleState
AWSCognitoAuthPlugin/InitializeAuthConfiguration.swift Sending event AuthEvent.validateCredentialAndConfiguration
AWSCognitoAuthPlugin/ValidateCredentialsAndConfiguration.swift Starting execution
AWSCognitoAuthPlugin/ValidateCredentialsAndConfiguration.swift Sending event AuthEvent.configureAuthentication
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: /Users/steve2/Library/Developer/Xcode/DerivedData/Lightning-fsowyplhrvflemfzmjodghqvhztm/SourcePackages/checkouts/amplify-swift/AmplifyPlugins/Core/AWSPluginsCore/Keychain/KeychainStoreError.swift
function: recoverySuggestion
line: 69)
AWSCognitoAuthPlugin/InitializeAuthenticationConfiguration.swift Starting execution
Credential Store state change:

idle
AWSCognitoAuthPlugin/InitializeAuthenticationConfiguration.swift Sending event AuthenticationEvent.configure
Auth state change:

{
    "AuthState.validatingCredentialsAndConfiguration" =     {
    };
}
Auth state change:

{
    "AuthState.configuringAuthentication" =     {
        "AuthenticationState.notConfigured" =         {
        };
    };
}
AWSCognitoAuthPlugin/ConfigureAuthentication.swift Start execution
Auth state change:

{
    "AuthState.configuringAuthentication" =     {
        "AuthenticationState.configured" =         {
        };
    };
}
AWSCognitoAuthPlugin/ConfigureAuthentication.swift Sending event AuthenticationEvent.initializedSignedOut
Auth state change:

{
    "AuthState.configuringAuthentication" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
    };
}
AWSCognitoAuthPlugin/ConfigureAuthentication.swift Sending event AuthEvent.authenticationConfigured
AWSCognitoAuthPlugin/InitializeAuthorizationConfiguration.swift Starting execution
Auth state change:

{
    "AuthState.configuringAuthorization" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.notConfigured" =         {
        };
    };
}
AWSCognitoAuthPlugin/InitializeAuthorizationConfiguration.swift Sending event AuthorizationEvent.configure
Auth state change:

{
    "AuthState.configuringAuthorization" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.configured" =         {
        };
    };
}
AWSCognitoAuthPlugin/ConfigureAuthorization.swift Starting execution
AWSCognitoAuthPlugin/ConfigureAuthorization.swift Sending event AuthEvent.authorizationConfigured
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.configured" =         {
        };
    };
}
Starting execution
Check if authstate configured
Auth state configured
Fetching current state
No session found, fetching unauth session
Waiting for session to establish
AWSCognitoAuthPlugin/InitializeFetchUnAuthSession.swift Starting execution
AWSCognitoAuthPlugin/InitializeFetchUnAuthSession.swift Sending event FetchAuthSessionEvent.throwError
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.fetchingUnAuthSession" =         {
            "FetchSessionState.notStarted" =             {
            };
        };
    };
}
AWSCognitoAuthPlugin/InformSessionError.swift Starting execution
AWSCognitoAuthPlugin/InformSessionError.swift Sending event AuthorizationEvent.receivedSessionError
Received error - sessionError(AWSCognitoAuthPlugin.FetchSessionError.noIdentityPool, noCredentials)
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.fetchingUnAuthSession" =         {
            "FetchSessionState.error" =             {
                error = "AWSCognitoAuthPlugin.FetchSessionError.noIdentityPool";
            };
        };
    };
}
Starting execution
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.error" =         {
            Error = "AWSCognitoAuthPlugin.AuthorizationError.sessionError(AWSCognitoAuthPlugin.FetchSessionError.noIdentityPool, noCredentials)";
        };
    };
}
Check if authstate configured
Auth state configured
Fetching current state
Waiting for session to establish
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.refreshingSession" =         {
            existing = noCredentials;
            refreshState =             {
                "RefreshSessionState.notStarted" =                 {
                };
            };
        };
    };
}
AWSCognitoAuthPlugin/InitializeRefreshSession.swift Starting execution
AWSCognitoAuthPlugin/InitializeRefreshSession.swift Sending event RefreshSessionEvent.throwError
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.refreshingSession" =         {
            existing = noCredentials;
            refreshState =             {
                "RefreshSessionState.error" =                 {
                    error = "AWSCognitoAuthPlugin.FetchSessionError.noCredentialsToRefresh";
                };
            };
        };
    };
}
AWSCognitoAuthPlugin/InformSessionError.swift Starting execution
AWSCognitoAuthPlugin/InformSessionError.swift Sending event AuthorizationEvent.receivedSessionError
Received error - sessionError(AWSCognitoAuthPlugin.FetchSessionError.noCredentialsToRefresh, noCredentials)
AmplifyManager.swift:132 - Call Auth.signIn to sign in a user and then call Auth.fetchSession
AmplifyManager.swift:133 - AuthError: There is no user signed in to retreive cognito tokens
Recovery suggestion: Call Auth.signIn to sign in a user and then call Auth.fetchSession
AmplifyManager.swift:134 - There is no user signed in to retreive cognito tokens
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.error" =         {
            Error = "AWSCognitoAuthPlugin.AuthorizationError.sessionError(AWSCognitoAuthPlugin.FetchSessionError.noCredentialsToRefresh, noCredentials)";
        };
    };
}
AmplifyManager.swift:135 - Unknown underlying error
tcp_output [C4.1.1:3] flags=14 seq=567,535,226, ack=3,724,724, win=2,048 state=0 rcv_nxt=3,724,724, snd_una=567,535,226
ApolloManager.swift:129 - The operation couldn’t be completed. (Amplify.AuthError error 6.)
Starting execution
Check if authstate configured
Auth state configured
Fetching current state
Waiting for session to establish
AWSCognitoAuthPlugin/InitializeRefreshSession.swift Starting execution
AWSCognitoAuthPlugin/InitializeRefreshSession.swift Sending event RefreshSessionEvent.throwError
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.refreshingSession" =         {
            existing = noCredentials;
            refreshState =             {
                "RefreshSessionState.notStarted" =                 {
                };
            };
        };
    };
}
AWSCognitoAuthPlugin/InformSessionError.swift Starting execution
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.refreshingSession" =         {
            existing = noCredentials;
            refreshState =             {
                "RefreshSessionState.error" =                 {
                    error = "AWSCognitoAuthPlugin.FetchSessionError.noCredentialsToRefresh";
                };
            };
        };
    };
}
AWSCognitoAuthPlugin/InformSessionError.swift Sending event AuthorizationEvent.receivedSessionError
Auth state change:

{
    "AuthState.configured" =     {
        "AuthenticationState.signedOut" =         {
            lastKnownUserName = "(nil)";
        };
        "AuthorizationState.error" =         {
            Error = "AWSCognitoAuthPlugin.AuthorizationError.sessionError(AWSCognitoAuthPlugin.FetchSessionError.noCredentialsToRefresh, noCredentials)";
        };
    };
}
Received error - sessionError(AWSCognitoAuthPlugin.FetchSessionError.noCredentialsToRefresh, noCredentials)
Call Auth.signIn to sign in a user and then call Auth.fetchSession
AuthError: There is no user signed in to retreive cognito tokens

@harsh62
Copy link
Member

harsh62 commented Nov 1, 2023

@smclelland So I inspected the logs and what I can see that Amplify is not able to retrieve the session from Keychain

loadingStoredCredentials
AWSCognitoAuthPlugin/LoadCredentialStore.swift Starting execution
AWSCognitoAuthPlugin/LoadCredentialStore.swift Retreiving credential amplifyCredentials
AWSCognitoAuthPlugin/LoadCredentialStore.swift Sending event CredentialStoreEvent.throwError
AWSCognitoAuthPlugin/IdleCredentialStore.swift Starting execution
No existing session found.

This could happen because of a few reasons. Like first time installations or there was no user signed in before.

I would like to understand what steps were taken before it was launched today? Are you absolutely sure it was logged in before you launched? Its not able to refresh the tokens, because it cannot find anything.

Few more questions:

  • Was it working before correctly?
  • Did you pull an update from Amplify recently?
  • Did any other environment change? App upgrades or something else that might have happened?

@smclelland
Copy link
Author

Yes absolutely sure that it was logged in before the launch.

  • Sign in, everything is good.
  • Terminate, launch again and its good.
  • Put the app away for a while, launch it, and its suddenly logged out with the log I sent above.

Was it working before correctly?
Did you pull an update from Amplify recently?

  • Yes it was working correctly. We've been going back through our commits looking for possible changes. We did upgrade from 2.14 to to 2.21.1. We downgraded to 2.14 thinking that might have been the issue but it seems to be the same. iOS 17 was of course another recent change.

Did any other environment change? App upgrades or something else that might have happened

  • One possible guess here is that we did enable Keychain Sharing with our bundle id to share internal keychain items. I have removed that since it's not critical and will continue to test.

@smclelland
Copy link
Author

Ok, I believe this issue is resolved and was in fact caused by "Keychain Sharing". Since removing I haven't been able to replicate it.

Best guess: the keychain was shared across our apps using a common key. Since some of our users have both dev and prod builds installed on the same device and are authenticated with two different Cognito users, it might have been overwriting bits that Amplify requires for token refresh in the same keychain. This ultimately led to Cognito revoking the refresh token due to suspicious activity or a mismatch, etc.

Thanks for your help! Will close for now.

@github-actions github-actions bot removed the pending-community-response Issue is pending response from the issue requestor label Nov 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auth Issues related to the Auth category question General question
Projects
None yet
Development

No branches or pull requests

2 participants