Alfa1.TokenStorage.PostgreSQL
0.0.1-preview-05
dotnet add package Alfa1.TokenStorage.PostgreSQL --version 0.0.1-preview-05
NuGet\Install-Package Alfa1.TokenStorage.PostgreSQL -Version 0.0.1-preview-05
<PackageReference Include="Alfa1.TokenStorage.PostgreSQL" Version="0.0.1-preview-05" />
<PackageVersion Include="Alfa1.TokenStorage.PostgreSQL" Version="0.0.1-preview-05" />
<PackageReference Include="Alfa1.TokenStorage.PostgreSQL" />
paket add Alfa1.TokenStorage.PostgreSQL --version 0.0.1-preview-05
#r "nuget: Alfa1.TokenStorage.PostgreSQL, 0.0.1-preview-05"
#:package Alfa1.TokenStorage.PostgreSQL@0.0.1-preview-05
#addin nuget:?package=Alfa1.TokenStorage.PostgreSQL&version=0.0.1-preview-05&prerelease
#tool nuget:?package=Alfa1.TokenStorage.PostgreSQL&version=0.0.1-preview-05&prerelease
Alfa1.TokenStorage - Registration Guide
This package family supports multiple storage providers for ITokenStorageService.
Registration styles
All providers support these patterns:
- Default registration (single
ITokenStorageService) - Keyed registration (multiple named token stores)
- Consumer-bound registration (bind a dependent type to one token identifier)
SQL Server
// Default registration (single ITokenStorageService)
services.AddTokenStorageSqlServer(configuration);
// Keyed registrations (multiple named token stores)
services.AddKeyedTokenStorageSqlServer("TypeA", "TypeAToken", configuration);
services.AddKeyedTokenStorageSqlServer("TypeB", "TypeBToken", configuration);
// Individual registrations (bind token store per dependent type)
services.AddTokenStorageSqlServerFor<TypeA>(configuration, "TypeAToken");
services.AddTokenStorageSqlServerFor<TypeB>(configuration); // defaults to "TypeB"
SQL Server schema initialization is explicit and should be done during app startup, after DI registration:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTokenStorageSqlServer(builder.Configuration);
var app = builder.Build();
app.Services.InitializeTokenStorageSqlServer();
This startup-time initialization is the recommended pattern.
appsettings.json for SQL Server:
{
"ConnectionStrings": {
"Tokens": "Server=.;Database=TokenDb;Trusted_Connection=True;TrustServerCertificate=True"
},
"SqlServerTokenStorageOptions": {
"ConnectionStringName": "Tokens",
"TableName": "Tokens",
"TokenIdentifierColumnName": "TokenIdentifier",
"TokenIdentifier": "default",
"RefreshTokenColumnName": "RefreshToken",
"RefreshTokenUpdatedAtColumnName": "RefreshTokenUpdatedAt",
"AccessTokenColumnName": "AccessToken",
"AccessTokenUpdatedAtColumnName": "AccessTokenUpdatedAt",
"AccessTokenExpireColumnName": "AccessTokenExpireAt"
}
}
PostgreSQL
// Default registration (single ITokenStorageService)
services.AddAuthenticationTokenStoragePostgreSQL(configuration);
// Keyed registrations (multiple named token stores)
services.AddKeyedAuthenticationTokenStoragePostgreSQL("TypeA", "TypeAToken", configuration);
services.AddKeyedAuthenticationTokenStoragePostgreSQL("TypeB", "TypeBToken", configuration);
// Individual registrations (bind token store per dependent type)
services.AddAuthenticationTokenStoragePostgreSQLFor<TypeA>(configuration, "TypeAToken");
services.AddAuthenticationTokenStoragePostgreSQLFor<TypeB>(configuration); // defaults to "TypeB"
appsettings.json for PostgreSQL:
{
"ConnectionStrings": {
"Tokens": "Host=localhost;Port=5432;Database=token_db;Username=postgres;Password=postgres"
},
"PostgreSQLTokenStorageOptions": {
"ConnectionStringName": "Tokens",
"TableName": "Tokens",
"TokenIdentifierColumnName": "TokenIdentifier",
"TokenIdentifier": "default",
"RefreshTokenColumnName": "RefreshToken",
"RefreshTokenUpdatedAtColumnName": "RefreshTokenUpdatedAt",
"AccessTokenColumnName": "AccessToken",
"AccessTokenUpdatedAtColumnName": "AccessTokenUpdatedAt",
"AccessTokenExpireColumnName": "AccessTokenExpireAt"
}
}
File system
// Default registration (single ITokenStorageService)
services.AddTokenStorageFileSystem(configuration);
// Keyed registrations (multiple named token stores)
services.AddKeyedTokenStorageFileSystem("TypeA", "TypeAToken", configuration);
services.AddKeyedTokenStorageFileSystem("TypeB", "TypeBToken", configuration);
// Individual registrations (bind token store per dependent type)
services.AddTokenStorageFileSystemFor<TypeA>(configuration, "TypeAToken");
services.AddTokenStorageFileSystemFor<TypeB>(configuration); // defaults to "TypeB"
appsettings.json for File system:
{
"FileSystemTokenStorageOptions": {
"TokenIdentifier": "default",
"RefreshTokenFilePathTemplate": "tokens/refresh.{tokenIdentifier}.txt",
"AccessTokenFilePathTemplate": "tokens/access.{tokenIdentifier}.txt"
}
}
FileSystemTokenStorageOptions supports template paths using {tokenIdentifier}:
{
"FileSystemTokenStorageOptions": {
"RefreshTokenFilePathTemplate": "tokens/refresh.{tokenIdentifier}.txt",
"AccessTokenFilePathTemplate": "tokens/access.{tokenIdentifier}.txt"
}
}
For TypeAToken this resolves to tokens/refresh.TypeAToken.txt and tokens/access.TypeAToken.txt.
Azure Blobs
// Default registration (single ITokenStorageService)
services.AddTokenStorageAzureBlobs(configuration);
// Keyed registrations (multiple named token stores)
services.AddKeyedTokenStorageAzureBlobs("TypeA", "TypeAToken", configuration);
services.AddKeyedTokenStorageAzureBlobs("TypeB", "TypeBToken", configuration);
// Individual registrations (bind token store per dependent type)
services.AddTokenStorageAzureBlobsFor<TypeA>(configuration, "TypeAToken");
services.AddTokenStorageAzureBlobsFor<TypeB>(configuration); // defaults to "TypeB"
appsettings.json for Azure Blobs:
{
"AzureBlobsTokenStorageOptions": {
"ConnectionString": "<azure-storage-connection-string>",
"ContainerName": "tokens",
"TokenIdentifier": "default",
"RefreshTokenFilePathTemplate": "refresh.{tokenIdentifier}.txt",
"AccessTokenFilePathTemplate": "access.{tokenIdentifier}.txt"
}
}
AzureBlobsTokenStorageOptions supports template blob paths using {tokenIdentifier}:
{
"AzureBlobsTokenStorageOptions": {
"RefreshTokenFilePathTemplate": "refresh.{tokenIdentifier}.txt",
"AccessTokenFilePathTemplate": "access.{tokenIdentifier}.txt"
}
}
For TypeAToken this resolves to refresh.TypeAToken.txt and access.TypeAToken.txt.
Mix and match providers
You can register different providers side-by-side using keyed services:
services.AddKeyedTokenStorageSqlServer("ApiA", "ApiAToken", configuration);
services.AddKeyedTokenStorageAzureBlobs("ApiB", "ApiBToken", configuration);
Then resolve by key where needed:
var tokenStorageA = serviceProvider.GetRequiredKeyedService<ITokenStorageService>("ApiA");
var tokenStorageB = serviceProvider.GetRequiredKeyedService<ITokenStorageService>("ApiB");
Notes
ITokenStorageServiceremains unchanged.- Token scoping is controlled internally by
tokenIdentifier. - If you omit
tokenIdentifierin...For<T>(), the default is the dependent type name.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net8.0
- Alfa1.TokenStorage.Abstractions (>= 0.0.1-preview-05)
- Microsoft.Bcl.TimeProvider (>= 8.0.1)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 8.0.0)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 8.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1-preview-05 | 55 | 5/20/2026 |
| 0.0.1-preview-04 | 47 | 5/19/2026 |
| 0.0.1-preview-02 | 51 | 5/19/2026 |
| 0.0.1-preview-01 | 53 | 5/12/2026 |
| 0.0.1-preview.3 | 51 | 5/19/2026 |