42

My app creates a custom attribute "userType" for each new signed-up user. Now I would like this "userType" claim/attribute to be added to the JWT access token whenever the user signs in or the token gets refreshed.

Is there an option to tell cognito to add my custom claim/attribute to the JWT access token? (Without a pre token generation Lambda)

Hiren Makwana
  • 1,976
  • 2
  • 13
  • 28

6 Answers6

23

Custom attributes are not available in Cognito access token. Currently it is not possible to inject additional claims in Access Token using Pre Token Generation Lambda Trigger as well. PreToken Generation Lambda Trigger allows you to customize identity token(Id Token) claims only.

stackOp
  • 731
  • 7
  • 7
  • 4
    There seems to be an exception to this: If you override the `cognito:groups` claim, it will override this in the access token as well as the ID token - see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html – Andy Dec 15 '21 at 16:23
6

The responses suggesting to use the ID Token for authorization in your backend systems are bad security practice. ID Tokens are for determining that the user is in fact logged in and the identity of that user. This is something that should be performed in your frontend. Access Tokens on the other hand are for determining that a request (to your backend) is authorized. ID Tokens do not have the same security controls against spoofing that Access Tokens have (see this blog from Auth0: https://auth0.com/blog/id-token-access-token-what-is-the-difference/).

Instead, I recommend that your backend accept an Access Token as a Bearer token via the Authorization HTTP header. Your backend then calls the corresponding /userinfo endpoint (see: https://openid.net/specs/openid-connect-core-1_0.html#UserInfo) on the authorization server that issued the Access Token, passing such said Access Token to that endpoint. This endpoint will return all of the ID Token information and claims, which you can then use to make authorization decisions in your code.

emilhdiaz
  • 81
  • 1
  • 3
  • From the [cognito docs](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-id-token.html): *The ID token can also be used to authenticate users to your resource servers or server applications* – Oliver Aug 09 '23 at 16:47
1

You can use ID token to get the token with custom attributes.

Access tokens are not intended to carry information about the user. They simply allow access to certain defined server resources.

You can pass an ID Token around different components of your client, and these components can use the ID Token to confirm that the user is authenticated and also to retrieve information about them.

How to retrieve Id token using amazon cognito identity js

cognitoUser.authenticateUser(authenticationDetails,{
  onSuccess: function(result) {
    var accessToken = result.getIdToken().getJwtToken();
    console.log('accessToken is: ' + accessToken);
  },
  onFailure: function(err) {
    alert(err.message || JSON.stringify(err));
  },
});
chetan mahajan
  • 723
  • 7
  • 9
0

I have the same problem when I want to create several microservice. There isn't a way I can customize an access token, but only an identity token. However, I use client credentials in the machine-to-machine which needs access token. So, in no way I can customize my token. At last, I decide to add such info(like user type) in the event header. It's not a very secure way compared to customize a token, but there isn't any other easy way to do it right now. Otherwise, I have to rewrite the authorizer in Cognito. Like rewriting a customize authorizer and it's very painful.

0

I have the same issue with Cognito; exist other tools like "PingFederate"Auth-server of Ping identity and Auth0 Auth-server; I know that the requirement isn't part of the standard, but these applications were my alternatives to fix this issue

0

I got it! Beautfull works

Lambda script:

const handler = async (event) => {
  const data = JSON.parse(event.request.clientMetadata.groups); # here you key from authorize
  
  const new_data = {
    custom_key_1: data,
    custom_key_2: "TEST",
  }
  event.response = {
    claimsOverrideDetails: {
      groupOverrideDetails: {
        groupsToOverride: [JSON.stringify(new_data)],
      }
    }
  };

  return event;
};

export { handler };

ACCESS_TOKEN RETURN: 'cognito:groups': ['{"custom_key_1":["admin"],"custom_key_2":"TESTE"}'],

pycognito authorize:

self.cog.authenticate(
password=password, client_metadata={"groups":json.dumps(custom_json)}
)
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 27 '23 at 09:53