Skip to content

Fix: AWS Cognito Forced IdP Reauthentication Loop

In a multi-tenant or federated environment using AWS Cognito, users may encounter a scenario where the system ignores existing session cookies and forces a redirect to the external Identity Provider (IdP) for every request. This typically occurs when the application or the Cognito Hosted UI incorrectly passes parameters that override the standard Single Sign-On (SSO) behavior, or when session durations between Cognito and the upstream IdP are mismatched.

When monitoring the network trace during the OAuth2 flow, you will observe the authorize endpoint being called with parameters that trigger a fresh login. In the browser console or application logs, you might see:

[DEBUG] Cognito identity provider returned a redirect to /oauth2/authorize
[WARN] Federated re-authentication triggered: prompt=login detected.
[ERROR] OAuth2 Flow interrupted: User prompted for credentials despite active session.
URL: https://<domain>.auth.<region>.amazoncognito.com/oauth2/authorize?response_type=code&client_id=xyz&prompt=login
  1. Inspect Query Parameters: Check the initial /oauth2/authorize request from your application. Is the prompt=login parameter being appended to the URL?
  2. IdP Session Lifetime: Verify if the upstream IdP (Okta, Azure AD, Auth0) has a MaxSessionAge shorter than the Cognito session.
  3. SAML ForceAuthn: If using SAML, check the AuthnRequest XML. Is ForceAuthn="true" present in the metadata or request?
  4. Cognito Client Settings: Ensure the App Client is not configured with extremely low “Session expiration” settings for Refresh tokens.
  5. Cookie Interference: Check for cross-domain cookie issues (SameSite attribute) that might prevent Cognito from reading the cognito session cookie.

The most common cause is the application frontend explicitly requesting a fresh login. Ensure your SDK (Amplify or generic OIDC client) is not injecting this parameter.

If using AWS Amplify, verify the federatedSignIn call:

Terminal window
# Ensure you are NOT passing 'login' to the prompt parameter
# Incorrect:
# Auth.federatedSignIn({ provider: 'MyIDP', options: { prompt: 'login' } });
# Correct:
Auth.federatedSignIn({ provider: 'MyIDP' });

If the issue persists due to IdP-specific requirements, you can adjust the User Pool Client settings using the AWS CLI to ensure token validity is handled correctly.

Terminal window
aws cognito-idp update-user-pool-client \
--user-pool-id <your-user-pool-id> \
--client-id <your-client-id> \
--refresh-token-validity 30 \
--access-token-validity 1 \
--id-token-validity 1 \
--token-validity-units '{"AccessToken": "hours", "IdToken": "hours", "RefreshToken": "days"}'

For SAML-based providers, ensure your Identity Provider is not configured to force re-authentication. In your SAML provider configuration (e.g., Azure Enterprise App), check the ForceAuthn setting. If you must modify the Cognito side via CloudFormation/YAML, ensure the Idp configuration does not enforce specific constraints that trigger re-auth.

# Example snippet for SAML IdP configuration
Resources:
UserPoolIdentityProvider:
Type: AWS::Cognito::UserPoolIdentityProvider
Properties:
ProviderName: "SAML-IdP"
UserPoolId: !Ref MyUserPool
ProviderType: "SAML"
ProviderDetails:
MetadataURL: "https://idp.example.com/metadata"
IDPSignout: "true"
AttributeMapping:
email: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"

If using an OIDC provider, verify that the authorization_endpoint does not have hardcoded prompt requirements. You can inspect the configuration returned by Cognito:

Terminal window
curl -X GET "https://cognito-idp.<region>.amazonaws.com/<user-pool-id>/.well-known/openid-configuration" | json_pp

Verify that the scopes_supported and response_types_supported align with what the application is sending. If the app sends a scope the IdP doesn’t recognize, some IdPs default to re-challenging the user instead of returning a specific error.