Add user attribute in IdToken AWS cognito Service - amazon-web-services

Consider I Have Following Attribute In user pool
username
first-name
last-name
location
How to add All attribute in IdToken after successful authentication

As per the ID Token specification, the response claim doesn't have these attribute values (user name, first & last name, location etc.).
However, as part of the standard claim, you can get these attributes using USERINFO endpoint.
ID Token

Related

Cognito Access Token missing "cognito:groups" claim

The documentation states that Access Token contains the cognito:groups claim.
Other answers (https://stackoverflow.com/a/68311699/1302308) suggest adding the openid scope, but this scope is already enabled:
Using currentAuthenticatedUser, the signInUserSession payload has all 3 tokens (accessToken, idToken, and refreshToken):
But the accessToken payload is missing cognito:groups along with all custom attributes:
auth_time: 1675179728
client_id: "xxxxxxxxxxxxxxxxxxxxxx"
event_id: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx"
exp: 1675183327
iat: 1675179728
iss: "https://cognito-idp.us-west-2.amazonaws.com/us-west-2_xxxxxxxxxx"
jti: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx"
origin_jti: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx"
scope: "aws.cognito.signin.user.admin"
sub: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx"
token_use: "access"
username: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx"
The idToken has a cognito:username but that's the only Cognito related attribute provided.
I have a previous user pool that this one is based off (same Serverless configuration) which does provide the cognito:groups attribute. I am migrating to this user pool to allow case insensitivity.
If it's not the openid scope, is there something else that I'm missing?
I've made sure that the openid scope has been added, tried adding aws.cognito.signin.user.admin scope, and have compared setting between my working user pool and the one that is not working.

Why can't I get more attributes from google provider via cognito UserInfo endpoint?

I have configured google provider via cognito user pool and I am able to login through google and get user information. And I have added many attributes on the attribute mapping page as shown in below screenshot.
The endpoint I am using to get user info is https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html.
The response data for user info is always:
data: {
identities: '[{"userId":"xxxx","providerName":"Google","providerType":"Google","issuer":null,"primary":true,"dateCreated":1587772412295}]',
email_verified: 'true',
email: 'xxxx#gmail.com',
username: 'Google_1xxxx'
}
Regardless how I update the attribute mappings, I always see above response. Why can't I get additional attributes like picture, given_name, birthday etc. Do I need to set any permission on google side?
In app client setting, I have below configuration:
In authorized scope, I have set: email openid profile

How can i get the user id from facebook url?

How can i get the user id from facebook url and get the basic info ?
This will be possible if i use the http://www.facebook.com/[username] '
In order to get the ID of a Facebook User, you need to authorize the User: https://developers.facebook.com/docs/facebook-login/
After that, you will get an "App Scoped ID" for that User with this API endpoint: https://graph.facebook.com/me?access_token=[user-token]
It is NOT possible to get the ID of a user by his username (or URL). Scraping is not allowed on Facebook - that i what some platforms do. But you do not need that ID anyway, you can just use the App Scoped ID instead.

How does timed JSON web signature serializer work?

Can I restrict actions of my API to specific users if I generate a token like this:
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
expiration = 600
s = Serializer(current_app.config['SECRET_KEY'], expires_in = expiration)
return s.dumps({ 'id': kwargs.get('user_id') })
And the verification
#staticmethod
def verify_auth_token(token):
s = Serializer(app.config['SECRET_KEY'])
try:
data = s.loads(token)
except SignatureExpired:
return None # valid token, but expired
except BadSignature:
return None # invalid token
user = User.query.get(data['id'])
return user
I don't understand how this works and achieves security. The way I'm used to securing an API for example, a user wants to do HTTP PUT to /posts/10 I'd usually get the post's author ie user_id then query the database get the token for that user_id, if the request token matches the queried token then it is safe for the PUT. I've read this article and don't fully understand how it achieves security without storing anything in a database. Could someone explain how it works?
By signing and sending the original token upon login the server basically gives the front end an all access ticket to the data the user would have access to, and the front end uses that token (golden ticket) on all future requests for as long as the token is not expired (tokens can be made to have expiration or not). The server in turn knows the token has not been tampered with, because the signature is basically the encrypted hash of the users recognizable data (user_id, username, etc). So, if you change the token information from something like:
{"user_id": 1}
to something like:
{"user_id": 2}
then the signature would be different and the server immediately knows this token is invalid.
This provides an authentication method that exempts the server from having to have a session, because it validates the token every time.
Here is an example of what a token could look like (itsdangerous can use this format of JSON web tokens)

Rest Replay Attacks / Security

let me describe a simple scenario:
There is a rest resource represented by this URI: /api/messages/{userid}. After the user is logged in, a request is dispatched passing to this URI "userid" (logged user). This way, as soon as the user logs in, he gets his own messages based on his ID.
If user is not logged yet, the URI is not visible (there is a authentication filter).
The problem is: if a already logged user discover this uri, he can submit a request passing another ID what will lead to a security problem because he will be able to get messages from another user (simply passing any random ID).
Can you propose any security model to prevent this security flaw ? (what I believe its more likely a cross-cutting concern).
Thanks, in advance!
Just off the top of my head, have the endpoint either (a) only return those messages visible by the logged-in user, or (b) only return messages if the logged-in user is the same as the userId in the URI. Which one depends on your business rules.
In the endpoint you can check for the user and then see if that user id matches the pathparam
finding the userid from the user name is as easy as selecting the id using the user name from a database
import javax.ws.rs.core.Context;
import javax.ws.rs.core.SecurityContext;
import ... blablabla;
#GET
#Path("messages/{userid}")
public Response getMessages( #PathParam("userid") int userId, #Context SecurityContext context ) {
String username = context.getUserPrincipal().getName();
int id = getIdFromName(username); // define this yourself
if(userId==id) {
// output the message list
List<Message> msgs = getDemMessagesGURL(); // define this yourself
return Response.ok(new GenericEntity<List<T>>(msgs) {}).build();
} else {
// output Forbidden(403)
return Response.status(403).build();
}
}
and with oauth you can use a servlet filter to set the user principal based on the oauth signiture