Cognito Access Token missing "cognito:groups" claim - amazon-web-services

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.

Related

id Token vs access_token google login api in web

I was using access_token after sign in with Google, but the Google login has changed and I am trying to use it as id_token.
I received the email and id through the existing code below.
const userInfoClient = google.oauth2('v2').userinfo;
this.oauthClient.setCredentials({
access_token: tokenData.token,
});
const userInfoResponse = await userInfoClient.get({
auth: this.oauthClient,
});
The changed code is as follows.
I receive various values ​​through the payload.
I need email and id, but id value does not exist. Is nbf equal to id in access_token?
const ticket = await client.verifyIdToken({
idToken: tokenData.token,
audience: process.env.GOOGLE_CLIENT_ID,
});
payload has values ​​such as iss,nbf,aud,sub,email,azp,name,picture,iat,exp,jti
The nbf stands for "Not Before" and it's a timestamp that specifies the time before which token cannot be used. The sub means "Subject" and is usually the user's UID that you might be looking for. Checkout RFC 7519 to learn more about the properties present in a JWT.

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

Cloud Endpoints Authentication

I am using App Engine Standard with the Python 2 runtime and Endpoints Frameworks.
When making a request, the app just returns "Successful" if the request was completed. I am trying to implement authentication so unauthenticated users are not able to complete the request. I've done the following:
Modified my main.py decorator to include issuers and audience:
issuers={'serviceAccount': endpoints.Issuer('[MYSERVICEACCOUNT]', 'https://www.googleapis.com/robot/v1/metadata/x509/[MYSERVICEACCOUNT]')},
audiences={'serviceAccount': ['[MYSERVICENAME]-dot-[MYPROJECT].appspot.com']}
Modifed my main.py method to check for a valid user:
user = endpoints.get_current_user()
if user is None:
raise endpoints.UnauthorizedException('You must authenticate first.')
Regenerated and redeployed my openAPI document. It now has security and securityDefinitions sections.
Updated my app.yaml to reference that Endpoints version.
Redeployed my app
To make an authorized request to my app, I have done the following:
I gave the service account the Service Consumer role on my Endpoints service.
Generate a signed jwt using the generate_jwt function from Google's documentation. I am passing in credentials using the service account's json key file.
payload = json.dumps({
"iat": now,
"exp": now + 3600,
"iss": [MYSERVICEACCOUNT],
"sub": [MYSERVICEACCOUNT],
"aud": [MYSERVICENAME]-dot-[MYPROJECT].appspot.com
})
Make the request using make_jwt_request function from Google's documentation.
headers = {
'Authorization': 'Bearer {}'.format(signed_jwt),
'content-type': 'application/json'}
I am getting 401 Client Error: Unauthorized for url error. Am I missing something?
Your audiences don't match; in your code, you are requiring an audience of [MYSERVICEACCOUNT], but when generating the JWT, your audience is [MYSERVICENAME]-dot-[MYPROJECT].appspot.com. These need to match.
There are few details, which might be worth checking:
The list of allowed audiences should contain the value of aud claim of a client-generated JWT token. This is what Rose has pointed out.
All of the JWT claims presented in sample client documentation are present. Your code is missing the email claim in the JWT payload dictionary.
The method you're accessing requires no specific OAuth scopes. The scopes are set as the scopes field of #endpoints.method decorator.
After opening a support ticket with Google, it turns out Google's documentation was incorrect. The main.py function needs to check for an authenticated user in the below manner:
providers=[{
'issuer': '[YOUR-SERVICE-ACCOUNT]',
'cert_uri': 'https://www.googleapis.com/service_accounts/v1/metadata/raw/[YOUR-SERVICE-ACCOUNT]',
}]
audiences = ['[YOUR-SERVICE-NAME]-dot-[YOUR-PROJECT-NAME].appspot.com']
user = endpoints.get_verified_jwt(providers, audiences, request=request)
if not user:
raise endpoints.UnauthorizedException
After making that change, I got the following error when trying to make an authenticated request:
Encountered unexpected error from ProtoRPC method implementation: AttributeError ('unicode' object has no attribute 'get')
This was caused by how I was generating the payload with json.dumps(). I generated without json.dumps() like below:
payload = {
"iat": now,
"exp": now + 3600,
"iss": [MYSERVICEACCOUNT],
"sub": [MYSERVICEACCOUNT],
"aud": [MYSERVICENAME]-dot-[MYPROJECT].appspot.com
}
These two changes fixed my issue.

Add user attribute in IdToken AWS cognito Service

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

What are the valid grant_type values for IdentityServer4 with a Client using Hybrid grant type?

Im using version version 1.0.0 of the IdentityServer4 package.
"IdentityServer4": "1.0.0"
I've created a Client
new Client
{
ClientId = "MobleAPP",
ClientName = "Moble App",
ClientUri= "http://localhost:52997/api/",
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
ClientSecrets =
{
new Secret("SecretForMobleAPP".Sha256())
},
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
"api"
},
AllowOfflineAccess = true
}
And the scope/ApiResources
public static IEnumerable<ApiResource> GetApiResources()
{
return new List<ApiResource>
{
new ApiResource("api", "My API")
};
}
With the following user/TestUser
public static List<TestUser> GetUsers()
{
return new List<TestUser>
{
new TestUser
{
SubjectId = "2",
Username = "bob",
Password = "password",
Claims = new []
{
new Claim(JwtClaimTypes.Name, "Bob Smith")
}
}
};
}
I'm trying to test the IdentityServer that I have setup from Postman and determine the possible values for the grant_type key value pair.
I can successfully connect when I set the grant_type to client_credentials and wasn't sure if there were other options for the grant_type value.
Working Postman configuration with grant_type set to client_credentials
Short answer
client_credentials is the only grant_type value you can use directly against the token endpoint when using both hybrid and client credentials grant types.
Longer answer
The client credentials grant type is the only one allowing you to hit the token endpoint directly, which is what you did in your Postman example. In that case the authentication is done against the client itself - i.e. the application you registered.
When you use the hybrid grant type, the authentication will be done against the end-user - the user using your application. In that case, you cannot hit the endpoint token directly but you'll have to issue an authorization request to IdentityServer.
When you do so, you won't use the grant_type parameter but the response_type parameter, to instruct IdentityServer what you expect back.
The possible values for response_type when you use the hybrid grant type can be found in IdentityServer constants - they are the last 3 items in the dictionary:
code id_token, which will return an authorization code and an identity token
code token, returning an authorization code and an access token
code id_token token, giving you back an authorization code, an identity token and an access token
After you get the authorization code, you'll be able to exchange it for an access token and possibily a refresh token by hitting the token endpoint.