Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS Cognito AccessToken vs IdToken

I created a .net Core API using the AWS Cognito SDK to authenticate and authorize users by posting credentials to my API and returning a JWT to a simple client side app (plain HTML/TypeScript). The request contains the user name and password.

...
var response = await cognito.AdminInitiateAuthAsync(request);

return Ok(response.AuthenticationResult.AccessToken);

vs

return Ok(response.AuthenticationResult.IdToken);

The problem I'm having is understanding why there are ID Tokens and Access Tokens. I'm able to secure controller endpoints with the [Authorize] attribute. The client app uses the Authorization header with Bearer {token}.

In my Startup.cs I'm able to AddAuthentication and verify the Signature, Issuer, Audience and Lifetime of the ID Token. However, I read that the ID Token contains claims about the identity of the user but not claims about the groups for authorization of the user. If I send the Access Token to my client and try to send this back to my API, I'm getting unauthorized. Maybe I'm not verifying the token properly but I still don't understand why there are two different types of tokens. The Access Token makes more sense to use for creating different auth policies based on claims the token contains.

The way I understand how JWT's work is that once a client obtains a token it stores it and uses it for all request to an API. I don't understand how this is supposed to work with two tokens.

Here is how I'm trying to validate the access token:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>{
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    IssuerSigningKeyResolver = (s, securityToken, identifier, parameters) =>
                    {
                        // get JsonWebKeySet from AWS
                        var json = new WebClient().DownloadString(parameters.ValidIssuer + "/.well-known/jwks.json");
                        // serialize the result
                        var keys = JsonConvert.DeserializeObject<JsonWebKeySet>(json).Keys;

                        // cast the result to be the type expected by IssuerSigningKeyResolver
                        return (IEnumerable<SecurityKey>)keys;
                    },
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["Authentication:Cognito:MetadataAddress"],
                    ValidateIssuer = true,
                    ValidAudience = Configuration["Authentication:Cognito:ClientId"],
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    RequireSignedTokens = true
                };
            });

There is no aud claim in the access token so I'm getting an error "Invalid token, audience = 'empty' is invalid.

Even if I remove ValidateAudience, I still get the error

like image 562
Shawn Avatar asked Apr 01 '20 15:04

Shawn


1 Answers

ID token is sent to the client application as part of an OpenID Connect flow and is used by the client to authenticate the user. Access tokens enable clients to securely call APIs protected by identity provider .

The ID token contains information about an End-User which is not used to access protected resource , while Access token allows access to certain defined server resources .

So that while using OpenID Connect , it will return ID token and access token back to your client , client app will get user's info from id token and sign in user , and use access token to access the protected resource .

If I send the Access Token to my client and try to send this back to my API, I'm getting unauthorized.

The ID token will be validated by your client app app to get user claims , so the audience claim in token is your client app's client ID . Access token is passed to your protected resource(web api) and should be validated by protected resource(web api) , so the audience is web api's name . You should check the validation options like audience , issuer .

like image 127
Nan Yu Avatar answered Oct 11 '22 07:10

Nan Yu