Can I use Cognito Access Token to generate an ID Token? - amazon-web-services

Is it possible to use the Cognito Access Token to generate an ID Token? I couldn't find any documentation on this online.
I'm trying to get an ID Token with custom claims, but the existing solutions don't work for my situation (details here). As a workaround, I'm thinking of manually asking Cognito for an ID Token directly with the Access Token after the user logs in.
What I tried
calling Cognito's /oauth2/userinfo endpoint only returns the basic claims, not the custom claims I had added via the pre token generation lambda trigger.
Adding custom claims/attributes to the access token. Seems like that's not supported.
Idea I haven't explored: use Amplify and somehow get ID Token through there?

You can use your access token to call the getUser method on the Cognito API:
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUser.html
That will provide the user attributes:
https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html
This provides the same data as you get on the ID token.

No.
If you need attributes inside an ID token, excluding open id claims such as exp, iss, aud, then maybe it's possible.
But if you need ID token (compliant with OIDC standard claims), then it is only issued by cognito upon specific cognito events.
The purpose of the ID token is to identify the user. ID token is often sent along the Authorisation header of a request to the backend server to be validated as a security measure. Knowing the purpose of the ID token, it will not be strange to understand why there are only specific ways to obtain the ID token.

Related

AWS Cognito: Why do you need an ID Token? [duplicate]

