AWS provides cognito which provides the developer with sign-up and sign-in functionality including federations with OpenId compatible identity providers such as facebook, google etc.
There are two types of categories in cognito developer console. These are managing user pool and managing federated identities.
I'm just a little bit confused because both are very similar even we want to provide our client to login with their facebook account.
The cognito user pool itself provides federation and federation identity pool also provide it by authentication providers.
The question is that if I want to allow my clients to use their own facebook account for sign-in, which categories should I use? user pool or federated identities?
In addition, if I want to configure authorizer in API gateway I have to create cognito user pool but federated identity pool. Is that the main reason choosing the cognito category?
Cognito user pool:
Amazon Cognito User Pool makes it easy for developers to add sign-up
and sign-in functionality to web and mobile applications. It serves as
your own identity provider to maintain a user directory. It supports
user registration and sign-in, as well as provisioning identity tokens
for signed-in users.
Cognito Federated Identities or Identity Pool:
Cognito Identity Pool (or Cognito Federated Identities) on the other
hand is a way to authorize your users to use the various AWS services.
Say you wanted to allow a user to have access to your S3 bucket so
that they could upload a file; you could specify that while creating
an Identity Pool. And to create these levels of access, the Identity
Pool has its own concept of an identity (or user). The source of these
identities (or users) could be a Cognito User Pool or even Facebook or
Google.
Relationship between User pool and Identity pool:
The Cognito Identity Pool simply takes all the identity providers and puts them together (federates them). And with all of this it can now give your users secure access to your AWS services, regardless of where they come from.
So in summary, the Cognito User Pool stores all the users which then plugs into Cognito Identity Pool which can give the users access to AWS services.
source
You can think of user pools as sort of a directory which contains user attributes such as name, email, phone number etc. This also provides sign up, sign in capability. You can federate users into user pools. Currently you can use Facebook, Google, and SAML as identity providers for user pools.
Cognito Federated identities lets you federate users into AWS and vends AWS credentials that can be used to access the resources you allow in your policy. For Cognito Federated Identities, you also have a variety of identity providers that you can configure such as Facebook, Google, and also Cognito User Pools can be an identity provider.
What you use depends on your use case. If you don't require AWS resources for your app, probably User Pools is all you need.
I believe AWS should separate User Pool and Identity Pool, and change the names. Because mixing up different services under the same name causes confusions, and the names do not give any clue about the services.
User Pool -> AWS Authentication and Token vending service, similar to Auth0. You can use Auth0 instead of unnecessarily complicated User Pool
Identity Pool -> AWS IAM Authorization service for the authentication tokens such as Auth0 token or AWS JWT token (from User Pool)
An analogy would be:
Use Pool is an agency in your country that identifies who you are and issues a VISA (The VISA is the token which the Identity Provider provides you as a user).
Identity Pool is the border control of the foreign country called "AWS" that you visit with the VISA. They verify who you are with the VISA and authorize what you can do in there. If the border control does not recognize the VISA, you cannot do anything. If they recognize it, then they have fine grained rules defined for each VISA what actions are allowed and where.
Forget about User Pool
Better focus on Identity Pool. Because User Pool is just another Identity Provider service like MSAD, Google, Facebook, Auth0, etc. An Identity Provider authenticates and provides a token e.g. Kerberos Token for a MS AD users, or a Cognito Userpool JWT token for a AWS Cognito Userpool user. Then Identity Pool can utilize the token to authorize access to AWS resources.
AWS has been mixing up this Identity Provider/Authentication service with Identity Pool/Authorization service, besides their strange naming, hence causing massive confusions, incurring the questions.
The name "Identity Pool" does not make any sense as it has no indication on what the service does. A word must navigate thinking that leads to understanding, not confusion. AWS exactly does the opposite.
Preparation
Before jumping to what Identity Pool does/is, better to understand a few things.
AWS STS Token
Naively saying, AWS STS Token allow us to create, use, update, delete AWS resources programmatically.
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
If you have an AWS account user, you can get AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY for the user, and then get a STS token using e.g. MFA.
IAM Role
In reality, an IAM Role defines which actions allowed on which AWS resources for a STS token. It may not allow delete but create. So it depends on the IAM Role what a STS Token allows us to do.
However, the point to note is, there is a association between an IAM Role and a STS Token you get, and someone must define the association for you.
What Identity Pool gives you
It gives a STS Token, using which you can manipulate AWS resources in an AWS account.
Situation where Identity Pool is useful
Another problem of AWS for me is their documentation does not declare This is when you need Identity Pool, but instead keep repeating the word Federation which does not point to what Identity Pool does, allow you to manipulate AWS resources with a STS Token.
If you are in the situation where:
I want to manipulate AWS resources in an AWS account, and
I do not have an AWS IAM User (or I do not want to use it), but
I have an account in Corporate AD, or in Google, or in Facebook, or in Auth0, or ..., or in Cognito User Pool.
Then you can use Identity Pool to get a STS token for the account e.g Google you logged in, and can manipulate the AWS resource.
For instance, if you have 1000+ users in your corporate AD and want to let them use AWS resources somehow. Would you create 1000+ AWS IAM users? Or find a way to map them to a few IAM roles such as "Administrator", "Accounting", "Finance", "IT"?
What Identity Pool does
Identity Pool maps an Identity Provider token (e.g. Google token) to an IAM Role in an AWS account, and gives a STS Token.
AWS calls this "mapping" as Federation, in my understanding.
I would recommend completely forgetting User Pool when discussing Identity Pool. User Pool is just another Identity Provider which you may not need at all.
Likewise, when discussing User Pool, I would recommend completely forgetting Identity Pool.
I do hope AWS will separate Identity Provider Service (User Pool) from Token Mapping service (Identity Pool) to stop causing confusions.
The best summary I have ever heard is:
user pools return JSON Web Tokens (JWTs) which are used to access APIs that you built (using api gateway or appsync)
identity pools return Security Token Service (STS) tokens that are used to access APIs that aws built (s3, dynamodb, etc.)
Watch this cognito deep dive video for more details.
The below picture is a good answer to the question (User pool Vs Identity Pool)
Related
I am currently investigating the use of Federated Identities and from the many examples I have read, it seems to be a way to grant users temporary credentials to various AWS services. For my case, the API Gateway is all that the user will interact with, since the API server is the one making calls to other services like S3 and DynamoDB. I like how permissions are controlled using IAM, but I'm failing to see any other appeals of Federated Identities. User Pools itself already supports password/fb/google/etc sign in, the only downside I see with user pools is that I'll need to do the authorization manually in the API layer. Is there something else I am missing with Federated Identities? Is it worth it given my use of only API Gateways (externally).
It all depends on the way that you will secure your API Gateway endpoint.
If you secure your API using AWS IAM, you'll need a way to convert your authentication tokens in AWS IAM Roles. For that scenario you can use AWS Cognito Idp (not the User Pool) or AWS Federated Identities. The difference is: using AWS IAM Federated Identities you will need to call AWS STS AssumeRoleWithWebIdentity in your frontend code. If you use AWS Cognito Idp this is done for you. . (AWS strongly suggest that you use the Cognito Idp in that scenario)
If you secure your API using AWS Cognito User Pools you don't need to use AWS Federated Identities. You can connect API Gateway directly to AWS Cognito and the service will enforce the controls for you. In that case you'll need to have a Cognito User Pool.
You also have a choice to use Custom Authorizers. In that scenario you will implement a lambda function that will evaluate your request and decide if it is authorized or not. In the same way, you won't need federated identities.
And finally you have the API Key authorization, that you already mentioned that is not applicable to your use case.
I am an AWS newb, so please go easy on me :)
I have setup a proof of concept to proove out an authenticated API backed by lambda with the following components.
API Gateway -> backed by Lambda
Federated Identities backed by AWS Cognito UserPool
I have the authorizer setup in the API gateway to use the IAM role which is being provided by the Federated Identity pool.
I can see the identity (ap-southeast-2:<GUID>) coming through into the gateway ( using this in my integration request mapping template "$context.identity.cognitoIdentityId" ) from https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#context-variable-reference
From either the gateway or lambda how can I resolve the 'ap-southeast-2:<GUID>' back to the source identity which resides in the user pool. (E.g. Pull one of the custom attributes from it)
Other information if relevant, i'm using Amplify-AWS for the client calling into the API Gateway.
TIA.
As you're noticing, Cognito as an identity provider is not the same as Cognito as a user pool.
Federated Identities provide a way of giving someone identified access to your AWS resources. The identity_id the identity provider gives you can almost be thought of as a tracking code. CIP (Congito [Federated] Identity Provider) allows you to get an identity id by signing in through any number of providers (not just the user pool), and even by not signing in at all.
User Pools give you a way of managing users for your application (i.e. a set of usernames, emails, passwords, etc).
This is the reason getting from identity_id back to the user pool user is hard (because, there's no guarantee it is a user pool user, it could well be someone from Facebook).
From what you've said, however, the assumption that said identity_id came from a UserPool authentication is safe. This means you have two options:
The official way will be to use identity:GetOpenIdToken to convert identity_id (you can ignore the logins part of the request) into an OpenId token. You can then use this token against the userpools:GetUser end point. There's a few pitfalls here, like ensuring you authenticate with a scope that allows you to see all the attributes you care about.
Curiously, however, the value of cognitoAuthenticationProvider is not opaque, and can (unoffically) be decoded:
// Cognito authentication provider looks like:
// cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxxxxxx,cognito-idp.us-east-1.amazonaws.com/us-east-1_aaaaaaaaa:CognitoSignIn:qqqqqqqq-1111-2222-3333-rrrrrrrrrrrr
// Where us-east-1_aaaaaaaaa is the User Pool id
// And qqqqqqqq-1111-2222-3333-rrrrrrrrrrrr is the User Pool User Id
The above example, with more details about how you can then use this with userpools:AdminGetUser can be found here: https://serverless-stack.com/chapters/mapping-cognito-identity-id-and-user-pool-id.html
Question
Why AWS Cognito has two places to federate Identity Providers? I think Identity Pool is supposed to be federated with identity providers and wonder why User Pool also can. Kindly suggest the reason why having two locations.
Cognito Identity Pool can federate identity providers.
Cognito User Pool can federate identity provides as well.
User Pool
User pools are for authentication (identity verification). With a user pool, your app users can sign in through the user pool (which is essentially a user directory in Amazon Cognito) or federate through a third-party identity provider (IdP), for example social identity providers like Google, Facebook, Amazon, or Apple, and through SAML identity providers.
After successfully authenticating a user, Amazon Cognito issues JSON web tokens (JWT) that you can use to secure and authorize access to your own APIs, or exchange for AWS credentials (here is where Identity Pool comes into play).
Use a user pool when you need to:
Design sign-up and sign-in webpages for your app.
Access and manage user data.
Track user device, location, and IP address, and adapt to sign-in requests of different risk levels.
Use a custom authentication flow for your app.
Identity Pool
Identity pools are for authorization (access control). With an identity pool, you can obtain temporary, limited-privilege AWS credentials to access other AWS services.
Use an identity pool when you need to:
Give your users access to AWS resources, such as an Amazon Simple Storage Service (Amazon S3) bucket or an Amazon DynamoDB table.
Generate temporary AWS credentials for unauthenticated users (User Pools support anonymous guest users).
Identity pools provide AWS credentials to grant your users access to other AWS services. To enable users in your user pool to access AWS resources, you can configure an identity pool to exchange user pool tokens for AWS credentials.
Sources:
https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pools-identity-pools/
https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html
https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html
The Main Difference is how users are saved and what permissions are granted once they signin with idp's using user pool vs identity pool.
So, Federation through User Pool (by themselves) don’t deal with permissions at the IAM-level which doesn't allow for a much more granular set of permissions, with respect to AWS services.
However Identity Pools creates a user from an Identity Provider with unique identities such as an IAM role, they essentially allow you to delegate authorization for AWS resources to AWS itself.
Refer here for scenarios!!
A similar source of confusion is caused by the fact that you can integrate external social providers like Facebook and Google with User Pools directly, without using Federated Identities at all. Using this approach, users can sign up and sign in to your app with their Facebook login, but they never get assigned an IAM role. Instead, the User Pool service automatically assigns these users to a Facebook group, and then maps the attributes of their Facebook profile (e.g. name, email, location) to the user attributes you’ve defined in your User Pool. Again, the key distinction here is not whether the Identity Provider is internal or external, but rather if an IAM role is assigned to the user after authentication.
Hope it Helps.
Problem: I want to authorize my Amazon API Gateway hosted REST API users using Facebook Authentication.
My Understanding: I know Amazon Cognito can be used to authenticate users, calling as Federated Identities. Then, I saw Authenticate API Clients with Amazon Cognito Your User Pool, which authenticates for Cognito User Pool. I also found Use Amazon API Gateway Custom Authorizers, to use from custom authorization. But, I did not find to link API Gateway to authenticate using Cognito Federated Identities (i.e. Facebook here). Can we use same procedure as User Pool for Federated Identities as well or should I use as in Custom Authorizers ?
I'm a bit confused. Any help is greatly appreciated.
Thanks in Advance.
Cognito federated identities and Cognito user pools address different use cases.
With Cognito user pools, you explicitly manage the users which can access your service. This is useful when you want to limit access to your API to a fixed set of users.
With Cognito federated identities, you delegate user management to an identity provider such as Facebook, Google, or Amazon. In that case, anyone with a user identity for your chosen identity provider can access your service. This is useful when you want to make your API broadly available, but still need to associate individual identities with your API users in order to manage per-user state or resources.
To use a federated identity, you set the API Gateway method to use “AWS_IAM” authorization. You use Cognito to create a role and associate it with your Cognito identity pool. You then use the Identity and Access Management (IAM) service to grant this role permission to call your API Gateway method.
I can't see a good design for claims- or role-based authorization over an AWS PaaS (gateway/lambda) API. Right now, there seems to be a functionality blindspot regardless of how you combine the following:
gateway cognito user pool or custom authorizers
cognito identity pools used for web and user pool identity federation
IAM roles for gateway execution authorization
Specifically, the blindspot seems to be associating cognito identities with roles (more varied than keys and suffixes in dynamo and s3) based on user attributes in a way that:
doesn't require a custom endpoint in your API to vend IAM temp creds (and consequently using something other than the supplied and/or generated SDKs)
doesn't require authorization logic in every lambda function
doesn't require persisting the above mapping in dynamo, cognito sync, etc
doesn't layer or sequence a separate flow for authorization (e.g. separate token)
lets your users sign in using external idps
I assume the following is impossible or excessively hacky:
cognito user pools that overlap or moving users between pools to represent the configuration of their roles
directly getting cognito user pool attributes from congito identity pool identity tokens (GetOpenIdToken)
having a readily-modifiable client pick its own privileges (e.g. choose an IAM role)
running every request as dry-run in a custom authorizer or otherwise shadow-implementing IAM
securing actually role-specific IAM roles with some kind of shared secret, etc.
Here are some examples and their shortcomings:
A user logs in with user pool credentials and attempts to execute a gateway api method.
A cognito authorizer over gateway api methods would let me say autheticated-therefore-authorized and map attributes/claims into the integration request, still leaving it to the lambda function to implement actual authorization logic.
A custom authorizer won't automatically validate and parse a user pool token, but I could still do so and conditionally construct a role.
A user logs in with google+ credentials, having a user pool identity as well, and attempts to execute a gateway api method.
A cognito authorizer is useless.
A custom authorizer won't automatically validate and parse the google+ token, but I could still do so and conditionally construct a role. Only now I'd need to map this to a user pool identity manually. Cognito adds no value at all here -- just an awkward document database as a service.
A user logs in with google+ credentials, having a user pool identity as well, then gets an identity pool token (GetOpenIdToken) and attempts to execute a gateway api method.
A cognito authorizer is useless.
A custom authorizer won't automatically validate and parse the cognito identity token, but I could still do so and conditionally construct a role. I still need to do manual mapping because I won't get the user pool attributes with this intermediate token.
A user logs in with google+ credentials, having a user pool identity as well, then gets temp creds (GetCredentialsForIdentity) and attempts to execute a gateway api method.
The default authorizer is useless. You just get authenticated-therefore-authorized.
A cognito authorizer is useless.
A custom authorizer is useless.
The easiest solutions to most of these problems are in User Pools (i.e. using Lambda hooks in the auth flow to check privileges, attributes can be retrieved from the token an authentication generates...etc.), however your requirement that users can sign in with external providers is not currently supported.
From that, you can potentially use Cognito federated identities with user pools and external providers, but that brings up some awkwardness. Building in the privilege authentication into the user pools lambda hooks when multiple providers are available is awkward and forces the usage of user pools with other providers.
From that, I would say mapping privileges to identity id in some external storage is the way to go, using some external hook (Lambda?) with that id to assume a role and get credentials, but you mentioned you wouldn't want to do that.
I would agree that what you're aiming for is not absolutely possible as is. My recommendation might be to get in touch with an SA and see if they can help you design a complex solution that fulfills your requirements.