Cognito: Federated Identity Id and User Attributes - amazon-web-services

Story:
I have a Cognito User Pool with Users.
This User Pool is an authentication provider in a Federated Identity Pool.
I have an S3 bucket where users are limited to uploading to a private path via a policy on the Auth Role as follows:
arn:aws:s3:::BUCKET_NAME/${cognito-identity.amazonaws.com:sub}/*
The users upload directly from the web browser via the aws javascript sdk.
Now this works great and my users are limited to where they upload. The files they upload end up with paths in the bucket looking like this:
us-east-1:0f26319c-1233-4c71-afb6-fac96a798ffb/random_file_name.txt
I then have a lambda which is triggered from this S3 bucket whenever a file is added. To clarify, the user does NOT invoke the lambda
Problem:
I would like to access the user's attributes in the user pool from the lamda. I thought that I could do this lookup using the cognito-identity sub. However, I can't seem to find a way using the SDK api's to allow this.
Using this api:
http://boto3.readthedocs.io/en/latest/reference/services/cognito-identity.html#CognitoIdentity.Client.describe_identity
I am able to get the login / the user pool but not the username associated with this Identity ID.
If I had the username, then I could use the api: http://boto3.readthedocs.io/en/latest/reference/services/cognito-idp.html?highlight=cognito#CognitoIdentityProvider.Client.admin_get_user
Any ideas how I can use the Federated Identity ID to lookup the user's attributes?

Unfortunately, I don't believe this is possible. The reason is, as far as I understand, technically the federated identity ID doesn't have to represent a user pool user. If you connected other authentication providers to the identity pool users could have completely different properties, for example.

What about storing files in
arn:aws:s3:::BUCKET_NAME/${cognito-idp.us-east-1.amazonaws.com:sub}
This will be resolved to the folder names like
f4cfd4a8-0e94-4287-8c5e-1b01538dd2a1
Using this sub of user from Cognito User Pool you can list users with that sub, for example in cli:
aws cognito-idp list-users --user-pool-id=us-east-1_ndhjGJQYE --filter "sub = 'f4cfd4a8-0e94-4287-8c5e-example'"

Related

Is there any way to get the user details from aws cognito without using AWS_KEY_ID And AWS_SECRET_KEY

Im using aws cognito and php sdk for user authentication and on website I want to list all the user names from cognito since I didn't saved the names in the database. The problem is I don't have aws key id and secret id. But i have pool id, client id and client secret key. Is there any way to fetch the details?
You need some kind of access with AWS Cognito rights. From client side you can't query all the users so you have to query them from server-side. Good part that you're using PHP SDK. If your PHP application is running on any AWS compute service like EC2 or Lambad then you don't need IAM Access Keys. You can use IAM Roles and attach the role with the services (EC2, Lambda, etc.) IAM roles behave same as Access Keys.
Sample code to list users in PHP can be found in the documentation below:
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-cognito-idp-2016-04-18.html#listusers

AWS DynamoDB with Cognito user-scoped access?

I am using AWS Cognito for user management. I want users of my application to store their data in DynamoDB. So I need user-scoped access (User A can write data and only read data added by User A, User B being able to only read data added by User B).
Docs suggest the ability to have row-level and column-level fine grain access: (https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/specifying-conditions.html).
BUT I am not using IAM, I am using Congito users (want it scoped to each user, not a Role/Group). This doc suggests you can use Cognito ID: (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_dynamodb_items.html).
However, according to this StackOverflow question (How to use DynamoDB fine grained access control with Cognito User Pools?), it's not what I am expecting?
Does AWS support my use-case? Lot of docs but its not clear if my use-case is supported.
You need to use Cognito identity pool. Cognito identity pool acts as an identity broker. When a Cognito user authenticates using the user pool, then Cognito provides JWT tokens. User can use ID token provided by Cognito user pool and Cognito identity pool can take the token and provide temporary IAM credentials.
I am familiar with a similar use case as of yours. In that use case, user who has written data to S3 can only modify/delete that data. In this case, you can create new S3 folders (prefixes) for each user's Identity ID (provided by Cognito identity pool) and that particular user can access data under that S3 folder only.
I am not much familiar with DynamoDB access control, hence not able provide the exact solution now. You can try a similar approach as the above one.
https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-create-identity-pool.html

AWS Cognito UserPool vs IdentityPool: Is IdentityPool mandatory?

Is using an IdentityPool mandatory with AWS Cognito?
My use case:
My web app has users who can self-signup and will be added to the Cognito UserPool I have set up. I only want to provide access to my backend resources to authenticated users (ie., users belonging to an authenticatedRole IAM role). My requirement is simple enough that a single authenticated role suffices to handle my application's resource authorization requirements and I just want to deny access to all backend resources for non-authenticated users.
Is this possible with just the UserPool and if yes, how do I go about accomplishing this?
Note: I am using CDK to define my Infrastructure as code.
Using an identity pool is by no means mandatory with Cognito. It is completely on a use case basis. A few things to clarify here.
Userpool - For authentication
Identity Pool - For authorization.
Basically, if you want your end users to sign-up, sign-in, and then access AWS resources or make AWS API calls, then you would have to use an Identity pool. So let’s say you have a gaming application where the end user can sign in via FB, Google, or natively (username and password). This is authentication, and here we would be using a Cognito user pool. Now the user, is logged in and playing the game. They make a high score. This high score may need to be added to S3 or a DynamoDB table record for the user. For this, an identity pool is used. An identity pool will help you with vending temporary AWS credentials that the end user can use.
I believe in your use case the userpool should be sufficient. You can grant access to your resources by verifying the access token returned by Cognito for the end user.

Authenticate s3 request based on both file and request

Let's say I want to store some files for each user which is using my website on s3. Later I want authenticate each request to s3 to make sure that user has access to the files she is requesting. I guess this can't be done using presigned URLs or signed cookies(using cloud front). So which Amazon service should I use for that? What is the simplest way to achieve this?
Lets saying I'm authenticating users using jwt and its possible to recognize wheather a user has access to a file or not by the filename and content of the jwt.
I'm sorry that I don't have enough reputation to comment so I'll post an answer here.
One solution is:
AWS Cognito (Federated Identities)
S3 (one bucket)
S3 bucket policies allow you to restrict access to "user folders" equivalent here to "identity" by the prefix like yourbucket/<cognito_identity_id>/* Each user on your webpage will have its own federated identity.
When you create and configure the identity pool in AWS define a custom authentication provider and authenticate users "by the developer" in your backend.
Also, associate the authenticated identities to one IAM Role with access to the S3 bucket where you will keep the data. The bucket policy will take care of only allowing each user to their files and not to others. (See referenced links for policy example and more)
Amazon S3: Allows Amazon Cognito Users to Access Objects in Their Bucket
Access to User level folders using Amazon S3 and Cognito
Developer Authenticated Identities (Identity Pools)

Allow Cognito user to Write to S3

I have an embedded device that requires the ability to write to S3. I want to avoid giving the embedded device an actual AWS IAMUser. I am looking at using Cognito to gain write access to S3.
I have a user pool with a group and one user (for now). The group has an attached policy which permits access to write to a certain S3 bucket. The pool is setup so that only admins can create new users. I have managed to authenticate the cognito user and have got access to refresh tokens and the idTokens. I am looking to use these tokens to write to my s3 bucket.
I am trying to follow trying to follow the documentation but am getting confused. I think i need a federated identity pool but i have no requirement for a public provider. I just want my cognito user group to write to s3.
Is there a simple solution to allow a cognito user to write to S3 without federated identities or if not do i require a back end to serve a token for a federated identity?
I have been using warrant https://github.com/capless/warrant to authenticate as so:
from warrant.aws_srp import AWSSRP
import boto3
client = boto3.client('cognito-idp')
aws = AWSSRP(username='<username>', password='<password>', pool_id='<pool>',
client_id='<clientid>', client=client)
tokens = aws.authenticate_user()
Any tips would be greatly appreciated!
You do need a federated identity pool. In the identity provider section you choose Cognito and enter your pool ID and pool client ID. Then, you need to provide the identity pool with authenticated and unauthenticated roles. You can use these roles to provide that S3 write access.
This is the default behavior for the identity provider setup. If you want the Role to come from the group that your user is in, you will need to set the Choose role from token option in the identity provider section under where you provided your pool and client id.