cognito-local
cognito-local copied to clipboard
ID token does not include attributes such as given_name, family_name, or preferred_username
The ID Token does not include attributes such as given_name, family_name, or preferred_username even though they exist on the user.
Decoded ID token:
{
"alg": "RS256",
"typ": "JWT",
"kid": "CognitoLocal"
}
{
"cognito:username": "[email protected]",
"auth_time": 1672277860,
"email": "[email protected]",
"email_verified": false,
"event_id": "171100f3-aaac-4144-ba08-34d546336515",
"iat": 1672277860,
"jti": "8dfcc238-6382-4ba7-af41-8d1e79e97135",
"sub": "f36cbdd1-253e-4d47-b7e3-04e2d92ea6c6",
"token_use": "id",
"exp": 1672364260,
"aud": "djvkg1i4saxvezvy9fsjbrcci",
"iss": "http://localhost:9229/local_1k918F3w"
}
Example user in local_ db file
{
"Users": {
"[email protected]": {
"Username": "[email protected]",
"Password": "123456789",
"Attributes": [
{
"Name": "sub",
"Value": "f36cbdd1-253e-4d47-b7e3-04e2d92ea6c6"
},
{
"Name": "preferred_username",
"Value": "[email protected]"
},
{
"Name": "email",
"Value": "[email protected]"
},
{
"Name": "given_name",
"Value": "First"
},
{
"Name": "family_name",
"Value": "Last"
}
...
Commands for setup and generating token:
aws --endpoint http://localhost:9229 cognito-idp list-user-pools --max-results 1
aws --endpoint http://localhost:9229 cognito-idp create-user-pool --pool-name userpool-name --username-attributes email
aws --endpoint http://localhost:9229 cognito-idp create-user-pool-client --user-pool-id $user_pool_id --client-name client-name --allowed-o-auth-scopes "email openid profile" --read-attributes "email" "given_name" "family_name" "preferred_username"
aws --endpoint http://localhost:9229 cognito-idp admin-create-user --user-pool-id $user_pool_id --desired-delivery-mediums EMAIL --username [email protected] --user-attributes Name=preferred_username,[email protected] Name=email,[email protected] Name=given_name,Value=First Name=family_name,Value=Last
aws --endpoint http://localhost:9229 cognito-idp admin-initiate-auth --user-pool-id $user_pool_id --client-id $client_id --auth-flow ADMIN_USER_PASSWORD_AUTH --auth-parameters [email protected],PASSWORD=123456789
The PR I've just opened resolved the issue around the given_name and family_name for us (and it could be updated to add the preferred_username as well).
Could do with some guidance on whether this is deemed the correct fix and recommendations on what the new tests should look like.
Maybe there is a better way. In cognito it might make sense to make any read, or write, attributes available in the payload
Maybe there is a better way
I agree, that was more a hack that worked enough for me to continue with some local testing
In cognito it might make sense to make any read, or write, attributes available in the payload
That seems sensible, although I think in AWS Cognito the attributes present on the token depend on which ones the client used to get token has access to read? So it seems that for accurate emulation we want to get the client and find out which ones it has access to, and also potentially add in any default ones that are always present from Cognito. Just need to investigate to confirm which ones (if any) should always be present.
Thanks for investigating this @alec-w, I think your assessment is correct that the Client would factor into which attributes should be included in the tokens.
The CreateUserPoolClient docs aren't especially helpful (as usual for Cognito), the ReadAttributes
description is just: "The read attributes" which doesn't really clarify anything, but WriteAttributes
does seem to suggest these are used for access controls: "The user pool attributes that the app client can write to."
Based off that, I think we should:
- Get all the attributes which have a value on a User
- Remove any attributes which are not present in either
ReadAttributes
orWriteAttributes
* on the Client - Any attributes left can be included in the tokens
* I'm assuming an attribute present in WriteAttributes
is implied to be readable, I don't think Cognito has write-only attributes?
If you're able to update your PR @alec-w to do this that would be amazing, otherwise I'll get to this when I can.
@alec-w @jagregory I too require this functionality for my application. I see that my real AWS ID Token has:
- family_name
- given_name
I then manually added the optional field middle_name
When I recheck my ID Token it now has middle_name
added to it.
Available Default Attrs
These are the list of attribute read and write that I can modify from my client:
same list in text format
Also listed here in AWS Docs
address
birthdate
email
email_verified
family_name
gender
given_name
locale
middle_name
name
nickname
phone_number
phone_number_verified
picture
preferred_username
profile
updated_at
website
zoneinfo
Write-Only Attrs
I'm assuming an attribute present in WriteAttributes is implied to be readable, I don't think Cognito has write-only attributes?
I unchecked birthdate
and it seems an attribute can be write-only
and not readable.
I added a value for birthdate
using AWS GUI.
Yet birthdate
was NOT present in my ID Token.
Next Steps
Would it be helpful to run the command below, to get what is listed in ReadAttributes
and WriteAttributes
?
aws cognito-idp describe-user-pool-client
For each app, you can mark attributes as readable or writeable. This applies to both standard and custom attributes. Your app can retrieve the value of attributes that you mark as readable, and can set or modify the value of attributes that you mark as writeable. If your app tries to set a value for an attribute that it isn't authorized to write, Amazon Cognito returns NotAuthorizedException. GetUser requests include an access token with an app client claim; Amazon Cognito only returns values for attributes that your app client can read. Your user's ID token from an app only contains claims that correspond to the readable attributes. All app clients can write user pool required attributes. You can only set the value of an attribute in an Amazon Cognito user pools API request when you also provide a value for any required attributes that don't yet have a value. https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html
Based on the bold text, I think these steps should be implemented (augmented from @jagregory)
- Get all the attributes which have a value on a User
- Remove from list if not in the
ReadAttributes
array - Insert list into the ID Token