Forward claims from external provider to Cognito Identity - amazon-web-services

I have an app and openid identity server. My app retrieves tokens from the Identity server.
I have also configured the identity server as an external provider for an AWS Cognito Identity Pool.
I can successfully retrieve AWS credentials for the User logged into my app.
However, I find the AWS credentials limited as the token does not contain any of the claims from the original login token. Is there any way to get them in there?
One the claims I use is clientID and I was hoping to be able to use that in a an IAM Policy to restrict S3 access by client.

I haven't found direct solution for that, and it seems like missing feature.
The workaround I did was:
Mapping id_token/access_token/refresh_token to custom cognito attributes. As all mapped attributes are later available in your frontend, you need to restrict read permissions for sensitive attributes.
Use TokenGeneration_HostedAuth lambda trigger to work on this data.

Related

AWS cognito authorization

I have an application (node.js) that need an Authentication and authorization.
My app need access to postgres database and also need a Inheritances (roles etc.)
One option to implement that is using the cognito service of aws (the app will host on aws properly - not sure about that)
so the questions is
Is cognito service support the authorization for node.js with database that is not services on aws? (I read that "identity pool" is for aws services like mariaDB)
If my app will be on heroku (not on aws), I will also be able to use with cognito services (for authorization)?
Is cognito support roles/users inheritances ?
Tnx
Cognito identity pool is used for granting access to aws services. User pool is used to exchange user credentials for tokens which can contain additional information about the user once decoded. So yes, you can use user pool just for authentication. Your user attributes can contain information related to the services this user needs to access.
However, if you plan on storing database credentials, I suggest you use AWS secrets manager to store your DB credentials and grant the cognito user access to this secret. You'll need to use both user pool and identity pool in this case.
Not directly, but you can use it to access secrets manager where you db credentials are stored.
Yes you can use cognito anywhere. It will be connecting to AWS to grant you tokens however. And these tokens are only recognized on AWS. Which is why you need to use them to access other secrets that can be used to access whatever other services you want.
Cognito supports groups. I'm not sure if that's what you mean by inheritences. You can have token based roles with groups.

How a mobile app should authenticate to AWS

I'm developing a mobile app that must access some AWS resources, so it needs authentication to AWS endpoint. The app doesn't manage users (sign-in, sign-out, register and so on).
My first solution was to create a IAM user dedicated to the mobile app and embed its credentials in the mobile app code. The app authenticate itself to AWS using the embedded credentials. It works, however AWS suggests to avoid embedding credentials directly in the app.
I think a better solution is Cognito. Because I don't need users management, I should use unauthenticated (guest) identity to request temporary AWS credentials.
However I don't understand why a guest Cognito identity is more secure than an embedded credentials. The mobile app receive a temporary AWS credentials by sending a Cognito Identity Pool ID, that is a long-term "number" embedded in the mobile app. If someone is able to find this Identity Pool ID, she can receive AWS credentials and access AWS resources as my official mobile app. It seems there's no difference between embedded AWS long-term credentials and huest Cognito access.
Why Cognito solution is better than embedded AWS credentials?
If you are creating unauthenticated access using identity pool, you are allowing public to access your AWS resources. Make sure you write your policy carefully and it won't matter if you use a single IAM user or cognito unauthenticated access as far as security is concerned.
Using federated identity will provide you benefits like getting statistics on usage and adding triggers to events. Also keep in mind that creating a single IAM user and then allowing multiple people to use these credentials is a "hack" way of doing what cognito federated unauthenticated idenity was designed to do. You might run into unexpected complications later if AWS decides to throttle this behavior of IAM.

Lookup cognito userpool uset based on cognito dentity pool identity in API Gateway

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

App Sync - Protecting Api for non authenticated users

We're building an application using AWS App Sync, we're still in a very early stage.
Our application has a restricted area, through user sign-in, which is being managed via aws cognito users pool. And this is fine.
We're having issues on the public area which doesn't require any authentication.
How can we protect these public endpoints?
We're having some doubts about hard coding the api key (that we know can be rotated), is it a good practice (documentation page says that it isn't ideal for production)?
Is there any way to authorise the origin? (aka, any request coming from www.foobar.baz is ok)
I would suggest using Amazon Cognito Federated Identity to control authenticated and unauthenticated access to the api. In order to do use Amazon Cognito Federated Identity with AWS AppSync, you need to use AWS IAM based authorization.
For the authenticated access you can use Amazon Cognito User Pools and federated to Amazon Cognito Federated Identity and since the federated identity can also allow for unauthenticated users it will allow you to control some api's which can be made public via an IAM policy.
For more information please read the AWS IAM Section of our security guide here
Under your AppSync app's Settings menu, where you set the User Pool Configuration, there is an option to set a default action. You can change this to DENY and all unauthenticated requests will be rejected. The alternative approach is to ALLOW everything, and manually add #aws_auth directives to every query/mutation/subscription field that you care about restricting.

Get current AWS Cognito identity id from supplied credentials

I have an iOS app that is authenticating using Facebook & Cognito. I am able to make calls to a local ReST service with the following AWS credentials from my iOS app extracted from Cognito:
accessToken: {a_token}
secretToken: {a_token}
sessionToken: {a_token}
I want to get the current Cognito identity from the AWS credentials so I can use that as a key in my DynamoDB table and handle authorization (I don't want to use IAM roles for this). I know I can directly invoke DynamoDB from the iOS app but I do not want my app directly calling my data storage (in case I want to change data storage, add caching, etc...). Is it possible to get the current Cognito identity from the current AWS credentials?
I do not want to pass the identity id with the request, as is defeats the purpose of passing the tokens.
I do not want to use AWS API Gateway either.
From your credentialsProvider you can call getIdentityId() and in continueWithBlock' you can accesscredentialsProvider.identityId`
I am sorry but there is no way to get an identity id from AWS credentials.
Is there a reason you do not want to call Amazon DynamoDB from the device directly using credentials vended by Cognito Identity? Using IAM roles you can restrict the usage for an identity to be able to write to only their records and this is the approach we recommend currently.
You can refer to our blog about fine grain access with DynamoDB using Cognito.