Thank you to our sponsors who keep this newsletter free to the reader:
Announcing Postman v11: supercharging development with AI and APIs. Streamline API development with Postman v11's new features for collaboration, AI, and security. Try out the new features like VS Code extension, Partner Workspaces, and Postman Vault to streamline your API development workflow.
Product for Engineers from PostHog is a newsletter helping engineers improve their product skills. Subscribe for free to get curated advice on building great products, lessons (and mistakes) from PostHog, and deep dives on top startups.
API gateways provide clients with a single point of entry. This streamlines their interactions with your system and ensures the security of your microservices or distributed system.
One critical aspect of API gateways is authentication - ensuring only authorized users and applications can access your valuable data and resources.
In this newsletter, we'll explore how you can implement API gateway authentication using YARP (Yet Another Reverse Proxy), a powerful and flexible reverse proxy library for .NET applications.
Here's what we will cover:
- The role of API gateways
- Configuring authentication with YARP
- Creating custom authorization policies
Let's dive in.
The Role of API Gateways
An API gateway is the "front door" to your backend services and APIs. It acts as an intermediary layer, handling client requests and routing them to the appropriate destinations.
The key benefits of API gateways are:
- Centralized access: All incoming requests must first pass through the gateway. This simplifies management and monitoring.
- Service abstraction: Clients interact only with the gateway. We can hide the complexity of the backend architecture from clients.
- Performance enhancement: Implement techniques like caching and load balancing to optimize API performance.
- Authentication and Authorization: API gateways verify user and application identities, enforcing whether a request is allowed or not.
Configuring Authentication With YARP
We can use the API gateway to authenticate and authorize requests before they are proxied to the destination servers. This can reduce the load on the destination servers, and introduce a layer of security. Implementing authentication on the API gateway ensures consistent policies are implemented across your applications.
If you're new to YARP, I recommend first reading about how to implement an API gateway with YARP.
By default, YARP won't authenticate or authorize requests unless enabled in the route or application configuration.
We can start by introducing authentication and authorization middleware:
app.UseAuthentication();
app.UseAuthorization();
app.MapReverseProxy();
This allows us to configure the authorization policy by providing the AuthorizationPolicy
value in the route configuration.
There are two special values we can specify in a route's authorization parameter:
default
- The route will require an authenticated user.anonymous
- The route will not require authorization regardless of any other configuration.
Here's how we can enforce that all incoming requests must be authenticated:
{
// This is how we define reverse proxy routes.
"Routes": {
"api-route": {
"ClusterId": "api-cluster",
"AuthorizationPolicy": "default",
"Match": {
"Path": "api/{**catch-all}"
}
}
}
}
We want to authorize any incoming request as soon as it hits the API gateway. However, the destination server may still need to know who the user is (authentication) and what they can do (authorization).
YARP will pass any credentials to the proxied request. By default, cookies, bearer tokens, and API keys will flow to the destination server.
Creating Custom Authentication Policies
YARP can utilize the powerful authorization policies feature in ASP.NET Core. We can specify a policy per route in the proxy configuration, and the rest is handled by existing ASP.NET Core authentication and authorization components.
{
// This is how we define auth policies for reverse proxy routes.
"Routes": {
"api-route1": {
"ClusterId": "api-cluster",
"AuthorizationPolicy": "is-vip",
"Match": {
"Path": "api/hello-vip"
}
},
"api-route2": {
"ClusterId": "api-cluster",
"AuthorizationPolicy": "default",
"Match": {
"Path": "api/{**catch-all}"
}
}
}
}
Here's how we can create a custom is-vip
policy with two components.
It requires an authenticated user and vip
claim with one of the defined allowed values to be present .
To use this policy, we can just specify it as the value for the AuthorizationPolicy
in the route configuration.
services.AddAuthorization(options =>
{
options.AddPolicy("is-vip", policy =>
policy
.RequireAuthenticatedUser()
.RequireClaim("vip", allowedValues: true.ToString()));
});
Summary
API gateways provide a unified access point, streamlining client interactions and securing your backend services. Authentication is an essential element of API gateway security, controlling who can access your resources.
YARP offers a versatile solution for building .NET API gateways. By integrating with ASP.NET Core's authentication and authorization frameworks, YARP enables robust security mechanisms.
This flexibility really shines with support for custom authorization policies. This allows you to define granular access control based on user roles, claims, or other attributes.
Thanks for reading, and I'll see you next week.
P.S. Here's the complete source code for this article if you want to try it out.