# How To Implement API Key Authentication In ASP.NET Core

> In this week's newsletter I want to show you how to implement API Key authentication in ASP.NET Core, with the API key passed in a request header. This kind of authentication is common in Server-to-Server (S2S) communication, and less common in client-server scenarios.

Published: 2023-01-28. Author: Milan Jovanović.

Canonical: https://milanjovanovic.tech/blog/how-to-implement-api-key-authentication-in-aspnet-core

You implement API Key authentication in ASP.NET Core with a `ServiceFilterAttribute` that resolves an `IAuthorizationFilter` from the DI container.
The filter reads the key from a request header like `X-API-Key`, validates it, and sets an `UnauthorizedResult` when the key isn't valid.
You can place the attribute on a single endpoint or on the entire controller.

In this week's newsletter I want to show you how to implement **API Key authentication**
in **ASP.NET Core**. This authentication approach uses an **API Key** to authenticate the
client of an API. You can pass the **API Key** to the API in a few ways, such as through
the query string or a request header.

I will show you how to implement **API Key authentication** where the **API key** is passed
in a request header. But the implementation would be similar if we were to use any
other approach.

When would you want to use **API Key authentication**? This kind of authentication
mechanism is common in **Server-to-Server (S2S)** communication. When your API serves
request for other server-side applications to consume and integrate with. It's
less common in client-server communication scenarios.

Let's see how we can implement **API Key authentication** in ASP.NET Core!

## Implementing API Key Authentication

We will start off by creating an attribute that we can place on endpoints
where we want to apply **API Key authentication**. It won't be any kind of
attribute, because we will use a `ServiceFilterAttribute`.

What a `ServiceFilterAttribute` allows us to do is specify a type for the
filter that will be created for that attribute.
This means we can implement our authentication logic in an `IAuthorizationFilter`.
With a `ServiceFilterAttribute` we also have support for dependency injection
in our `IAuthorizationFilter` implementation.

Let's first define the `ApiKeyAttribute` class:

```csharp
public class ApiKeyAttribute : ServiceFilterAttribute
{
    public ApiKeyAttribute()
        : base(typeof(ApiKeyAuthorizationFilter))
    {
    }
}
```

In the `ApiKeyAttribute` we specify `ApiKeyAuthorizationFilter` class as the
filter that will be resolved from the DI container. Here's what it looks like:

```csharp
public class ApiKeyAuthorizationFilter : IAuthorizationFilter
{
    private const string ApiKeyHeaderName = "X-API-Key";

    private readonly IApiKeyValidator _apiKeyValidator;

    public ApiKeyAuthorizationFilter(IApiKeyValidator apiKeyValidator)
    {
        _apiKeyValidator = apiKeyValidator;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        string apiKey = context.HttpContext.Request.Headers[ApiKeyHeaderName];

        if (!_apiKeyValidator.IsValid(apiKey))
        {
            context.Result = new UnauthorizedResult();
        }
    }
}
```

The implementation comes down to validating the **API Key** obtained from
the header of the current request. If we determine that the **API Key**
is not valid, we set the value of `AuthorizationFilterContext.Result`
to a new instance of an `UnauthorizedResult`.

And lastly, all that's left for us to do is implement our custom
validation logic for the **API Key** inside of `ApiKeyValidator`:

```csharp
public class ApiKeyValidator : IApiKeyValidator
{
    public bool IsValid(string apiKey)
    {
        // Implement logic for validating the API key.
    }
}

public interface IApiKeyValidator
{
    bool IsValid(string apiKey);
}
```

The actual implementation for validating the **API Key** will vary based
on your use case, and where you are storing the API keys.
For example, if you store the API keys in the database you would check
if the provided **API Key** exists in the database.
If it exists, then validation passes.
If it doesn't exist, then validation fails and we return an
`UnauthorizedResult`.

## Registering Services With Dependency Injection

We have to make sure to register our `ApiKeyAuthorizationFilter` and
`ApiKeyValidator` services with the dependency injection container.

```csharp
builder.Services.AddSingleton<ApiKeyAuthorizationFilter>();

builder.Services.AddSingleton<IApiKeyValidator, ApiKeyValidator>();
```

This will register them as singleton services in our application.
You can use a different service scope such as `Transient` or `Scoped`
if you need to.

## Applying API Key Authentication To Endpoints

Finally, with our **API Key authentication** in place, we can apply the
`ApiKeyAttribute` attribute to our endpoints:

```csharp
public class NewslettersController : ControllerBase
{
    [ApiKey]
    [HttpGet]
    public IActionResult Get()
    {
        // ...
    }
}
```

In this case I'm applying the `ApiKeyAttribute` to an endpoint, but
you can also apply it on the `NewslettersController` and it will add
authentication to all the endpoints for that controller.

## Next Steps

Now that you know how to implement **API Key authentication**, I think you
should also learn how to implement [**JWT authentication**](https://milanjovanovic.tech/blog/jwt-authentication-aspnetcore). And while you're
at it, why not throw **authorization** into the mix.

I made a few videos about **JWT authentication** and **permission authorization**
that you should take a look at next:

- [Token Authentication In ASP.NET Core 7 With JWT](https://youtu.be/4cFhYUK8wnc)
- [Introduction To Permission Authorization In ASP.NET Core 7](https://youtu.be/PlbAuNvR16s)
- [Managing Permissions With EF Core Migrations](https://youtu.be/v4vXDRJ9_sg)
- [Implementing A Custom Authorization Handler In ASP.NET Core](https://youtu.be/SZtZuvcMBA0)
- [Using Custom JWT Claims For Authorization In ASP.NET Core](https://youtu.be/SUyFPp6BPV0)

---

## Frequently asked questions

### What is API key authentication?

API key authentication uses an API key to authenticate the client of an API. The key can be passed to the API in a few ways, such as through the query string or a request header like X-API-Key.

### When should you use API key authentication?

API key authentication is common in server-to-server (S2S) communication, where your API serves requests for other server-side applications to consume and integrate with. It is less common in client-server communication scenarios.

### How do you implement API key authentication in ASP.NET Core?

Create an attribute deriving from ServiceFilterAttribute that points to an IAuthorizationFilter implementation. The filter reads the API key from the request header, validates it, and sets an UnauthorizedResult on the context when the key is not valid.

### Why use a ServiceFilterAttribute for API key authentication?

ServiceFilterAttribute lets you specify the filter type that will be resolved from the dependency injection container. That gives your IAuthorizationFilter implementation full dependency injection support, so the validator can, for example, check the provided API key against a database.

### Can you apply API key authentication to an entire controller?

Yes. You can place the API key attribute on a single endpoint, or on the controller class itself, which adds authentication to all the endpoints of that controller.
