Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ID token does not include attributes such as given_name, family_name, or preferred_username #360

Open
michaelrhyndress opened this issue Dec 29, 2022 · 6 comments · May be fixed by #361
Open

Comments

@michaelrhyndress
Copy link

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": "First.Last@email.com",
  "auth_time": 1672277860,
  "email": "First.Last@email.com",
  "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": {
    "First.Last@email.com": {
      "Username": "First.Last@email.com",
      "Password": "123456789",
      "Attributes": [
        {
          "Name": "sub",
          "Value": "f36cbdd1-253e-4d47-b7e3-04e2d92ea6c6"
        },
        {
          "Name": "preferred_username",
          "Value": "1234567@email.com"
        },
        {
          "Name": "email",
          "Value": "First.Last@email.com"
        },
        {
          "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 First.Last@email.com --user-attributes Name=preferred_username,Value=1234567@email.com Name=email,Value=First.Last@email.com 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 USERNAME=First.Last@email.com,PASSWORD=123456789
@alec-w alec-w linked a pull request Jan 4, 2023 that will close this issue
@alec-w
Copy link

alec-w commented Jan 4, 2023

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.

@michaelrhyndress
Copy link
Author

Maybe there is a better way. In cognito it might make sense to make any read, or write, attributes available in the payload

@alec-w
Copy link

alec-w commented Jan 15, 2023

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.

@jagregory
Copy link
Owner

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:

  1. Get all the attributes which have a value on a User
  2. Remove any attributes which are not present in either ReadAttributes or WriteAttributes* on the Client
  3. 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.

@Elte156
Copy link

Elte156 commented Jan 25, 2024

@alec-w @jagregory I too require this functionality for my application.
I see that my real AWS ID Token has:

  • email
  • 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.
image

Available Default Attrs

These are the list of attribute read and write that I can modify from my client:
image
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.
image

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

@Elte156
Copy link

Elte156 commented Jan 25, 2024

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)

  1. Get all the attributes which have a value on a User
  2. Remove from list if not in the ReadAttributes array
  3. Insert list into the ID Token

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants