GithubHelp home page GithubHelp logo

Comments (8)

ottokruse avatar ottokruse commented on July 3, 2024

Hi @bedaka

Those cookie settings you pasted look good (the vanilla values, should work).

Is the app client allowed to refresh tokens? (Does it allow ALLOW_REFRESH_TOKEN_AUTH)

400 I've see reported here before had to do with some conflicting set up in Cognito. Such as:

  • Using a client with a secret but running the deployment with EnableSpaMode = true
  • Federating to another IDP, but not having proper attribute mappings

See this search: https://github.com/aws-samples/cloudfront-authorization-at-edge/issues?q=is%3Aissue+400

Looking at the code again, I see there's not much logging to help you in this case:

throw new Error(`Status is ${res.status}, expected 200`);

It would be great to add e.g. console.log(res.data?.toString()) there, then we'd see the response value from Cognito (not always helpful either but who knows).

If you're deploying using SAM CLI, you can add that logging yourself in the code and redeploy (increase the value for parameter VERSION then, to ensure CloudFormation really redeploys the Lambda functions)

from cloudfront-authorization-at-edge.

ottokruse avatar ottokruse commented on July 3, 2024

It would be helpful to know:

  1. How did you deploy? (Serverless Application Repository, or SAM CLI, or ...)
  2. What parameter values did you use? (e.g. is CreateCloudFrontDistribution set to true, are you bringing you own user pool and client? Etc)

from cloudfront-authorization-at-edge.

bedaka avatar bedaka commented on July 3, 2024

Thanks for your reply.

To answer your follow up questions:

  • There is no "App client secret" set in the Cognito App client
  • we do federate to a seperate IDP (Azure AD) via SAML but since the login worked I assumed that our attribute mappings are correct. "Enable IdP sign out flow" is enabled.
  • We use our own User Pool and Cloudfront Distribution. The UserPool is located in a different region as the Cloudfront.
  • We deploy with CDK (using the CfnApplication Construct) with these parameters:
parameters: {
        CreateCloudFrontDistribution: 'false',
        AlternateDomainNames: `example.com`,
        EnableSPAMode: 'true',
        OAuthScopes: ['email', 'openid'].join(','),
        UserPoolArn: outputs.get('UserPoolArn'),
        UserPoolClientId: 'name',
        RewritePathWithTrailingSlashToIndex: 'false',
}

this is the header of my request and the decoded JWTs in case this is of interest:

amplitude_id_5b66b1a209cXXXXX_our_domain.com=XXXX;
amp_5b66b1=f6d857dd-8db9-4523-af3XXXXXXXXXXXXXXXX;
amplitude_id_dba089949XXXXXXX_our_domain.com=XXXX;
amp_dba089=iZx_lSj4bItoXmfxE_VP71.ZjBjZThlYzXXXXXXXXXX;
amp_326633=Mq67UonvBjDnfLJi99MZlK.MDdkZjhXXXXXXXXXXXXXX;
CognitoIdentityServiceProvider.qwertzuiopqwertzuiop.LastAuthUser=[email protected];
CognitoIdentityServiceProvider.qwertzuiopqwertzuiop.azuread_name@our-domain.com.tokenScopesString=email openid;
CognitoIdentityServiceProvider.qwertzuiopqwertzuiop.azuread_name@our-domain.com.userData=%7B%22UserAttributes%22%3A%5B%7B%22Name%22%3A%22sub%22%2C%22Value%22%3A%220cc3284d-3017-46b2-b227-bc380b433f0e%22%7D%2C%7B%22Name%22%3A%22email%22%2C%22Value%22%3A%22name%40our-domain.com%22%7D%5D%2C%22Username%22%3A%22azuread_name%40our-domain.com%22%7D;
amplify-signin-with-hostedUI=true;
CognitoIdentityServiceProvider.qwertzuiopqwertzuiop.azuread_name@our-domain.com.idToken=;
CognitoIdentityServiceProvider.qwertzuiopqwertzuiop.azuread_name@our-domain.com.accessToken=;
CognitoIdentityServiceProvider.qwertzuiopqwertzuiop.azuread_name@our-domain.com.refreshToken=;
spa-auth-edge-nonce=1234567890;
spa-auth-edge-nonce-hmac=asdfgh-asdfg

