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.
The Error
Section titled “The Error”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=loginDiagnostic Checklist
Section titled “Diagnostic Checklist”- Inspect Query Parameters: Check the initial
/oauth2/authorizerequest from your application. Is theprompt=loginparameter being appended to the URL? - IdP Session Lifetime: Verify if the upstream IdP (Okta, Azure AD, Auth0) has a
MaxSessionAgeshorter than the Cognito session. - SAML ForceAuthn: If using SAML, check the
AuthnRequestXML. IsForceAuthn="true"present in the metadata or request? - Cognito Client Settings: Ensure the App Client is not configured with extremely low “Session expiration” settings for Refresh tokens.
- Cookie Interference: Check for cross-domain cookie issues (SameSite attribute) that might prevent Cognito from reading the
cognitosession cookie.
The Fix
Section titled “The Fix”1. Remove the prompt=login parameter
Section titled “1. Remove the prompt=login parameter”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:
# Ensure you are NOT passing 'login' to the prompt parameter# Incorrect:# Auth.federatedSignIn({ provider: 'MyIDP', options: { prompt: 'login' } });
# Correct:Auth.federatedSignIn({ provider: 'MyIDP' });2. Update Cognito User Pool via CLI
Section titled “2. Update Cognito User Pool via CLI”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.
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"}'3. SAML Metadata Configuration
Section titled “3. SAML Metadata Configuration”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 configurationResources: 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"4. Validate OIDC Discovery Document
Section titled “4. Validate OIDC Discovery Document”If using an OIDC provider, verify that the authorization_endpoint does not have hardcoded prompt requirements. You can inspect the configuration returned by Cognito:
curl -X GET "https://cognito-idp.<region>.amazonaws.com/<user-pool-id>/.well-known/openid-configuration" | json_ppVerify 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.