aws / aws-sdk-js-v3

Modularized AWS SDK for JavaScript.
Apache License 2.0
3.05k stars 574 forks source link

Getting "SAML Assertion signature is invalid" after adding a new SAML identity provider #6201

Open ap-h opened 3 months ago

ap-h commented 3 months ago

Checkboxes for prior research

Describe the bug

Hi, when we add a new SAML identity provider to cognito user pool client and user try to login via application UI we get this error (added to the callback url): https://callback.url/?error_description=Invalid+SAML+response+received%3A+SAML+Assertion+signature+is+invalid.+&error=server_error

Decoded error: Error: Invalid SAML response received: SAML Assertion signature is invalid.

But when we go to the AWS console > cognito user pool > App integration > App client > Click client > Edit Hosted UI > Just save without changes then it works fine.

The code we use to create SAML identity provider and add it to the client:

async createSamlIdentityProvider() {
  this.cognitoIdentityProvider = new CognitoIdentityProvider()

  const createIdentityProviderParams = {
    UserPoolId: 'UserPoolId',
    ProviderName: 'providerName',
    ProviderType: IdentityProviderTypeType.SAML,
    ProviderDetails: {
      MetadataFile: '...',
    },
    AttributeMapping: { email },
  }

  const command = new CreateIdentityProviderCommand(createIdentityProviderParams)
  await this.cognitoIdentityProvider.send(command)

  const describeCommand = new DescribeUserPoolClientCommand({
    UserPoolId: 'UserPoolId',
    ClientId: 'UserPoolClientId',
  })
  const clientDetail = await this.cognitoIdentityProvider.send(describeCommand)

  const providerNames = clientDetail?.UserPoolClient?.SupportedIdentityProviders?.concat('providerName')

  const updateUserPoolClientCommand = new UpdateUserPoolClientCommand({
    UserPoolId: 'UserPoolId',
    ClientId: 'UserPoolClientId',
    SupportedIdentityProviders: providerNames,
    ...
  })

  await this.cognitoIdentityProvider.send(updateUserPoolClientCommand)
}

This is the CDK code how we create user pool and client:

this.pool = new cognito.UserPool(scope, 'user-pool', {
  autoVerify: { email: true },
  mfa: cognito.Mfa.OPTIONAL,
  mfaSecondFactor: { sms: false, otp: true },
  signInAliases: { email: true },
  standardAttributes: { email: { required: true, mutable: true } },
  userPoolName: 'user-pool',
})

this.client = new cognito.UserPoolClient(scope, 'user-pool-client', {
  generateSecret: false,
  authFlows: {
    userPassword: true,
    userSrp: true,
    adminUserPassword: true,
    custom: true,
  },
  preventUserExistenceErrors: true,
  oAuth: {
    callbackUrls: callbackUrls,
    flows: { authorizationCodeGrant: true, implicitCodeGrant: true },
    logoutUrls: logoutUrls,
    scopes: [OPENID, EMAIL, PROFILE, PHONE, COGNITO_ADMIN],
  },
  userPool: this.pool,
  userPoolClientName: 'user-pool-client',
})

this.domain = new cognito.UserPoolDomain(scope, 'domain', {
  cognitoDomain: { domainPrefix: '...' },
  userPool: this.pool,
})

SDK version number

@aws-sdk/client-cognito-identity-provider@3.583.0

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

Node 18

Reproduction Steps

Please use the code in the description to reproduce it.

Observed Behavior

Getting this error in UI after redirected from Azure login: Error: Invalid SAML response received: SAML Assertion signature is invalid. This is logged in console by amplify but also I can se the error added to the callback url.

Expected Behavior

No error

Possible Solution

Currently the workaround is to manually go to AWS cognito console and just Edit > Save the hosted UI of the user pool client without any changes.

Additional Information/Context

No response

aBurmeseDev commented 3 months ago

Hi @ap-h - thanks for reaching out.

This sounds like it's more of SAML related issue rather than AWS SDK. I'm able to run the SDK code that you shared successfully. Upon doing some research on the error, the culprit might be the metadata mismatch between SAML response and Cognito User Pool metadata. It could also be SAML attribute mapping. Is there a way for you to compare successful and failed SAML assertions?

I'm not sure what your workflow setup looks like but I'd be happy to duplicate similar setup and try to reproduce it on my end, if you can share step-by-step repro.

Here are some resources that might be useful:

Hope it helps!

ap-h commented 3 months ago

Hi @aBurmeseDev thank you for getting back to me and share the links!

The SDK and CDK codes work fine, but we get the error when we test SSO login in UI. We get the following error: SAML Assertion signature is invalid However if we just submit the Hosted UI without changes then it works. This is the confusing part.

When I search "SAML Assertion signature is invalid" in Google it just returns 8 results that are totally unrelated. I checked all links you shared but they are different error messages, am I missing something?

Sorry I'm not sure what you mean by: compare successful and failed SAML assertions Happy to provide the details you want if you can tell me what I need to do.

This is an example SAML file we use (masked values):

SAML file:

```xml LjED5k8EutKYrP+xxx/lP4= JSBTIrYoHFz1zrPR5OmCxOdxzrIF80zoQ275ogKN0HEgaswPHGxZ3im566xJ95aABHdRQifOLMkViYABYRIN4+xxx== MIIC8DCCAdigAwIBAgIQSTxxx MIIC8DCCAdigAwIBAgIQSTTRchxxx Name The mutable display name of the user. Subject An immutable, globally unique, non-reusable identifier of the user that is unique to the application for which a token is issued. Given Name First name of the user. Surname Last name of the user. Display Name Display name of the user. Nick Name Nick name of the user. Authentication Instant The time (UTC) when the user is authenticated to Windows Azure Active Directory. Authentication Method The method that Windows Azure Active Directory uses to authenticate users. ObjectIdentifier Primary identifier for the user in the directory. Immutable, globally unique, non-reusable. TenantId Identifier for the user's tenant. IdentityProvider Identity provider for the user. Email Email address of the user. Groups Groups of the user. External Access Token Access token issued by external identity provider. External Access Token Expiration UTC expiration time of access token issued by external identity provider. External OpenID 2.0 Identifier OpenID 2.0 identifier issued by external identity provider. GroupsOverageClaim Issued when number of user's group claims exceeds return limit. Role Claim Roles that the user or Service Principal is attached to RoleTemplate Id Claim Role template id of the Built-in Directory Roles that the user is a member of https://login.microsoftonline.com/78fc3e7b-3a69-4a24-b243-571ff1d015e4/wsfed https://login.microsoftonline.com/78fc3e7b-3a69-4a24-b243-571ff1d015e4/wsfed MIIC8DCCAdigAwIBAgIQSxxx https://sts.windows.net/78fc3e7b-3a69-4a24-b243-xxx/ https://login.microsoftonline.com/78fc3e7b-3a69-4a24-b243-xxx/wsfed https://login.microsoftonline.com/78fc3e7b-3a69-4a24-b243-xxx/wsfed MIIC8DCCAdigAwIBAgIQSTTRchOUiYRxxx ```