Description
When calling Amplify.Auth.signInWithWebUI with a SAML provider, the method completes and returns result.isSignedIn == true immediately after the Cognito Hosted UI redirects back to the app via deep link.
However, calling fetchAuthSession() (even with forceRefresh: true) right after that often fails to return tokens. userPoolTokensResult.hasValue is false or accessing .value throws an exception.
The tokens only become available after a short period because the authorization code exchange happens asynchronously in the background. This creates a race condition that makes it difficult to reliably retrieve the access token or id token right after SAML login.
The issue is much more noticeable with SAML compared to social providers (Google, Facebook, etc.).
Categories
Steps to Reproduce
- Configure a Cognito User Pool with a SAML Identity Provider.
- Set up correct OAuth callback URLs and deep link scheme (AndroidManifest.xml is already configured correctly).
- Perform login:
final result = await Amplify.Auth.signInWithWebUI(
provider: const AuthProvider.saml('SSO'), // replace with your exact provider name
);
print('isSignedIn: ${result.isSignedIn}'); // → always returns true
5. Immediately attempt to fetch tokens:
final session = await Amplify.Auth.fetchAuthSession(
options: const FetchAuthSessionOptions(forceRefresh: true),
) as CognitoAuthSession;
final accessToken = session.userPoolTokensResult.value.accessToken.raw; // ← frequently fails or has no value on first attempt
Expected behavior
After signInWithWebUI returns isSignedIn: true, fetchAuthSession() should reliably return the user pool tokens immediately, or Amplify should provide a clear mechanism (callback, future, or event) to know when the token exchange has completed.
There should be no race condition between the redirect returning to the app and token availability.
Platforms
Flutter Version
3.32.8
Amplify Flutter Version
2.6.0
Deployment Method
Amplify Gen 2
Description
When calling Amplify.Auth.signInWithWebUI with a SAML provider, the method completes and returns result.isSignedIn == true immediately after the Cognito Hosted UI redirects back to the app via deep link.
However, calling fetchAuthSession() (even with forceRefresh: true) right after that often fails to return tokens. userPoolTokensResult.hasValue is false or accessing .value throws an exception.
The tokens only become available after a short period because the authorization code exchange happens asynchronously in the background. This creates a race condition that makes it difficult to reliably retrieve the access token or id token right after SAML login.
The issue is much more noticeable with SAML compared to social providers (Google, Facebook, etc.).
Categories
Steps to Reproduce
final result = await Amplify.Auth.signInWithWebUI(
provider: const AuthProvider.saml('SSO'), // replace with your exact provider name
);
print('isSignedIn: ${result.isSignedIn}'); // → always returns true
5. Immediately attempt to fetch tokens:
final session = await Amplify.Auth.fetchAuthSession(
options: const FetchAuthSessionOptions(forceRefresh: true),
) as CognitoAuthSession;
final accessToken = session.userPoolTokensResult.value.accessToken.raw; // ← frequently fails or has no value on first attempt
Expected behavior
After signInWithWebUI returns isSignedIn: true, fetchAuthSession() should reliably return the user pool tokens immediately, or Amplify should provide a clear mechanism (callback, future, or event) to know when the token exchange has completed.
There should be no race condition between the redirect returning to the app and token availability.
Platforms
Flutter Version
3.32.8
Amplify Flutter Version
2.6.0
Deployment Method
Amplify Gen 2