aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.44k stars 2.13k forks source link

Not able to get any OAuth or Custom Scopes in Access Token #3732

Open hanslai opened 5 years ago

hanslai commented 5 years ago

Which Category is your question related to? Cognito, Oauth2/OIDC Access Token

What AWS Services are you utilizing? Cognito User Pool

Provide additional details e.g. code snippets Using either Auth.signIn or the Vue Authentication Components are not able to get any OAuth or Custom Scopes.
oidc+scope

Sorry, I only have a image of the source my coworker sent me. Amplify+JS

I also tested, I was able to get the OAuth scopes if I use the Token Endpoint in Postman https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html

Or do we have to use https://github.com/aws/amazon-cognito-auth-js to get the scopes? But with Amplify I wonder do we still need to use this amazon-cognito-auth-js library? Actually, I am confused why there are two JS libraries for cognito.

both #1884 and #1370 have the same problem, which is not solved but closed. It has been almost a year on this issues already. Any update on this?

tobilg commented 3 years ago

@disbelief / @ravenscar It's not entirely correct that API Gateway can't be used to verify scopes in id tokens. It works as I mentioned, but to the cost that you have to change from Lambda proxy to Lambda integration method and the Lambda function responses as well, and write more IAC.

See https://medium.com/@lakshmanLD/lambda-proxy-vs-lambda-integration-in-aws-api-gateway-3a9397af0e6d for an idea.