Just reading the docs, they seem very similar to me so I can't really discern why to use one over the other. Although identity token seems better since it has custom attributes on it from the user pool (eg: custom:blah and the default ones like name and email).
Right now, I am working with an app that passes the access token back down to the browser so it can use it for making ajax REST calls (there is an auth filter that expects this access token and validates it). Could I just switch out the access token with the id token? The current validation logic is to just get the sub field (the uuid) from the access token, but this sub field is also present in the identity token (as well as practically every other attribute except the aud which I don't need). I just want to make sure I am understanding this right as it is confusing to me why both tokens exist and seem so similar.
The id_token is for your application to process, so you can get all the personal details for your user, like their name, age, email address etc. Generally speaking you shouldn't send this token anywhere else as it contains sensitive user data.
The access_token is used to call other 'external' services (and by external I include other AWS services - these are often called over http). It provides service access authorisation for your user without having to include their personal details.
On the face of it this appears slightly confusing as you can actually use the id_token to access services in the same way as the access_token. However, good practise is to use the access_token in this circumstance and if backend services need user data, they should look it up themselves in Cognito.
EDIT: If you need to authenticate an api call based on claims in the identity token, there are circumstances when this is perfectly valid. But be aware of what details are in the identity token, and whether those claims are suitable to send to the particular API. If you don't need to use any claims from the id_token, use the access_token as this reduces the amount of potentially sensitive data you are sending.
The thing that wasn't obvious from documentation for me about the difference:
If you are using pretoken trigger function and want to add additional information to the claims with claimsToAddOrOverride , you need to use an id token because this information doesn't exist in the access token.
For ex:
event.response = {
claimsOverrideDetails: {
claimsToAddOrOverride: {
'userProfileID': id,
}
},
}
I've expected it in the AppSync resolver with lambda function as source
Speaking about AWS User Pool tokens:
Identity token is used to authenticate users to your resource servers or server applications. For example, if you use Cognito as authorizer in AWS API Gateway you need to use Identity token to call API.
The purpose of the access token is to authorize API operations in the context of the user in the user pool. For example, you can use the access token to grant your user access to add, change, or delete user attributes.
The header for the access token has the same structure as the ID token. However, the key ID (kid) is different because different keys are used to sign ID tokens and access tokens.

Cognito User Pools & Access Tokens

I am hoping to use Cognito and User Pools to support a multitenant environment. So far it checks most of the boxes. It is my understanding that there is no current way to enrich the access token using Lambda triggers. I would really like to pass something to identify which user pool the user authenticated with in the access token to my APIs. Am I missing something or is there a workaround for this?
One option that came to mind is to create a group in each to which all members of the pool are members off that is either the name or combination of the name and tenant id. Is this a reasonable approach or a horrible idea? something like tenant_1234. Then I believe this group would be included in the access token and can be parsed to get the id.
Thanks.
I may had misunderstood the question, however access token payload contains the user pool Id https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-access-token.html#user-pool-access-token-payload
Issuer (iss)
The iss claim has the following format:
https://cognito-idp.{region}.amazonaws.com/{userPoolId}.
You can also add the custom scopes to the access token to customize the payload further

Should resource_owner/User-id be included in the OAuth 2.0 Access Token response?

This is a problem we are confronted with today. I looked online as much as I can before deciding to ask the question here.
The question is, when a user makes a "Access Token Request" with a username/password, should the Access Token response contain "user-id" field?
The OAuth 2.0 spec says there can be an extra field (search for "example_parameter" in the spec) as part of the access token response. Can this extra field be user-id?
However, Many of the companies like facebook/google/twitter does not provide user-id as part of the access token response. User-id is provided as part of the validate token response.
What are the reasons for not providing user-id as part of the Access Token response? Why do we have to make another call (an extra round trip) if we need a user-id? What are the consequences of providing user-id as part of the Access Token response?
Most applications don't want to leak their user-ids to the UI layer. It is generally considered bad practice. If you send the userid to the UI layer, the UI will have the ability to request information about that UserId, and get information about it back...
This presents a security issue, as the client can generally modify these calls to get information about other UserIDs... If you are going to authenticate each call each time to validate that the token is bound to that user id, then it likely is a waste to have the client pass the userid itself, you are already doing the lookup, so you might as well keep the data internal to the service.
This also sets you up nicely to change your concept of a UserId in the future, maybe changing it to be group id, or an email address instead of the database userid...
Oauth2.0 is an authorisation framework and doesn't deal with user authentication.
The question is, when a user makes a "Access Token Request" with a
username/password, should the Access Token response contain "user-id"
field? In this context the resource
It's really a client requesting an access token and in many cases a client doesn't want to know about the id of the resource owner it just wants a token to allow it it call an endpoint on the resource server. The resource server can identity the user from the contents of the access token.
OpenID Connect can be used to extend OAuth2.0 to include an ID token. This gives basic user info in a standard format without the need to call a further endpoint.
An access token is a normally a bearer token that allows you to call an API. In OpenID Connect, you use the access token to call an api called the user_info endpoint, which returns a JSON object that contains information about the person, like first name, last name, etc. If you are looking for a free open source central authentication server that supports OAuth2, you should look at the Gluu Server http://gluu.org

How to verify a facebook token and user id?

I encounter a problem about to verify facebook user id and access token. In the app you need to register with facebook to get started. When an user get authenticated with facebook, we send the token and user_id to backend to insert into related table. But we have to know that the token belongs to the user. We saw a couple soution about it:
https://stackoverflow.com/a/8608017/1664109
And this
https://stackoverflow.com/a/20518868/1664109
So how to verify a token and user_id without send request to facebook ? Is there a way ?
based on Facebook's documentation:
as Facebook makes changes to what is stored in them and how they are
encoded.
I would say it's not possible to reliably "parse" a token.
Without sending a request to Facebook? No. But you can use the Access Token with a call to the /me endpoint. You will get the ID, and you can compare it to your stored one.

Get username from oAuth2 access token API Manager

The use case occurs once user is authenticated and obtain an oAuth2 access token from Wso2 API Manager and we want to obtain username again from this access token.
To obtain access token I've followed normal steps published on: [API Manager] (http://docs.wso2.org/display/AM160/Token+API#TokenAPI-GeneratingaccesstokenswithusercredentialspasswordgranttypeGenerating)
Does WSO2 AM provide any REST method to solve it?
Yes.. There would be two ways that you can obtain user name
APIM would return the user name with the Access token. Here user name would be embedded with the access token. You can find more details from here
You can obtain the user name and user's attribute during access token verification process. Once access token is verified successfully, It would return back with JWT token which contains user's attributes. Then you can extract use name from JWT. You find more details on here. Basically inside the APIM, you can extract JWT token in transport header. But, if you want to retrieve the JWT token for the use of your application, you can send the access token to "OAuth2TokenValidationService" service and validate it and then it return back with JWT. (But "OAuth2TokenValidationService" is a web service.). You can use web service client to invoke this service (such as SOAPUI)