idToken: {
  "at_hash": "LtXtcxxxxxxx",
  "sub": "0cc3284d-xxxxxxxxx",
  "cognito:groups": [
    "eu-central-1_XXXXXX_AzureAd"
  ],
  "email_verified": false,
  "iss": "https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_XXXXXXXX",
  "cognito:username": "[email protected]",
  "nonce": "1TCTBEud5e8geAO_XXXXXXXXXXX",
  "origin_jti": "38c6c8f1-XXXXXXXXXXXX",
  "aud": "7kq22gd6xxxxxxxxxx",
  "identities": [
    {
      "userId": "[email protected]",
      "providerName": "AzureAd",
      "providerType": "SAML",
      "issuer": "https://sts.windows.net/3124141-xxxxxxxxxxxx/",
      "primary": "true",
      "dateCreated": "1647502726514"
    }
  ],
  "token_use": "id",
  "auth_time": 1651579835,
  "exp": 1651582835,
  "iat": 1651579835,
  "jti": "dd4bca55-xxxxxxxxxxxxxxxx",
  "email": "[email protected]"
}

accessToken: {
  "sub": "xxxxx",
  "cognito:groups": [
    "eu-central-1_XXXXXX_AzureAd"
  ],
  "iss": "https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_XXXXXX",
  "version": 2,
  "client_id": "7kq22gd6erxxxxxxxxx",
  "origin_jti": "38c6c8f1-2046xxxxxxx",
  "token_use": "access",
  "scope": "openid email",
  "auth_time": 1651579835,
  "exp": 1651582835,
  "iat": 1651579835,
  "jti": "b957c5da-0d90-xxxxxxxxxxx",
  "username": "[email protected]"
}

I'll try to add the advanced logging as you recommended and see if it generated new insights.

from cloudfront-authorization-at-edge.

bedaka avatar bedaka commented on July 3, 2024

The advanced logging as you suggested provided this message:

Error: Failed to refresh tokens: Error: Status is 400, expected 200. 
Data: {"error":"invalid_grant"} [log region: eu-central-1] 

from cloudfront-authorization-at-edge.

ottokruse avatar ottokruse commented on July 3, 2024

Thanks for the extra info.
Just to make sure, can you confirm that the app client has ALLOW_REFRESH_TOKEN_AUTH = true ?

Also, you mentioned the signin button does not work. Do you have more info on that?

from cloudfront-authorization-at-edge.

bedaka avatar bedaka commented on July 3, 2024

Yes sorry I forgot to mention that ALLOW_REFRESH_TOKEN_AUTH is set to true.

But actually I might have figured out the issue. The "Sign in" Button redirects to /signout but the Cloudfront behaviour rule is named "signOut" (uppercase O). Therefore the the Sign in Button currently does not work, because it just gets redirected to the /refreshauth page again. I'll try to rename the behaviour rule.

Unrelated to that I wonder why the refreshAuth lambda does not realize that my token is expired but instead tries to query cognito. The "invalid_grant" error seems to be a reasonable reponse in case the refresh token is expired but woudn't the correct response be to clear the client cookies so that it can log in again instead of throwing an error?

from cloudfront-authorization-at-edge.

ottokruse avatar ottokruse commented on July 3, 2024

Ahh so the token was expired. Great that you found the reason and know now why the button didn’t work.

You can’t tell if a refresh token is expired or not, the only way is to try to use it. (It’s an encrypted JWT that only Cognito can decrypt)

Since the “invalid grant” is an error that can happen in other cases as well, you don’t know it refresh token expired is the reason for it. But it would probably be good to add to the error message a text like “this is likely because your refresh token is expired. Please sign-in again”

from cloudfront-authorization-at-edge.

bedaka avatar bedaka commented on July 3, 2024

Fixing the Behavior rules name did work.

Thank you very much for your support 🙏🏽

from cloudfront-authorization-at-edge.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.