Example in Serverless (would validate if the scope test/test is in the id token's claims):

resources:
  Resources:
    ApiGatewayAuthorizer:
      Type: AWS::ApiGateway::Authorizer
      Properties: 
        Name: cognitoAuthorizer
        Type: COGNITO_USER_POOLS
        IdentitySource: method.request.header.Authorization
        RestApiId: 
          Ref: ApiGatewayRestApi
        ProviderARNs: 
          - '#{CognitoUserPool.Arn}'

functions:
   testFunction:
    handler: src/test.handler
    memorySize: 128
    timeout: 3
    events:
      - http:
          path: test
          method: get
          cors: true
          idTokenAuthorizer: true
          integration: lambda
          request:
            template:
              application/json: '{ "test/test": "$context.authorizer.claims[''test/test'']" }'
          response:
            headers:
              Access-Control-Allow-Origin: "'*'"
              Access-Control-Allow-Credentials: "'true'"
              Access-Control-Allow-Methods: "'DELETE, POST, GET, OPTIONS, PATCH'"
              Access-Control-Allow-Headers: "'Content-Type, X-Amz-Date, Authorization, X-Api-Key, X-Amz-Security-Token, X-Amz-User-Agent'"
          authorizer:
            authorizerId: '#{ApiGatewayAuthorizer}

I agree that it's not ideal to use the id token, but at least for me that's a workaround that works (in conjunction with a PreToken trigger and a custom authorizer where I define on route level the necessary scopes to access the respective route), I'm not planning to integrate into other systems via OAuth2/OIDC anyway.

Having said that, it's a pity that Cognito/API Gateway can't currently do this out of the box, and I personally know people who have switched to Auth0 or the likes because of that.

Proposed solution: Make the PreToken trigger usable for access tokens as well, or create a new trigger with which scopes can be added/verified in access token.

I also proposed this long ago via enterprise support channels, Twitter discussions with AWS employees and also via the AWS Community Builders, to no avail unfortunately.

disbelief commented 3 years ago

@tobilg that actually doesn't sound too bad, thanks for sharing your solution. I'm going to give this a shot as it seems like less custom authentication/authorization code to write vs. rolling my own lambda function to verify, authenticate, and authorize JWT tokens.

ravenscar commented 3 years ago

@disbelief if you don't have fine-grained scopes, and are just using cognito to authenticate (this is what we are doing) have you just considered using API Gateways built in access token authenticator and telling it to use the aws.cognito.signin.user.admin scope? This way you probably don't need to do anything fancy.

disbelief commented 3 years ago

@ravenscar that's a good point. I probably should have just done that. But I've learned ever so much about velocity templates now β€” silver linings πŸ˜‚

xyklex commented 3 years ago

I've been around this specific issue several times, and I don't know if this could help but I'll still share it in case it is useful to introduce into the SDK or a new client, maybe useful to @ravenscar @disbelief

So because of the lack of allowing setting custom scopes in Amplify SDK, I did try to make use of the OAuth endpoints to see if I can reproduce the Authentication Code Flow from the shell and not directly from the browser to understand the process.

These are the steps:

  1. Call the /oauth2/authorize endpoint

    curl -X GET "https://customers-login.auth.us-east-1.amazoncognito.com/oauth2/authorize?response_type=code&
    client_id=72vvq39ev9op0cqn102jp2a51f&
    redirect_uri=http://localhost:8081/&
    state=429EA3CA-B8F5-45F9-B423-6E85DF7E2B26&
    scope=openid+profile+email" -c cookies.txt

    which gives you a redirect answer (302) but I store the cookies return with -c cookies.txt

    #HttpOnly_customers-login.auth.us-east-1.amazoncognito.com   FALSE   /       TRUE    1582913132      csrf-state-legacy       ""
    #HttpOnly_customers-login.auth.us-east-1.amazoncognito.com   FALSE   /       TRUE    1582913132      csrf-state      ""
    #HttpOnly_customers-login.auth.us-east-1.amazoncognito.com   FALSE   /       TRUE    0       XSRF-TOKEN      7e6f047a-8080-4c8c-a990-d9b85b0b0389
  2. Then I did a POST request to the value in Location: header

    curl -i -X POST -H 'Content-Type: application/x-www-form-urlencoded' "https://customers-login.auth.us-east-1.amazoncognito.com/login?response_type=code&
    client_id=72vvq39ev9op0cqn102jp2a51f&
    redirect_uri=http://localhost:8081/&
    state=429EA3CA-B8F5-45F9-B423-6E85DF7E2B26&
    scope=openid+profile+email" -d "username=<email>&password=<password>&_csrf=<XSRF-TOKEN>" -b cookies.txt -c cookies.txt

    replace: <email> with the registered email <password> with the corresponding password and <XSRF-TOKEN> with the corresponding value from the cookie file The state= value does not matter too much here and could be anything

This will return you a new Location URL in the response headers with the code value

  1. Exchange code for access tokens
    curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' "https://customers-login.auth.us-east-1.amazoncognito.com/oauth2/token" -d 'grant_type=authorization_code&client_id=72vvq39ev9op0cqn102jp2a51f&redirect_uri=http://localhost:8081/&code=97b42149-13db-4dcd-8f11-9b108cc94b0a'

This will return you an id_token, access_token, and refresh_token

tobilg commented 3 years ago

@xyklex IMHO the Cognito Auth API is documented at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-userpools-server-contract-reference.html so I'd say this is known information.

zoellner commented 2 years ago

Another problem adding to this is that the hosted UI doesn't properly support two factor authentication that was finally added recently. So there is no solution that actually works to use custom scopes and 2FA because one requires you to use the hosted UI and the other requires you to handle the login yourself.

theWebKeyGuy commented 2 years ago

Just want to share this with everyone that may need a better understanding. This was shared with me by the Amplify Staff on their discord. This helped me get a better understanding of how things were meant to be and why. Something to note when using the AWS Amplify UI components it uses the AWS Signature Version 4 signing process. This is the reason I'm assuming there are no custom scopes and it kind of makes sense why.

This is how it works behind the scenes: https://www.youtube.com/watch?v=1N0lNLHYGVs

More Info: https://docs.amplify.aws/lib/auth/overview/q/platform/js/ https://docs.amplify.aws/cli/auth/groups/

ahfx commented 2 years ago

For anyone having this issue with Postman and the OAuth 2.0 Authorization type, you also need to add the required scope in the fields provided (I spent my fair share of time googling before realizing this):

image
estebane-frb commented 2 years ago

Hi there, any updates on this? or estimates on when a fix is planned? I want to use custom scopes with the Amplify UI, not the Cognito Hosted UI.

Tran-Minh23 commented 2 years ago

You know you will have a headache day when you seeing someone faced this issue in 2019, and in 2022 you still got the same problem without any solution...

tobilg commented 2 years ago

I guess that's called "Customer Obsession"...

AWS Leadership Principles

jcardus commented 2 years ago

Suffering with this also... Using cognito / amplify was one of the worst decisions of my life...

viniarruda commented 2 years ago

Hello guys, any news about this issue?

arthurgurov commented 2 years ago

One day you decide to become a certified AWS expert... you spend a lot of time and money to achieve that. Once certified, you share your joy with all your friends and clients. You dream about modern cloud solutions with super cool architectures. You think you know everything needed to build a cool solution, not only because of fancy marketing words - you think you know this platform.

And then... then you see such sh## like this... when a super obvious thing is not working and no one plans to fix it (only 3 years passed from the initial post). I was really disappointed when I noticed almost zero customization of the hosted UI. But this... this is just ridiculous.

Now I'm at a point where I regret the decision to use Cognito because it's a real blocker for us. I have to step back and re-architect the system to use a more bullet-proof solution than Cognito.

stewberticus commented 2 years ago

Are there any valid work arounds? I need a custom scope in my access token

Tran-Minh23 commented 2 years ago

Are there any valid work arounds? I need a custom scope in my access token

I think there is a way, you can try add your users into a specific user group in Cognito. The access token can return the user group, and in the backend you can filter that claim. I hope it fits your use case

hiepluong2205 commented 2 years ago

Same issue here. Missing custom scope from accessToken returned from AWS-Amplify. Please have your priotity on this.

SonofNun15 commented 2 years ago

As mentioned by @ravenscar, the major issue for us with the Hosted UI is that we need our users to enter their email into our portal before we redirect them to the login page so that we can migrate existing users to our Cognito user pool. Requiring them to enter their email twice is absurd and there appears to be no way to inject this into the Hosted UI. Just no customizability there. But then this issue with custom scopes is just baffling.

jonaselan commented 2 years ago

To solve this problem with custom scopes + Amplify, I replace for the Cognito groups. So to check if a user has authorization, I look to "cognito:groups" instead "scopes".

Just like @Tran-Minh23 did

matthew-mcdermott commented 1 year ago

I see people saying you can use the hosted ui, but for me that doesn't even work. No matter what I try, I get no scopes. Any insight from anyone?

Also, I hope the AWS team can handle this soon :/

lisadesouza89 commented 1 year ago

I agree, I'm using the Amplify frontend for the simple integration - now I was looking to plug into other oauth based systems and my access token is missing the openid scope. Help @aws-amplify-ops

abdallahshaban557 commented 1 year ago

Hello everyone, we are discussing this request with the Cognito team. We realize this is important for you, and we will keep this issue updated when we have progress!

lisadesouza89 commented 1 year ago

Hello everyone, we are discussing this request with the Cognito team. We realize this is important for you, and we will keep this issue updated when we have progress!

Any update on this? @aws-amplify-ops ?

btodts commented 1 year ago

Hi @abdallahshaban557 , it's been a month - how did the discussion with the Cognito team go? Having custom scopes in our access tokens is the missing piece to have a production-ready setup of Cognito and Amplify for us.

AndroidDoctorr commented 1 year ago

I would also really like an update on this.

abdallahshaban557 commented 1 year ago

The Cognito team is investigating supporting this feature. We do not have exact timelines yet - but we will share them when we have more details!

cracanut1 commented 1 year ago

Also waiting for this to be fixed.

jorenvh1 commented 1 year ago

@abdallahshaban557 This bug has been open for multiple years now. What is the timeline on this please?

whimzyLive commented 1 year ago

giphy (3)

ym-herby commented 1 year ago

I am also blocked on this issue. In my use case when logging in using Google as the Identity provider I get a token with the openid scope included, which makes sense. If I user username/password login which presumably uses Cognito itself as the identity provider then the only scope that is included is the aws.cognito.signin.user.admin. How do we configure Cognito to behave like any other OIDC provider and issue an access token with the openid scope?

This is clearly an issue with the Amplify implementation because when I login using username and password using the hosted UI. The access token that is returned does indeed include the openid scope

abdallahshaban557 commented 1 year ago

Hello everyone, this issue is currently a limitation with Cognito not supporting the retrieval of custom scopes with SRP login (logging in with Email/Username and password). We are working closely with their team to get it resolved, and we will provide an update when this feature is available. We realize that this is an essential feature for providing granular Authorization, and it is a top priority for us to expose that functionality once Cognito makes it possible. We will provide updates here when we have clarity on our timelines.

adambeer commented 1 year ago

@abdallahshaban557 Sorry that you have to take the brunt of this but "top priority" shouldn't take another month. People are paying money for Cognito and Amplify. This is embarrassing.

panterozo commented 1 year ago

Same here.. Is it possible to have any update on this?

abdallahshaban557 commented 1 year ago

Hello @adambeer @panterozo - we do not have an update yet. We will provide an update when we have the next steps clear with Cognito.

PeelyZenobe commented 1 year ago

Hello everyone, this issue is currently a limitation with Cognito not supporting the retrieval of custom scopes with SRP login (logging in with Email/Username and password). We are working closely with their team to get it resolved, and we will provide an update when this feature is available. We realize that this is an essential feature for providing granular Authorization, and it is a top priority for us to expose that functionality once Cognito makes it possible. We will provide updates here when we have clarity on our timelines.

Thank you @abdallahshaban557 for letting us know this is a limitation with Cognito, and not Amplify. This is helpful when it comes to ultimately deciding if we want to use Amplify in our next project, and trying to find a workaround.

Can I ask, is the limitation you mentioned anything to do with the large callout at the top of this page? https://docs.aws.amazon.com/cognito/latest/developerguide/user-pools-API-operations.html For ease, i'll paste it here

Note Access tokens from user pools API authentication only contain the aws.cognito.signin.user.admin scope. If you instead want to generate an access token with additional scopes, for example to authorize a request to a third-party API, authenticate your users through your user pool endpoints.

Emphasis mine, to clear up any confusion it means to use the AWS Hosted UI to handle Login, instead of using the User Pools API (Which is what I assume the Auth.SignUp and Auth.SignIn functions use under the hood). So I assume that is what you are talking about?

marcjulianfleck commented 1 year ago

@abdallahshaban557 Can you tell us why the Cognito team is not prioritizing such a crucial feature?

abdallahshaban557 commented 1 year ago

@PeelyZenobe - yes, you are correct!

@marcjulianfleck - they are working on enabling it ASAP. We apologize this has taken so long.

PeelyZenobe commented 1 year ago

@PeelyZenobe - yes, you are correct!

@marcjulianfleck - they are working on enabling it ASAP. We apologize this has taken so long.

Thank you for getting back to me so fast @abdallahshaban557, I really appreciate it. It's good to hear that the Cognito team are working on enabling it ASAP :) To free you up from being a constant go-between, is there an Cognito representative in this Issue thread? Or another Issue we can track the Cognito teams progress on? As you said, it's not an Amplify problem.

jamesh38 commented 1 year ago

@abdallahshaban557 Any luck this month?

shaktiks commented 1 year ago

any update on this? It seems like aws is going down the drain, time to move to GCP.

cwomack commented 1 year ago

Hey, @jamesh38 and @shaktiks πŸ‘‹. We can't announce an exact release date just yet, but this feature is actively being worked on and planned for an upcoming release. As soon as we can communicate an actual day it will be available, we'll be sure to do so!

jamesh38 commented 1 year ago

Hey that’s awesome to hear. Thanks a lot Chris.

On Fri, Sep 22, 2023 at 1:06 PM Chris Womack @.***> wrote:

Hey, @jamesh38 https://github.com/jamesh38 and @shaktiks https://github.com/shaktiks πŸ‘‹. We can't announce an exact release date just yet, but this feature is actively being worked on and planned for an upcoming release. As soon as we can communicate an actual day it will be available, we'll be sure to do so!

β€” Reply to this email directly, view it on GitHub https://github.com/aws-amplify/amplify-js/issues/3732#issuecomment-1731756094, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA3OHUSBXCXPMN5IWIRX7F3X3XARRANCNFSM4IG2QWQQ . You are receiving this because you were mentioned.Message ID: @.***>

Ataraxia009 commented 1 year ago

hey @cwomack thanks for looking into this Just want to confirm -> the new new release will also allow custom scopes to be sent in the access token for CUSTOM_AUTH flows right? Specifically I am using the lambda trigger auth challenges and the defineAuthChallenge lambda trigger. The response is quite limited in what to feed the access token.

danfhernandez commented 1 year ago

Any update on this? Something I'm also running into unfortunately. I'm very close to choosing to migrate off of amplify and roll auth myself.

PeelyZenobe commented 1 year ago

Any update on this? Something I'm also running into unfortunately. I'm very close to choosing to migrate off of amplify and roll auth myself.

Just to be clar, you don't need to "roll auth yourself". You can still just use Cognito without Amplify. Yes you can still only get the custom scopes if you use the Amazon Cognito provided Hosted UI (Which provides all of the Authentication journeys (Signup, Login, Password Reset and MFA) out of the box), but in my investigations it turns out that custom scopes aren't really needed that often, it's an anti-pattern to use them for User Permissions and you should be using another system to handle that. Machine-to-Machine stuff can use Cognito just fine to get customer scopes.

rupertlssmith commented 11 months ago

Seems to have been fixed on Cognito User Pools: https://aws.amazon.com/about-aws/whats-new/2023/12/amazon-cognito-user-pools-customize-access-tokens/

lobaak commented 10 months ago

I'm just confirming that it is now possible to add custom scopes to the access token generated using Amplify. We were able to get this working using the steps found on:

https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html#user-pool-lambda-pre-token-generation-accesstoken

The lambda function we used is taken from the example on that page:

export const handler = function(event, context) {
  event.response = {
    "claimsAndScopeOverrideDetails": {
      "accessTokenGeneration": {
        "scopesToAdd": [
          "openid",
        ],
        "scopesToSuppress": [
          "aws.cognito.signin.user.admin"
        ]
      },
    }
  };
  // Return to Amazon Cognito
  context.done(null, event);
};

Which generates the following access token:

{
  "sub": "xxxx",
  "iss": "https://xxxx.amazonaws.com/xxxx",
  "client_id": "xxxx",
  "origin_jti": "xxxx",
  "event_id": "xxxx",
  "token_use": "access",
  "scope": "openid",
  "auth_time": 1705450802,
  "exp": 1705451102,
  "iat": 1705450802,
  "jti": "xxxx",
  "username": "xxxx"
}
sgasior commented 10 months ago

I'm just confirming that it is now possible to add custom scopes to the access token generated using Amplify. We were able to get this working using the steps found on:

https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html#user-pool-lambda-pre-token-generation-accesstoken

The lambda function we used is taken from the example on that page:

export const handler = function(event, context) {
  event.response = {
    "claimsAndScopeOverrideDetails": {
      "accessTokenGeneration": {
        "scopesToAdd": [
          "openid",
        ],
        "scopesToSuppress": [
          "aws.cognito.signin.user.admin"
        ]
      },
    }
  };
  // Return to Amazon Cognito
  context.done(null, event);
};

Which generates the following access token:

{
  "sub": "xxxx",
  "iss": "https://xxxx.amazonaws.com/xxxx",
  "client_id": "xxxx",
  "origin_jti": "xxxx",
  "event_id": "xxxx",
  "token_use": "access",
  "scope": "openid",
  "auth_time": 1705450802,
  "exp": 1705451102,
  "iat": 1705450802,
  "jti": "xxxx",
  "username": "xxxx"
}

It requires to use Advanced security features and this is very expensive feature as I know...(0.05$).

Probably for most of us using scope aws.cognito.signin.user.admin is still option 1 because of costs..

DavidWells commented 9 months ago

I was quite pleased when I saw the announcement that is was possible to modify the access token via a lambda function. https://aws.amazon.com/about-aws/whats-new/2023/12/amazon-cognito-user-pools-customize-access-tokens/

But then like @sgasior I realized it requires opting into Advanced security features. For access token customization you must enable "AdvancedSecurityMode" which blows up the cost of MAU to 0.05 per user from 0.0055 per user.

This is a 809.09% price increase per user. 😭

Surely there is a way to enable the new Pre token generation Lambda trigger to the V2_0 signature without this incredible increase in cost.

We just need this one simple feature, not everything that is included in the Advanced security features offering.

image