How to add array values in Claims of IdToken in Cognito using claimsToAddOrOverride
Asked Answered
S

3

12

I am using Pre Token Generation to update the claims of IdToken.

I am successfully able to update claim using single key:value pair. Below is the sample example of that.

event["response"] = {"claimsOverrideDetails":{"claimsToAddOrOverride":{"scope": "test.debug"}}}

But when i am trying to add array of string inside that, it giving me internal server error (Response from AWS Cognito)

Ex:

event["response"] = {"claimsOverrideDetails":{"claimsToAddOrOverride":{"scope": ["test1","test2]}}}

It is working fine using 'Test' option of lambda function.

If i am using groupsToOverride then it is overriding the cognito:groups claim.

Any help?

Spitsbergen answered 29/3, 2018 at 12:34 Comment(2)
There's a AWS Forums post about this too (also unanswered at this time): forums.aws.amazon.com/thread.jspa?messageID=835981&#835981Exhibitive
^ link now dead sadly.Orgeat
H
11

I think this must be a bug with Cognito and unfortunately will require a workaround until it's resolved.

It's not ideal I know, but I've worked around this issue by using a delimited string which I then parse to an array when I receive the token.

Lambda:

exports.handler = (event, context, callback) => {
    event.response = {
        "claimsOverrideDetails": {
            "claimsToAddOrOverride": {
                "scope": "test1|test2"
            }
        }
    };

    // Return to Amazon Cognito
    callback(null, event);
};

Client:

const token = jwt.decode(id_token);
const scopes = token.scope.split('|');
Hydrozoan answered 29/11, 2018 at 9:50 Comment(3)
Yes probably. Right now i am also using the same way, I have used , as delimited string :)Spitsbergen
this is still a bug 2y later - seems using a string and then parsing the claim is the workaround for now.Edette
or just stringify the array :)Moratorium
A
2

As annoying as it is, this is behaving as documented here.

The response.claimsOverrideDetails.claimsToAddOrOverride where you correctly are adding the claims you want added to the jwt takes a StringMap type, which is an object with all key value pairs having all values being strings.

This is in spite of the fact that some of the claims provided by AWS and passed into the PreTokenGeneration lambda are not strings, such as auth_time which is a number.

I find this particuarly annoying when I want to add a 'isRegistrationComplete' boolean to the jwt (which is used to force display of the pages to collect final registration details). I need to pass it in as:

{
  isRegistrationComplete: "true"
}

or

{
  isRegistrationComplete: "false"
}

Hence for your array, you must encode it as a string first.

You can do this for any object (including your array) using JSON.stringify() in the lambda code, and JSON.parse() code in your client.

You can find this documented on this page (find the text: "claimsToAddOrOverride": {"string": "string"},)

Airliner answered 16/3, 2023 at 3:40 Comment(1)
Yeah. seems like a fine workaround to use JSON.stringify() and JSON.parse(), no need for over complicated custom delimited mapping required this way.Franklinfranklinite
P
0

The name scope have special meaning in a JWT, libraries expect this to be a list in string form separated by space. So the scopes test1 and test2 would become "test1 test2".

I would recommend using space as separator and not any other format. If you prefer another format just give your field a different name - like group.

{
  "iss": "https://authorization-server.example.com/",
  "sub": " 5ba552d67",
  "aud":   "https://rs.example.com/",
  "exp": 1544645174,
  "client_id": "s6BhdRkqt3_",
  "scope": "openid profile reademail"
}
Porras answered 26/5, 2021 at 11:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.