amplify-js icon indicating copy to clipboard operation
amplify-js copied to clipboard

Unable to pass SECRET_HASH value to cognito user pool from Gen 2 auth library signIn() method

Open sagshar5 opened this issue 1 year ago • 18 comments

Environment information

System:
  OS: macOS 14.4.1
  CPU: (8) arm64 Apple M1 Pro
  Memory: 154.64 MB / 16.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 20.15.0 - /usr/local/bin/node
  Yarn: 1.22.22 - /usr/local/bin/yarn
  npm: 10.7.0 - /usr/local/bin/npm
  pnpm: undefined - undefined
NPM Packages:
  @aws-amplify/backend: 1.0.4
  @aws-amplify/backend-cli: 1.1.0
  aws-amplify: 6.3.8
  aws-cdk: 2.147.3
  aws-cdk-lib: 2.147.3
  typescript: 5.5.3
AWS environment variables:
  AWS_STS_REGIONAL_ENDPOINTS = regional
  AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
  AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables

Description

An Amazon Cognito user pool enabled with Client secret is imported to Amplify Gen 2 project.

    import { defineBackend } from '@aws-amplify/backend';
    import { auth } from './auth/resource';
    import { data } from './data/resource';

    /**
     * @see https://docs.amplify.aws/react/build-a-backend/ to add storage, functions, and more
     */
    const backend = defineBackend({
    });

    backend.addOutput({
      auth: {
        aws_region: "REGION",
        user_pool_id: "USER_POOL_ID",
        user_pool_client_id: "CLIENT_ID",
        identity_pool_id: "IDENTITY_POOL_ID",
        username_attributes: ["email"],
        standard_required_attributes: ["email"],
        user_verification_types: ["email"],
        unauthenticated_identities_enabled: true,
        password_policy: {
          min_length: 8,
          require_lowercase: true,
          require_uppercase: true,
          require_numbers: true,
          require_symbols: true,
        }
      }
    })

Unable to find any way to pass Secret_hash value to cognito using auth library signIn() or signUp() method.

Sample signIn()

    import type { FormEvent } from "react"
    import { Amplify } from "aws-amplify"

    import { signIn } from "aws-amplify/auth"
    import outputs from "../amplify_outputs.json"

    Amplify.configure(outputs)

    interface SignInFormElements extends HTMLFormControlsCollection {
      email: HTMLInputElement
      password: HTMLInputElement
    }

    interface SignInForm extends HTMLFormElement {
      readonly elements: SignInFormElements
    }

    export default function App() {
      async function handleSubmit(event: FormEvent<SignInForm>) {
        event.preventDefault()
        const form = event.currentTarget
        // ... validate inputs
        await signIn({
          username: [form.elements.email](http://form.elements.email/).value,
          password: form.elements.password.value,
          
          options: {
            authFlowType: "CUSTOM_WITH_SRP",
            clientMetadata: {
              secretHash: "IyW/XXX+pvk="
            }
          }
        })
      }

      return (
        <form onSubmit={handleSubmit}>
          <label htmlFor="email">Email:</label>
          <input type="text" id="email" name="email" />
          <label htmlFor="password">Password:</label>
          <input type="password" id="password" name="password" />
          <input type="submit" />
        </form>
      )
    }

Using above signUp() method, can see in browser console that the secretHash value is passed. However, still getting :

    400 Bad Request :: Client is configured with secret but SECRET_HASH was not received".

Can you please advise if we can use Amplify Gen 2 with Cognito user pool having client enabled client secret ?

sagshar5 avatar Jul 05 '24 15:07 sagshar5

Hey👋 thanks for raising this! I'm going to transfer this over to our JS repository for better assistance 🙂

ykethan avatar Jul 08 '24 17:07 ykethan

Hello, @sagshar5 and thanks for creating this issue. To address the question on Gen 2 support, this is NOT currently supported out of the box at this time. As such, we'll mark this as a feature request.

We'll follow up with any additional questions or updates we have on this from here, but feel free to add any additional context for use cases or implementations you're looking for in Gen 2 as well. Thanks!

cwomack avatar Jul 09 '24 20:07 cwomack

@sagshar5, did you run into this only after upgrading to v6 or using Gen2?

cwomack avatar Jul 09 '24 20:07 cwomack

Having same issue, does anyone know a workaround?

anyaname avatar Jul 19 '24 07:07 anyaname

You have to disable the client secret when you create the userPool. Unfortunately you cannot disable the client secret for a created userPool as far as I can see.

alexandreomiranda avatar Jul 23 '24 23:07 alexandreomiranda

This is very frustrating! Can't believe that amplify doesn't support the SECRET_HASH. With modern frameworks like NEXT.js that have a FE servers where the auth interactions occur.

The workaround we used was to use

import {
  CognitoIdentityProviderClient,
  InitiateAuthCommand,
} from "@aws-sdk/client-cognito-identity-provider"

ndueber avatar Sep 03 '24 21:09 ndueber

@cwomack is there an update this on this? I'm running into the same issue. This just feels like a half baked solution. Pretty poor for AWS standards.

zammitjames avatar Dec 23 '24 14:12 zammitjames

@zammitjames don't have any updates yet, but appreciate the feedback and additional comment on this. The more upvotes, followers, and comments we get from the community on feature requests like this help us gauge the interest.

I'll bring it back through to the team and if there's any further updates I'll follow up with another comment (likely after the holidays).

cwomack avatar Dec 23 '24 17:12 cwomack

I recently encountered the same issue while integrating AWS Cognito with an Elastic Load Balancer (ELB). ELB requires the use of a client secret, but our ReactJS client cannot leverage Amplify to send this information directly with signIn(). This presents another use case for supporting SECRET_HASH, which I hope your team can take into consideration.

Vinci08 avatar Jan 03 '25 14:01 Vinci08

@Vinci08, thanks for adding this context to the issue. We're reviewing this internally as a feature request and will update with another comment on any progress or news regarding this.

cwomack avatar Jan 03 '25 19:01 cwomack

I just encountered this and had to patch locally to get it working. It's also missing from sendCustomChallengeAnswer. For my purposes, I've overloaded clientMetadata to avoid changing the signature of the functions

https://github.com/wavey-ai/amplify-js/commit/a0fba1d1e01809592e1c0541cf37fdd885b9a1f6

jbrough avatar Jan 14 '25 12:01 jbrough

I found this issue too, Why can't add the secret_hash into the signIn and confirmSignIn methods. Obviously, there need the param in some situations. And change it is so easy. Why don't change it?

810307015 avatar Mar 25 '25 06:03 810307015

Is there another workaround other than to create a new user-pool without client secret, and from a security stand point of view is that fine?

root-daemon avatar Mar 26 '25 18:03 root-daemon

Hi @root-daemon,

We don't have enough knowledge for the difference yet. I have filed a ticket internally to consult with the service team. I'll keep you post for any updates.

AllanZhengYP avatar Mar 26 '25 20:03 AllanZhengYP

ok so my approach above was wrong. It seems like client apps (of the public, mobile app sort) should not send a SECRET_HASH at all (as they need a client secret to be able to generate it). Instead, the recommended workaround seems @root-daemon to use an edge lambda to inject the SECRET_HASH (so, amplify would talk to your CloudFront proxy rather than Cognito directly). https://aws.amazon.com/blogs/security/protect-public-clients-for-amazon-cognito-by-using-an-amazon-cloudfront-proxy/

This still has some benefits to help ensure logins are from your own client and not a fraudulent one, as it can be combined with WAF, being a Cloudfront proxy.

jbrough avatar Mar 31 '25 07:03 jbrough

Thanks @jbrough for sharing the information.

Hi @root-daemon Besides the doc shared above, you can also find the information you are looking for in this doc: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html

AllanZhengYP avatar Apr 01 '25 06:04 AllanZhengYP

So, if you use their CFN to deploy the WAF application to Edge via the link above, you will need to modify it to use nodejs16.x as the lambda runtime. Above that will not work. Node 16 is deprecated and will be blocked on AWS in October - I'll create a new lambda template when I have time but I'm rolling with Node 16 atm. Btw, it works great once you use node 16.

https://aws-security-blog-content.s3.amazonaws.com/public/sample/876-Protect-unauthenticated-APIs-Cognito/CloudFront-WAF.yaml

jbrough avatar Apr 01 '25 11:04 jbrough

Thanks for sharing this information and CFN template @jbrough!

jjarvisp avatar Apr 01 '25 19:04 jjarvisp

If using SPA type then client secret for a created userPool is not seen and In hosted ui if Login pages unavailable. Please contact an administrator. The Cognito UI is a bit confusing sometimes. This is just one of the quirks. Click the left nav bar "Overview" (above "Applications") . This is the "overview" of the user pool where your app client is in. On the right side under "Recommendations", there is an icon for "Apply branding to your managed login pages" , click "Configure styles". I think you use Managed Login, click [Create a Style] button to create a new style and assign it to your 2nd app.

ViviiM avatar Jul 22 '25 12:07 ViviiM

No further action from our side needed. Please refer to this document for more information. Thanks!

osama-rizk avatar Jul 23 '25 14:07 osama-rizk

Hello @cwomack, just checking if this feature update has been pushed yet. I’m currently facing the same issue.

oxblixxx avatar Aug 23 '25 11:08 oxblixxx