Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the code returned from Cognito to get AWS credentials?

Right now, I'm struggling to understand AWS Cognito so maybe someone could help me out. I set a domain to serve Cognito's hosted UI for my User Pool like what's described here. So when I go to https://<my-domain>.auth.us-east-1.amazoncognito.com/login?response_type=code&client_id=<MY_POOL_CLIENT_ID>&redirect_uri=https://localhost:8080 I get a login page where my users can login to my app with Google. That part is working great.

I confused about what to do with the code that is returned from that page once my user logs in. So once I get redirected to Google and authorize the application to view my information, I get redirected back to one of my URLs with a code in the query params. Right now I'm redirecting to localhost, so the redirect URL look like this:

https://localhost:8080/?code=XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX

What exactly is this code? Also, how do I use it to get access to AWS resources for my user?

like image 706
arjabbar Avatar asked Aug 20 '17 19:08

arjabbar


People also ask

How do I get my Cognito credentials?

Amazon Cognito identities are not credentials. They are exchanged for credentials using web identity federation support in the AWS Security Token Service (AWS STS). The recommended way to obtain AWS credentials for your app users is to use AWS.

What does AWS Cognito return?

Once the end user is authenticated with the IdP, the OAuth or OpenID Connect token or the SAML assertion returned from the IdP is passed by your app to Cognito Identity, which returns a new Cognito ID for the user and a set of temporary, limited-privilege AWS credentials.


1 Answers

First off, screw authentication a thousand times. No one deserves to spend half a day looking at this shit.

Authentication for API Gateway Authorized with Cognito

Ingredients

  1. client_id and client_secret: In Cognito > General Settings > App clients you can find the App client id, then click on Show Details to find the App client secret

  2. For the header Authorization: Basic YWJjZGVmZzpvMWZjb28zc... you need to encode those two with: Base64Encode(client_id:client_secret), for example in Python:

    import base64   base64.b64encode('qcbstohg3o:alksjdlkjdasdksd')`   

    side note: Postman also has an option to generate this in Authorization > Basic Auth

  3. redirect_uri: passed in the body, it is the callback url that you configured in App integration > App client settings.
    This MUST match with what you configured or you will get a totally unhelpful message { "error": "invalid_grant" }

Example of a request to get a token from the code:

curl --location --request POST 'https://mycognitodomain.auth.us-east-1.amazoncognito.com/oauth2/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Authorization: Basic <base64 encoded client_id:client_secret>' \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode 'client_id=<client_id>' \ --data-urlencode 'code=<use the code you received post login>' \ --data-urlencode 'redirect_uri=https://myapp.com' 

This will return your tokens:

{   "access_token":"eyJz9sdfsdfsdfsd",    "refresh_token":"dn43ud8uj32nk2je",   "id_token":"dmcxd329ujdmkemkd349r",   "token_type":"Bearer",    "expires_in":3600 } 

Then take the id_token and plug into your API call:

curl --location --request GET 'https://myapigateway.execute-api.us-east-1.amazonaws.com/' \ --header 'Authorization: <id_token>' 

Ok, this is tagged as JavaScript but since we also suffer in Python

Friendly reminder: this is an example, please don't hardcode your secrets.

import requests  # In: General Settings > App clients > Show details client_id = "ksjahdskaLAJS ..." client_secret = "dssaKJHSAKJHDSsjdhksjHSKJDskdjhsa..."  # URL in your application that receives the code post-authentication # (Cognito lets you use localhost for testing purposes) callback_uri = "http://localhost:8001/accounts/amazon-cognito/login/callback/"  # Find this in: App Integration > Domain cognito_app_url = "https://my-application-name.auth.us-west-2.amazoncognito.com"  # this is the response code you received - you can get a code to test by going to # going to App Integration > App client settings > Lunch Hosted UI # and doing the login steps, even if it redirects you to an invalid URL after login # you can see the code in the querystring, for example: # http://localhost:8001/accounts/amazon-cognito/login/callback/?code=b2ca649e-b34a-44a7-be1a-121882e27fe6 code="b2ca649e-b34a-44a7-be1a-121882e27fe6"  token_url = f"{cognito_app_url}/oauth2/token" auth = requests.auth.HTTPBasicAuth(client_id, client_secret)  params = {     "grant_type": "authorization_code",     "client_id": client_id,     "code": code,     "redirect_uri": callback_uri }  response = requests.post(token_url, auth=auth, data=params)  print(response.json()) # don't judge me, this is an example 
like image 122
bubbassauro Avatar answered Oct 04 '22 07:10

bubbassauro