Open hanslai opened 5 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.
@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.
@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.
@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 π
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:
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
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
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
@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.
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.
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/
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):
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.
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...
I guess that's called "Customer Obsession"...
Suffering with this also... Using cognito / amplify was one of the worst decisions of my life...
Hello guys, any news about this issue?
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.
Are there any valid work arounds? I need a custom scope in my access token
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
Same issue here. Missing custom scope from accessToken returned from AWS-Amplify. Please have your priotity on this.
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.
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
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 :/
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
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!
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 ?
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.
I would also really like an update on this.
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!
Also waiting for this to be fixed.
@abdallahshaban557 This bug has been open for multiple years now. What is the timeline on this please?
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
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.
@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.
Same here.. Is it possible to have any update on this?
Hello @adambeer @panterozo - we do not have an update yet. We will provide an update when we have the next steps clear with Cognito.
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?
@abdallahshaban557 Can you tell us why the Cognito team is not prioritizing such a crucial feature?
@PeelyZenobe - yes, you are correct!
@marcjulianfleck - they are working on enabling it ASAP. We apologize this has taken so long.
@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.
@abdallahshaban557 Any luck this month?
any update on this? It seems like aws is going down the drain, time to move to GCP.
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!
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: @.***>
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.
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.
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.
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/
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:
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"
}
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:
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..
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.
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.
Sorry, I only have a image of the source my coworker sent me.
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?