WebApi.Authentication 1.2.0

dotnet add package WebApi.Authentication --version 1.2.0
                    
NuGet\Install-Package WebApi.Authentication -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WebApi.Authentication" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WebApi.Authentication" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="WebApi.Authentication" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WebApi.Authentication --version 1.2.0
                    
#r "nuget: WebApi.Authentication, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WebApi.Authentication@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WebApi.Authentication&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=WebApi.Authentication&version=1.2.0
                    
Install as a Cake Tool

Want to see what's changed?

Changelog

WebApi.Authentication

Simplifies issuing, authenticating, and maintaining Api Secrets for you publicly facing WebApi.

It's using Microsoft's JwtBearer package, and centered around Jwt as the primary authentication mechanism.

On top of that it adds a storage repository where secrets are stored. This in turn allows you to revoke a secret, something that's otherwise not possible with a long-lived Jwt token.

Installation

I recommend using the NuGet package: WebApi.Authentication however feel free to clone the source instead if that suits your needs better.

Usage

Separation of concerns

Since this solution is mainly intended for public facing WebApi's, I'd suggest splitting your solution into two WebApi projects:

  • One that requires User based Authentication, which allows the user to issue Api secrets for the publicly facing Api
  • One publicly facing Api that requires Api secrets for its usage

This has 2 benefits:

  • Simplifies configuration of Authentication, as you'll only have one mechanism per project (User based in one, Api secret based in the other)
  • Avoids the "Noisy neighbor" syndrome, where a lot of traffic hitting your publicly facing Api could render your application Api unavailable

As such each has a slightly different setup, as shown below.

Issuing new tokens

The solution is based around .Net's built-in Dependency Injection system. As such start by injecting the necessary bits:

var builder = WebApplication.CreateBuilder(args);

var secretKey = RandomNumberGenerator.GetBytes(64); // You should generate this key once per environment you run, and store it securely.

var configuration = new AuthenticationConfiguration
{
    SecretKey = secretKey, 
    Issuer = "YOUR_NAME", // Could be the name of your company, yourself or similar - just pick one and stick with it.
    Audience = "YOUR_AUDIENCE", // Could be the name of your application or similar - just pick one and stick with it.
    Expiration = TimeSpan.FromDays(30) // How long should the token be valid for
};

// For this example we'll use a MongoDB database for storage
var client = new MongoClient("mongodb://localhost:27017"); // You should use a connection string here.
var db = client.GetDatabase("my_db");

builder.Services.AddApiSecretProvider(configuration) // Adds the IApiSecretProvider to the DI container
                .AddApiSecretMongoRepository(db, "api-secrets");

Now you'll have access to the IApiSecretProvider which you can use to store new Api secrets:

var secret = new ApiSecret(); 
await provider.PersistSecretAsync(secret);

// secret.JwtToken is now a valid JWT token and can be given to the 3rd party for usage.

Configuring Authentication of the tokens

Just like with issuing tokens, we'll need the same configuration:

var builder = WebApplication.CreateBuilder(args);

var secretKey = RandomNumberGenerator.GetBytes(64); // You should generate this key once per environment you run, and store it securely.

var configuration = new AuthenticationConfiguration
{
    SecretKey = secretKey, 
    Issuer = "YOUR_NAME", // Could be the name of your company, yourself or similar - just pick one and stick with it.
    Audience = "YOUR_AUDIENCE", // Could be the name of your application or similar - just pick one and stick with it.
    Expiration = TimeSpan.FromDays(30) // How long should the token be valid for
};

// For this example we'll use a MongoDB database for storage
var client = new MongoClient("mongodb://localhost:27017"); // You should use a connection string here.
var db = client.GetDatabase("my_db");

builder.Services.AddApiSecretAuthentication(configuration, jwtBearerOptions =>
{
    if (builder.Environment.IsDevelopment()) // Disables HTTPs requirement in development
    {
        jwtBearerOptions.RequireHttpsMetadata = false;
    }
})
.AddApiSecretMongoRepository(db, "api-secrets");

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

And that's it for the authentication part, now you can mark any endpoints that requires Authentication with either [Authorize] or .RequireAuthorization() depending on whether you're using Controllers or Minimal APIs.

Data segregation

The above Usage examples are all based on the default data model, where the ApiSecret class is used to store the secrets in a single repository. It only contains the bare essentials for issuing and revoking tokens. However if you want to do data segregation, that's built-in as well.

I'd suggest defining a custom type for your secrets, rather than using generics everywhere, but it's up to you.

public class CustomerApiSecret : SegregatedApiSecret<CustomerId>;

And that's all for configuration.

For your Dependency Injection you'll just need to use the Segregated methods instead of the "normal" ones:

builder.Services.AddSegregatedApiSecretAuthentication<CustomerApiSecret, CustomerId>(configuration, jwtBearerOptions =>
{
    if (builder.Environment.IsDevelopment())
    {
        jwtBearerOptions.RequireHttpsMetadata = false;
    }
});

builder.Services.AddSegregatedApiSecretProvider<CustomerApiSecret, CustomerId>(configuration)
                .AddSegregatedApiSecretMongoRepository((provider, key) =>
                {
                    var client = provider.GetRequiredService<IMongoClient>();
                    var db = client.GetDatabase($"my_db_{key}"); // Segregate at db level
                    var collection = db.GetCollection<CustomerApiSecret>("api-secrets"); // You could segregate here instead/as well
                    return collection;
                });

Customization

The above examples are very bare-bones in terms of data, so what if you'd like to include e.g. roles in your secrets?

Luckily this is really simple, just define a custom type for your secrets, and extend the model as you see fit. e.g.

public class RoleBasedApiSecret : ApiSecret
{
    public required string[] Roles {get; init;}
}

And specify RoleBasedApiSecret when doing your DI, and you're all set 😃

builder.Services.AddApiSecretAuthentication<RoleBasedApiSecret>(configuration, jwtBearerOptions =>
{
    if (builder.Environment.IsDevelopment())
    {
        jwtBearerOptions.RequireHttpsMetadata = false;
    }
});

builder.Services.AddApiSecretProvider<RoleBasedApiSecret>(configuration)
    .AddApiSecretMongoRepository(db, "api-secrets");

Documentation

Auto generated documentation via DocFx is available here: https://steffenskov.github.io/WebApi.Authentication/

Compatibility

MongoDB

This is supported through the package WebApi.Authentication.MongoDB.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on WebApi.Authentication:

Package Downloads
WebApi.Authentication.MongoDB

Storage extension for WebApi.Authentication to support MongoDB.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 1,539 7/4/2026
1.1.0 430 3/21/2026
1.0.0 179 3/15/2026