Authenticating API Gateway with Cognito in .NET Apps


When building secure and scalable APIs on AWS, Amazon Cognito paired with API Gateway provides a powerful combination for authentication. Cognito handles the identity layer, while API Gateway manages the request routing and enforcement of authentication via JWT tokens.
In this post, we’ll walk through how to authenticate .NET applications against an API Gateway endpoint secured by Cognito. This setup works great for web apps, desktop clients, and server-to-server communication.
Why Use Cognito with API Gateway?
Amazon Cognito is a user directory service that provides:
Secure user sign-up and sign-in
JWT token-based authentication
Integration with identity providers like Google, Facebook, and Microsoft
Federated access to AWS services
API Gateway can directly validate JWT tokens issued by Cognito using a User Pool Authorizer. This allows you to secure your APIs without writing custom authentication logic.
Step 1: Set Up Cognito
Create a User Pool
Go to the Cognito console.
Choose “Create user pool” and configure fields like username, email, and password policies.
Create an App Client
Disable the client secret (for public clients like desktop or mobile apps).
Enable the
ALLOW_USER_PASSWORD_AUTH
andALLOW_REFRESH_TOKEN_AUTH
flows if you want to authenticate with username/password directly.
(Optional) Hosted UI
- Use Cognito's hosted UI if you want OAuth2-style login redirects.
Step 2: Create and Configure API Gateway
Create a REST API or HTTP API
In the API Gateway console, choose to create a new HTTP API.
Name it something like
UserServiceAPI
.
Define a Secure Endpoint
Add a new route:
GET /profile
This endpoint will return user profile data and should only be accessible to authenticated users.
Add a Cognito Authorizer
Go to the Authorizers section.
Choose "Cognito" and select the user pool you created earlier.
Give the authorizer a name like
CognitoUserPoolAuthorizer
.
Secure the
/profile
RouteIn the route settings, attach the Cognito authorizer to the
/profile
endpoint.This ensures that any request to
/profile
must include a valid JWT token issued by your Cognito User Pool.
Step 3: Get a JWT Token from Cognito in .NET
You can authenticate a user and retrieve tokens via HTTP using Cognito’s /oauth2/token
endpoint.
Here’s how to do that using HttpClient
in a .NET app:
var httpClient = new HttpClient();
var parameters = new Dictionary<string, string>
{
{ "grant_type", "password" },
{ "client_id", "<your-app-client-id>" },
{ "username", "<user-email>" },
{ "password", "<user-password>" },
};
var content = new FormUrlEncodedContent(parameters);
var response = await httpClient.PostAsync("https://<your-domain>.auth.<region>.amazoncognito.com/oauth2/token", content);
var json = await response.Content.ReadAsStringAsync();
var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(json);
public class TokenResponse
{
public string Access_token { get; set; }
public string Id_token { get; set; }
public string Refresh_token { get; set; }
public string Token_type { get; set; }
public int Expires_in { get; set; }
}
Tip: You can also use MSAL.NET if you’re using the OAuth2 code flow with redirect URIs and Cognito’s hosted UI.
Step 4: Send Authenticated Requests to API Gateway
After obtaining the token from Cognito, use it to call the protected /profile
endpoint:
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenResponse.Id_token);
var response = await client.GetAsync("https://your-api-id.execute-api.us-east-1.amazonaws.com/prod/profile");
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);
}
else
{
Console.WriteLine($"Request failed: {response.StatusCode}");
}
Replace your-api-id
with your actual API Gateway ID and region. This example assumes the endpoint is deployed under the prod
stage.
Step 5: (Optional) Validate Tokens Manually
If you’re processing the token yourself (e.g., in a Lambda function), use System.IdentityModel.Tokens.Jwt
to parse and validate the token:
var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken(tokenResponse.Id_token);
foreach (var claim in token.Claims)
{
Console.WriteLine($"{claim.Type}: {claim.Value}");
}
Make sure to validate:
Signature (using the JWKS endpoint)
Expiration (
exp
)Audience (
aud
)Issuer (
iss
)
Common Issues
Missing Token: Ensure the
Authorization
header is set and the route is protected with the authorizer.Invalid Token: Check that you're using the correct Cognito user pool and app client.
CORS Errors: If calling from a browser, configure CORS settings in API Gateway.
Token Expired: Use the refresh token to obtain a new access token.
Conclusion
By combining Amazon Cognito and API Gateway, you can add strong authentication to your APIs without maintaining your own user system. .NET apps can easily acquire and use tokens to call these APIs securely. Whether you're building a mobile app, a web frontend, or a backend service, this setup is clean, scalable, and secure.
References
Subscribe to my newsletter
Read articles from Renato Ramos Nascimento directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Renato Ramos Nascimento
Renato Ramos Nascimento
With over 14 years in software development, I specialize in backend systems using .NET, Python, and Java. I bring full lifecycle expertise, including requirements analysis, client/server and data layer development, automated testing (unit, integration, end-to-end), and CI/CD implementations using Docker, GitLab Pipelines, GitHub Actions, Terraform, and AWS CodeStar.