# 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

1. **Create a User Pool**
    
    * Go to the Cognito console.
        
    * Choose “Create user pool” and configure fields like username, email, and password policies.
        
2. **Create an App Client**
    
    * Disable the client secret (for public clients like desktop or mobile apps).
        
    * Enable the `ALLOW_USER_PASSWORD_AUTH` and `ALLOW_REFRESH_TOKEN_AUTH` flows if you want to authenticate with username/password directly.
        
3. **(Optional) Hosted UI**
    
    * Use Cognito's hosted UI if you want OAuth2-style login redirects.
        

---

## Step 2: Create and Configure API Gateway

1. **Create a REST API or HTTP API**
    
    * In the API Gateway console, choose to create a new **HTTP API**.
        
    * Name it something like `UserServiceAPI`.
        
2. **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.
        
3. **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`.
        
4. **Secure the** `/profile` Route
    
    * In 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:

```csharp
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:

```csharp
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:

```csharp
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

* [Amazon Cognito User Pools](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html)
    
* [API Gateway Cognito Authorizer](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html)
    
* [Cognito OAuth2 Token Endpoint](https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html)
    
* [System.IdentityModel.Tokens.Jwt](https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/)
