awsdocs / aws-doc-sdk-examples

Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.
Apache License 2.0
9.4k stars 5.6k forks source link

[Enhancement]: React example with PKCE authorization-code grant #6800

Closed holmesjr closed 1 week ago

holmesjr commented 2 weeks ago

Background story

The React example currently in the repo uses one of the least secure methods of authentication possible:

https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cognito-identity-provider/scenarios/cognito-developer-guide-react-example/frontend-client/src/authService.ts#L13

Even the AWS docs mention that USER_PASSWORD_AUTH should be replaced: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-authentication-flow.html#amazon-cognito-user-pools-user-migration-authentication-flow

An example with the PKCE authorisation code grant should be created. As per https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html,

As a best security practice in public-client apps, activate only the authorization-code grant OAuth flow, and implement Proof Key for Code Exchange (PKCE) to restrict token exchange. With PKCE, a client can only exchange an authorization code when they have provided the token endpoint with the same secret that was presented in the original authentication request. For more information on PKCE, see IETF RFC 7636.

What does this example accomplish?

The existing React example at https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/cognito-identity-provider/scenarios/cognito-developer-guide-react-example/frontend-client serves as a basis for the new example.

Which AWS service(s)?

Cognito

Which AWS SDKs or tools?

Are there existing code examples to leverage?

https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/cognito-identity-provider/scenarios/cognito-developer-guide-react-example/frontend-client

Do you have any reference code?

No response

cpyle0819 commented 1 week ago

Thanks for submitting this. I'll tag the example author.

AMZ-brandon commented 1 week ago

Hi!

The React example is a showcase of authentication with the Cognito user pools API. The API doesn't do standard OIDC flows like PKCE with the authorize endpoint. It has significant differences from the OAuth/OIDC flow including scopes available to the access token, but most importantly it doesn't do the authorization-code grant that PKCE is built on. An example flow with PKCE would use a standard OIDC client library. Instead, this example uses an AWS SDK, with a client library that maps to the user pools API - see here: https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javascriptv3/example_code/cognito-identity-provider/scenarios/cognito-developer-guide-react-example/frontend-client/src/authService.ts#L4 More on API vs OAuth authentication models here: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pools-API-operations.html

That said, this example uses USER_PASSWORD_AUTH when it could use Secure Remote Password with the recommended USER_SRP_AUTH and abstract the plaintext password from the transit path. We don't implement that in this example for a couple of reasons:

  1. This example is linked to our getting started content and is intended to be the simplest baseline. For similar reasons, we use InitiateAuth, not the IAM-authenticated admin sign-in operations that require AWS credentials and would be the recommended implementation for a webserver of this type that can secure server-side credentials.
  2. We don't have an official first-person SRP library to use in examples, and we wanted to avoid dependencies on third-party libraries to the extent we could. There is a well-tested JavaScript SRP implementation here that you could sample as you expand from the test application baseline. There are also many JS SRP implementations you can choose from. I'm told that Amplify does SRP under the hood too, and if you dig enough in the JS library you can find their implementation.

We are working on additional examples to encompass a client implementation of the OAuth model with PKCE as well as client-side and server-side auth with SRP.

AMZ-brandon commented 1 week ago

I'm going to consider this question answered and resolve it.