Reputation: 1844
I want to authorize user requests to API via AWS Cognito (Google identity provider). At the moment I can recieve JWT token (id_token and access_token) from aws and authorize requests, but I did it with id_token and not with access_token. But some articles says that using id_token to authorize API request is a bad practice (sending id_token from frontend in headers) and I should use access_token. Is it possible to make same thing with access_token instead of id_token?
import boto3
id_token = get_token_from_headers(headers)
identity_client = boto3.client('cognito-identity')
id_response = identity_client.get_id(
AccountId='account_id',
IdentityPoolId='identity_pool_id',
Logins={
'cognito-idp.us-west-1.amazonaws.com/us-west-1_blabla: id_token'
}
)
response = identity_client.get_credentials_for_identity(
IdentityId=id_response['IdentityId'],
Logins={
'cognito-idp.us-west-1.amazonaws.com/us-west-1_blabla': id_token
})
access_key = response['Credentials']['AccessKeyId']
secret_key = response['Credentials']['SecretKey']
session_key = response['Credentials']['SessionToken']
Looks like it is able to get temporary credentials with access_token from assume_role_with_web_identity
link to docs, but the docs says that WebIdentityToken
argument for this methods only accepts access_token in cases when as oAuth providers are Amazon and Facebook
Upvotes: 2
Views: 1682
Reputation: 2797
It seems that retrieving the temporary credentials via AWS Cognito Identity pools is always via identity token: https://docs.aws.amazon.com/cognito/latest/developerguide/google.html
Successful authentication results in a response object that contains an id_token, which Amazon Cognito uses to authenticate the user and generate a unique identifier
I do not think that this is breaching the security as AWS Cognito Identity Pools are specifically set up to work with the identity tokens and you can configure what IAM role will be assigned to your temporary AWS credentials based on the identity token returned to you from Identity pool: https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html, https://docs.aws.amazon.com/cognito/latest/developerguide/role-based-access-control.html
You should however not send the Google id_token to the (I assume AWS based) API where you get the AWS temporary credentials. Instead, you should get the AWS temporary credentials on the client and then call AWS resources with Signature V4 header.
Alternatively, if your API can assume the AWS service role and you don't need to get temporary AWS credentials, you can use the AWS Cognito User Pools. They also support Google identity provider - https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-social-idp.html
For API hosted on EC2, you can't really use Cognito Identity Pools generated security credentials as you can't effectively control EC2 HTTP(S) port access via IAM policies. Your EC2 hosted application can however accept the Google id_token and validate it - https://developers.google.com/identity/sign-in/web/backend-auth#:~:text=After%20you%20receive%20the%20ID,to%20verify%20the%20token's%20signature. There is no reason to use identity pool, and there is no security risk of authenticating API access by Google id_token as the token is signed by Google and you can verify that on your API. You can also use Cognito User Pools: You retrieve the access token from the user pool on the client and send it to the API hosted on the EC2. You then validate access token on the hosted application - https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html
If your EC2 is accessed through the Elastic Load Balancer, you can shift user authentication to ELB level. You can use Cognito User Pools or Google identity provider user authentication - https://docs.aws.amazon.com/elasticloadbalancing/latest/application/listener-authenticate-users.html
For Amazon API Gateway you can use Cognito Identity Pools: Your security credentials generated on the client will allow execution of the given API Gateway, and you enable IAM authentication on the API Gateway - https://aws.amazon.com/premiumsupport/knowledge-center/iam-authentication-api-gateway/. You can also use the Cognito User Pools: You retrieve the access token from the user pool on the client and send it to API Gateway which has Cognito authentication enabled - https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html
Upvotes: 2