MasLazu.AspNet.ApiKey
1.0.0-preview.1
dotnet add package MasLazu.AspNet.ApiKey --version 1.0.0-preview.1
NuGet\Install-Package MasLazu.AspNet.ApiKey -Version 1.0.0-preview.1
<PackageReference Include="MasLazu.AspNet.ApiKey" Version="1.0.0-preview.1" />
<PackageVersion Include="MasLazu.AspNet.ApiKey" Version="1.0.0-preview.1" />
<PackageReference Include="MasLazu.AspNet.ApiKey" />
paket add MasLazu.AspNet.ApiKey --version 1.0.0-preview.1
#r "nuget: MasLazu.AspNet.ApiKey, 1.0.0-preview.1"
#:package MasLazu.AspNet.ApiKey@1.0.0-preview.1
#addin nuget:?package=MasLazu.AspNet.ApiKey&version=1.0.0-preview.1&prerelease
#tool nuget:?package=MasLazu.AspNet.ApiKey&version=1.0.0-preview.1&prerelease
MasLazu.AspNet.ApiKey
Core service layer implementing the API key management interfaces defined in MasLazu.AspNet.ApiKey.Abstraction.
Overview
This project contains the concrete implementations of the API key management services defined in the abstraction layer. It provides the business logic for managing API keys and their associated permission scopes, implementing the contracts specified in MasLazu.AspNet.ApiKey.Abstraction.
Architecture Relationship
This service layer implements the interfaces defined in MasLazu.AspNet.ApiKey.Abstraction:
ApiKeyServiceimplementsIApiKeyServiceApiKeyScopeServiceimplementsIApiKeyScopeService
The services inherit from CrudService<T, TDto, TCreate, TUpdate> to provide standard CRUD operations while implementing custom business logic for API key management.
Core Services
ApiKeyService
Main service implementing IApiKeyService for comprehensive API key management:
public class ApiKeyService : CrudService<Domain.Entities.ApiKey, ApiKeyDto, CreateApiKeyRequest, UpdateApiKeyRequest>, IApiKeyService
Key Methods:
RevokeAsync(): Revoke an API key by setting RevokedDateRotateAsync(): Generate new key value while preserving the key recordValidateAsync(): Validate key with permission checkingRevokeAllForUserAsync(): Bulk revoke all keys for a userUpdateLastUsedAsync(): Track key usage for monitoringGetByUserIdAsync(): Retrieve all keys for a specific user
ApiKeyScopeService
Service for managing permission scopes associated with API keys:
public class ApiKeyScopeService : CrudService<ApiKeyScope, ApiKeyScopeDto, CreateApiKeyScopeRequest, UpdateApiKeyScopeRequest>, IApiKeyScopeService
Key Methods:
AddScopeAsync(): Grant a permission to an API keyRemoveScopeAsync(): Revoke a permission from an API key
Business Logic Implementation
Key Rotation
public async Task<ApiKeyDto> RotateAsync(Guid userId, Guid apiKeyId, CancellationToken ct = default)
{
Domain.Entities.ApiKey? apiKey = await Repository.GetByIdAsync(apiKeyId, ct) ??
throw new NotFoundException("API key not found.");
apiKey.Key = Guid.NewGuid().ToString("N");
await Repository.UpdateAsync(apiKey, ct);
await UnitOfWork.SaveChangesAsync(ct);
return apiKey.Adapt<ApiKeyDto>();
}
Key Validation
public async Task<bool> ValidateAsync(ValidateApiKeyRequest request, CancellationToken ct = default)
{
return await ReadRepository.ExistsAsync(x =>
x.Key == request.Key &&
x.RevokedDate == null &&
(x.ExpiresDate == null || x.ExpiresDate > DateTime.UtcNow) &&
x.Scopes.Any(s => s.PermissionId == request.PermissionId), ct);
}
Extensions
Service Registration
public static class ApiKeyApplicationServiceExtension
{
public static IServiceCollection AddApiKeyApplicationServices(this IServiceCollection services)
{
services.AddScoped<IApiKeyService, ApiKeyService>();
services.AddScoped<IApiKeyScopeService, ApiKeyScopeService>();
return services;
}
}
Validators
Request validation using FluentValidation:
CreateApiKeyRequestValidator
public class CreateApiKeyRequestValidator : AbstractValidator<CreateApiKeyRequest>
{
public CreateApiKeyRequestValidator()
{
RuleFor(x => x.UserId).NotEmpty();
RuleFor(x => x.Name).MaximumLength(100).When(x => !string.IsNullOrEmpty(x.Name));
RuleFor(x => x.ExpiresDate).GreaterThan(DateTime.UtcNow)
.When(x => x.ExpiresDate.HasValue)
.WithMessage("Expiration date must be in the future.");
}
}
Property Maps
Entity property mapping for dynamic queries:
ApiKeyEntityPropertyMap
public class ApiKeyEntityPropertyMap : IEntityPropertyMap<Domain.Entities.ApiKey>
{
private readonly Dictionary<string, Expression<Func<Domain.Entities.ApiKey, object>>> _map = new()
{
{ "id", ak => ak.Id },
{ "userId", ak => ak.UserId },
{ "key", ak => ak.Key },
{ "name", ak => ak.Name! },
{ "expiresDate", ak => ak.ExpiresDate! },
{ "lastUsed", ak => ak.LastUsed! },
{ "revokedDate", ak => ak.RevokedDate! },
{ "createdAt", ak => ak.CreatedAt },
{ "updatedAt", ak => ak.UpdatedAt! }
};
}
Dependencies
- .NET 9.0
- Microsoft.Extensions.DependencyInjection (9.0.9)
- MasLazu.AspNet.ApiKey.Abstraction (implements interfaces from this project)
- MasLazu.AspNet.ApiKey.Domain (uses domain entities from this project)
Dependencies Diagram
graph TD
A[MasLazu.AspNet.ApiKey] --> B[MasLazu.AspNet.ApiKey.Abstraction]
A --> C[MasLazu.AspNet.ApiKey.Domain]
B --> D[MasLazu.AspNet.Framework.Application]
C --> E[MasLazu.AspNet.Framework.Domain]
Key Features
Security
- Secure key generation using
Guid.NewGuid().ToString("N") - Key validation with expiration and revocation checks
- Permission-based access control through scopes
Error Handling
NotFoundExceptionfor missing entities- Proper exception messages for debugging
- Graceful handling of edge cases
Performance
- Async/await throughout for non-blocking operations
- Efficient database queries with proper indexing
- Cancellation token support for request cancellation
Maintainability
- Clean separation of concerns
- Dependency injection for testability
- FluentValidation for request validation
- Mapster for object mapping
Project Structure
MasLazu.AspNet.ApiKey/
├── Services/
│ ├── ApiKeyService.cs
│ └── ApiKeyScopeService.cs
├── Extensions/
│ ├── ApiKeyApplicationExtension.cs
│ ├── ApiKeyApplicationServiceExtension.cs
│ ├── ApiKeyApplicationUtilExtension.cs
│ └── ApiKeyApplicationValidatorExtension.cs
├── Utils/
│ ├── ApiKeyEntityPropertyMap.cs
│ └── ApiKeyScopeEntityPropertyMap.cs
├── Validators/
│ ├── CreateApiKeyRequestValidator.cs
│ ├── CreateApiKeyScopeRequestValidator.cs
│ ├── UpdateApiKeyRequestValidator.cs
│ └── UpdateApiKeyScopeRequestValidator.cs
└── MasLazu.AspNet.ApiKey.csproj
Usage
Service Registration
builder.Services.AddApiKeyApplicationServices();
Using Services
// Inject services
private readonly IApiKeyService _apiKeyService;
private readonly IApiKeyScopeService _apiKeyScopeService;
// Create API key
var createRequest = new CreateApiKeyRequest(userId, "My API Key", DateTime.UtcNow.AddDays(30));
var apiKey = await _apiKeyService.CreateAsync(userId, createRequest);
// Validate API key
var isValid = await _apiKeyService.ValidateAsync(new ValidateApiKeyRequest("key", permissionId));
// Rotate API key
var rotatedKey = await _apiKeyService.RotateAsync(userId, apiKey.Id);
Design Principles
- SOLID: Single responsibility, open/closed, dependency inversion
- Clean Architecture: Business logic independent of infrastructure
- Dependency Injection: Constructor injection for testability
- Async Programming: Non-blocking operations with cancellation support
- Validation: Input validation with meaningful error messages
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. 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. |
-
net9.0
- MasLazu.AspNet.ApiKey.Abstraction (>= 1.0.0-preview.1)
- MasLazu.AspNet.ApiKey.Domain (>= 1.0.0-preview.1)
- Microsoft.Extensions.DependencyInjection (>= 9.0.9)
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 |
|---|---|---|
| 1.0.0-preview.1 | 209 | 9/20/2025 |
See RELEASES.md for release notes.