Checking the tokens that a server side app receives from front-end application

0

Hi guys,

I've working with Amazon Cognito and I've a doubt, for example: if I've working with a server side applications (Authorization Code Grant Flow) and a user logged in the app, then Cognito send him an id token and access token. With these tokens the app can access to some resources, but here is my question: I know that we should verify the tokens in the server side received from a user application (id token and access token), but my question is if the user application (for example in the front-end) should verify also the tokens returned from Cognito ? or only it is mandatory or recommended to check the tokens in the server side application ?

One mounth ago I 've asked a question about the same topic, and a user answered me saying that it's highly recommended checking the tokens sended by the front-end app in any request to server side application. And I understand the answer, but now is on the contrary my doubt. Thanks in advance !!

Greetings.

asked 8 months ago216 views
2 Answers
1

Hello,

First of all regarding the Authorization Code Grant Flow I would like to mention that it is basically a method for authorizing end users. Instead of directly providing user pool tokens to an end user (like id and access token) upon authentication, an authorization code is provided instead, and this code is then sent to the application that can exchange it for the desired tokens [1].

To summarize - Cognito sends an authorization code to the user using Authorization Code Grant Flow. The custom application that’s hosted at the redirect URL can then extract the authorization code from the query parameters and exchange it for user pool tokens.

Now in regards to the statement -

  1. if I've working with a server side applications (Authorization Code Grant Flow) and a user logged in the app, then Cognito send him an id token and access token.
  • The Cognito server doesn't send tokens to the user. Cognito only provides authorization code to the user. It will be the app that extracts that code to exchange the code for token. Thereby making sure that the tokens are not exposed to the end user directly, which is the reason why it is recommended over implicit grant flow.
  • "Because the tokens are never exposed directly to an end user, they are less likely to become compromised." (1)
  1. "With these tokens the app can access to some resources"
  • This statement is correct. The custom application that’s hosted at the redirect URL can then extract the authorization code from the query parameters and exchange it for user pool tokens.
  1. "But my question is if the user application (for example in the front-end) should verify also the tokens returned from Cognito?"
  • Here, we need to understand that, if we try to provide/exchange an invalid authorization code (or even an already used authorization code) to/with the Cognito server (your Cognito userpool) then you will receive an error.

For example -

$ curl --location --request POST 'https://teXXXXXXXXXXXXun.auth.us-east-1.amazoncognito.com/oauth2/token'
--header 'Authorization: Basic MXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXz'
--header 'Content-Type: application/x-www-form-urlencoded'
--header 'Cookie: XSRF-TOKEN=XXXXXXXXXXXX-XXXXXXXX'
--data-urlencode 'grant_type=authorization_code'
--data-urlencode 'code=adXXXX5-cXXX-XXXX-XXXX-7XXXXb5ef'
--data-urlencode 'redirect_uri=https://www.example.com'

Output -

{ "error": "invalid_grant" }

To shed some more light on the above error ->

invalid_grant error can occur when Authorization code has been consumed already or does not exist. (2)

So to summarize - Cognito will only provide you with the tokens when the correct authorization code is provided to the Cognito server.

So rest assured in case if you do try to provide a bogus authorization code or an already used authorization code for exchange of tokens, you will not receive any tokens from Cognito but rather you will receive an invalid grant error from Cognito server as demonstrated in the example above.

So the check for authorization code is already happening on Cognito's end itself, and you will only be able to get the tokens when you provide the correct authorization code. However, if the verification fails - meaning that you provided an incorrect (bogus/already used) authorization code then you won't receive any tokens from the Cognito server.

Now in regards to verifying the tokens that you received from Cognito for your application, I would like to mention that the identity token and access token are all JWTs (JSON Web Tokens), which means that you can check that the signature and structure of the token is valid. There are many libraries available for decoding and verifying a JWT so you can use them to decode the token. You can compare key ids, or verify claims such as 'iss' field to confirm if the token was issued by your user pool etc. For more information on this, please refer to our knowledge center article (3) and AWS Documentation (4).

Also this verification of tokens on the part of the application is not mandatory, however verifying the tokens can help you understand that they are coming from the right userpool, the right application client, has the right JWT structure or are valid unexpired tokens etc.

Please note that, if you use the amplify SDK provided by AWS then you don't have to validate the token yourself since the SDK will do it for you and it will also refresh the token automatically. (5)

========= Extra Information on JWTs =========

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

JWT Token validate with respect to the corresponding public JSON Web Key (JWK) for your User Pool, which is located at the following link:

https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json.

You can use this public key to verify the signature of the token using any open source JWT library. Once the signature is validated, we can extract values from the token payload such as the aud, email and user name. Also, as a best practice, we could check if the token is not expired and the audience ("aud") specified in the payload matches the app client ID created in the Amazon Cognito user pool.

You can parse the Cognito JWT ID token online as well using jwt.io

References:

  1. https://aws.amazon.com/blogs/mobile/understanding-amazon-cognito-user-pool-oauth-2-0-grants/

  2. https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html

  3. https://aws.amazon.com/premiumsupport/knowledge-center/decode-verify-cognito-json-token/

  4. https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html

  5. https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html#amazon-cognito-user-pools-using-tokens-prerequisites

profile picture
SUPPORT ENGINEER
Yash_C
answered 8 months ago
0

Hi Yash_C,

Thanks for your reply. I was a bit wrong about the Authorization Code Grant Flow. Indeed the tokens are returned in this case to the server side app, and then this app can send the access token to Cognito and this grants access to a protected resource. Please correct me if I've misunderstood your reply. And because of your reply, now may be it's interesting to validate the tokens in the front-end application according with your recomendations (of course in this case we'll use the Implicit Grant Flow) if I'm not wrong. If I'm wrong please correcte me, any additional advice would be greatly appreciated ! Thanks a lot !

King regards.

answered 8 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions