![]() |
VOOZH | about |
dotnet add package Indiko.Blocks.Security.Authentication.Abstractions --version 2.8.0
NuGet\Install-Package Indiko.Blocks.Security.Authentication.Abstractions -Version 2.8.0
<PackageReference Include="Indiko.Blocks.Security.Authentication.Abstractions" Version="2.8.0" />
<PackageVersion Include="Indiko.Blocks.Security.Authentication.Abstractions" Version="2.8.0" />Directory.Packages.props
<PackageReference Include="Indiko.Blocks.Security.Authentication.Abstractions" />Project file
paket add Indiko.Blocks.Security.Authentication.Abstractions --version 2.8.0
#r "nuget: Indiko.Blocks.Security.Authentication.Abstractions, 2.8.0"
#:package Indiko.Blocks.Security.Authentication.Abstractions@2.8.0
#addin nuget:?package=Indiko.Blocks.Security.Authentication.Abstractions&version=2.8.0Install as a Cake Addin
#tool nuget:?package=Indiko.Blocks.Security.Authentication.Abstractions&version=2.8.0Install as a Cake Tool
Core authentication abstractions for implementing secure authentication and token management in the Indiko framework.
This package provides fundamental contracts and models for implementing authentication systems, including JWT tokens, identity management, and token providers.
dotnet add package Indiko.Blocks.Security.Authentication.Abstractions
Interface for generating authentication tokens.
public interface ITokenProvider
{
Task<TokenResponse> GetToken(IdentityUser user, CancellationToken cancellationToken = default);
Task<TokenResponse> GetToken(IdentityUser user, Dictionary<string, string> customClaims,
CancellationToken cancellationToken = default);
Task<TokenResponse> GetToken(IdentityClient client, CancellationToken cancellationToken = default);
}
Represents authentication token response.
public sealed class TokenResponse
{
public Dictionary<string, string> Properties { get; init; }
public required string AccessToken { get; init; }
public required string IdentityToken { get; init; }
public required string RefreshToken { get; init; }
}
Represents an authenticated user.
public class IdentityUser
{
public string UserId { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string[] Roles { get; set; }
public Dictionary<string, string> Claims { get; set; }
}
Represents a client application or service.
public class IdentityClient
{
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string[] Scopes { get; set; }
}
public class JwtTokenProvider : ITokenProvider
{
private readonly AuthenticationOptions _options;
private readonly ILogger<JwtTokenProvider> _logger;
public JwtTokenProvider(
IOptions<AuthenticationOptions> options,
ILogger<JwtTokenProvider> logger)
{
_options = options.Value;
_logger = logger;
}
public async Task<TokenResponse> GetToken(
IdentityUser user,
CancellationToken cancellationToken = default)
{
var claims = new List<Claim>
{
new(ClaimTypes.NameIdentifier, user.UserId),
new(ClaimTypes.Name, user.Username),
new(ClaimTypes.Email, user.Email)
};
foreach (var role in user.Roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
var token = GenerateJwtToken(claims);
var refreshToken = GenerateRefreshToken();
return new TokenResponse
{
AccessToken = token,
IdentityToken = token,
RefreshToken = refreshToken,
Properties = new Dictionary<string, string>
{
{ "expires_in", "3600" },
{ "token_type", "Bearer" }
}
};
}
public async Task<TokenResponse> GetToken(
IdentityUser user,
Dictionary<string, string> customClaims,
CancellationToken cancellationToken = default)
{
var tokenResponse = await GetToken(user, cancellationToken);
// Add custom claims to properties
foreach (var claim in customClaims)
{
tokenResponse.Properties[claim.Key] = claim.Value;
}
return tokenResponse;
}
public async Task<TokenResponse> GetToken(
IdentityClient client,
CancellationToken cancellationToken = default)
{
// Client credentials flow
var claims = new List<Claim>
{
new("client_id", client.ClientId),
new("scope", string.Join(" ", client.Scopes))
};
var token = GenerateJwtToken(claims);
return new TokenResponse
{
AccessToken = token,
IdentityToken = token,
RefreshToken = string.Empty,
Properties = new Dictionary<string, string>
{
{ "expires_in", "3600" },
{ "token_type", "Bearer" }
}
};
}
}
public class AuthenticationService
{
private readonly ITokenProvider _tokenProvider;
private readonly IUserRepository _userRepository;
public AuthenticationService(
ITokenProvider tokenProvider,
IUserRepository userRepository)
{
_tokenProvider = tokenProvider;
_userRepository = userRepository;
}
public async Task<TokenResponse> AuthenticateAsync(
string username,
string password)
{
// Validate credentials
var user = await _userRepository.ValidateCredentialsAsync(username, password);
if (user == null)
throw new UnauthorizedAccessException("Invalid credentials");
// Create identity user
var identityUser = new IdentityUser
{
UserId = user.Id.ToString(),
Username = user.Username,
Email = user.Email,
Roles = user.Roles.ToArray()
};
// Generate tokens
return await _tokenProvider.GetToken(identityUser);
}
public async Task<TokenResponse> AuthenticateWithCustomClaimsAsync(
string username,
string password,
Dictionary<string, string> customClaims)
{
var user = await _userRepository.ValidateCredentialsAsync(username, password);
if (user == null)
throw new UnauthorizedAccessException("Invalid credentials");
var identityUser = new IdentityUser
{
UserId = user.Id.ToString(),
Username = user.Username,
Email = user.Email,
Roles = user.Roles.ToArray()
};
return await _tokenProvider.GetToken(identityUser, customClaims);
}
}
Helper methods for working with claims.
using Indiko.Blocks.Security.Authentication.Abstractions.Extensions;
public class UserService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public string GetCurrentUserId()
{
var identity = _httpContextAccessor.HttpContext?.User?.Identity as ClaimsIdentity;
return identity?.GetUserId();
}
public string GetCurrentUserEmail()
{
var identity = _httpContextAccessor.HttpContext?.User?.Identity as ClaimsIdentity;
return identity?.GetUserEmail();
}
public string[] GetCurrentUserRoles()
{
var identity = _httpContextAccessor.HttpContext?.User?.Identity as ClaimsIdentity;
return identity?.GetRoles();
}
public bool HasRole(string role)
{
var identity = _httpContextAccessor.HttpContext?.User?.Identity as ClaimsIdentity;
return identity?.HasRole(role) ?? false;
}
}
Configuration model for authentication settings.
public class AuthenticationOptions
{
public string Authority { get; set; }
public string Audience { get; set; }
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string[] Scopes { get; set; }
public string SigningKey { get; set; }
public string Issuer { get; set; }
public int TokenExpirationMinutes { get; set; } = 60;
public int RefreshTokenExpirationDays { get; set; } = 7;
}
{
"AuthenticationOptions": {
"Authority": "https://identity.example.com",
"Audience": "api.example.com",
"ClientId": "my-api",
"ClientSecret": "secret",
"Scopes": ["openid", "profile", "email", "api"],
"SigningKey": "your-256-bit-secret-key-here",
"Issuer": "https://api.example.com",
"TokenExpirationMinutes": 60,
"RefreshTokenExpirationDays": 7
}
}
Custom exception for token validation errors.
public class TokenValidationException : Exception
{
public TokenValidationException(string message) : base(message)
{
}
public TokenValidationException(string message, Exception innerException)
: base(message, innerException)
{
}
}
public class TokenValidator
{
public void ValidateToken(string token)
{
try
{
// Validate token logic
if (string.IsNullOrEmpty(token))
throw new TokenValidationException("Token is null or empty");
// Additional validation
}
catch (Exception ex)
{
throw new TokenValidationException("Token validation failed", ex);
}
}
}
public class LoginController : ControllerBase
{
private readonly ITokenProvider _tokenProvider;
private readonly IUserRepository _userRepository;
[HttpPost("login")]
public async Task<IActionResult> Login([FromBody] LoginRequest request)
{
// 1. Validate credentials
var user = await _userRepository.ValidateCredentialsAsync(
request.Username,
request.Password);
if (user == null)
return Unauthorized(new { error = "Invalid credentials" });
// 2. Create identity user
var identityUser = new IdentityUser
{
UserId = user.Id.ToString(),
Username = user.Username,
Email = user.Email,
Roles = user.Roles.ToArray(),
Claims = new Dictionary<string, string>
{
{ "tenant_id", user.TenantId.ToString() },
{ "subscription_tier", user.SubscriptionTier }
}
};
// 3. Generate tokens
var tokenResponse = await _tokenProvider.GetToken(identityUser);
// 4. Return tokens
return Ok(new
{
access_token = tokenResponse.AccessToken,
refresh_token = tokenResponse.RefreshToken,
expires_in = tokenResponse.Properties["expires_in"],
token_type = tokenResponse.Properties["token_type"]
});
}
}
public class ClientAuthenticationService
{
private readonly ITokenProvider _tokenProvider;
public async Task<TokenResponse> AuthenticateClientAsync(
string clientId,
string clientSecret)
{
// Validate client credentials
if (!IsValidClient(clientId, clientSecret))
throw new UnauthorizedAccessException("Invalid client credentials");
var client = new IdentityClient
{
ClientId = clientId,
ClientSecret = clientSecret,
Scopes = new[] { "api.read", "api.write" }
};
return await _tokenProvider.GetToken(client);
}
}
public class TokenRefreshService
{
private readonly ITokenProvider _tokenProvider;
private readonly IRefreshTokenRepository _refreshTokenRepository;
public async Task<TokenResponse> RefreshTokenAsync(string refreshToken)
{
// Validate refresh token
var storedToken = await _refreshTokenRepository.GetByTokenAsync(refreshToken);
if (storedToken == null || storedToken.IsExpired)
throw new TokenValidationException("Invalid or expired refresh token");
// Get user
var user = await GetUserByIdAsync(storedToken.UserId);
var identityUser = new IdentityUser
{
UserId = user.Id.ToString(),
Username = user.Username,
Email = user.Email,
Roles = user.Roles.ToArray()
};
// Generate new tokens
var newTokens = await _tokenProvider.GetToken(identityUser);
// Revoke old refresh token
await _refreshTokenRepository.RevokeAsync(refreshToken);
return newTokens;
}
}
Indiko.Blocks.Common.AbstractionsSee LICENSE file in the repository root.
Indiko.Blocks.Security.Authentication.ASPNetCore - ASP.NET Core authentication implementationIndiko.Blocks.Security.AuthenticationProvider.Abstractions - Authentication provider abstractionsIndiko.Blocks.Security.AuthenticationProvider.Blazor - Blazor authentication providerIndiko.Hosting.Web - Web API hosting| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 2 NuGet packages that depend on Indiko.Blocks.Security.Authentication.Abstractions:
| Package | Downloads |
|---|---|
|
Indiko.Blocks.Security.Authentication.ASPNetCore
Building Blocks Security Authentication ASPNet Core |
|
|
Indiko.Blocks.Security.Authentication.OpenIdDict
Building Blocks Security Authentication Open Id Dict |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.8.0 | 114 | 5/22/2026 |
| 2.7.8 | 121 | 5/7/2026 |
| 2.7.7 | 109 | 5/7/2026 |
| 2.7.6 | 121 | 4/23/2026 |
| 2.7.5 | 108 | 4/23/2026 |
| 2.7.4 | 113 | 4/23/2026 |
| 2.7.3 | 120 | 4/23/2026 |
| 2.7.2 | 113 | 4/23/2026 |
| 2.7.1 | 108 | 4/23/2026 |
| 2.7.0 | 120 | 4/23/2026 |
| 2.6.4 | 105 | 4/21/2026 |
| 2.6.3 | 111 | 4/21/2026 |
| 2.6.2 | 115 | 4/21/2026 |
| 2.6.1 | 115 | 4/18/2026 |
| 2.6.0 | 124 | 4/17/2026 |
| 2.5.1 | 119 | 4/14/2026 |
| 2.5.0 | 161 | 3/30/2026 |
| 2.2.18 | 131 | 3/8/2026 |
| 2.2.17 | 116 | 3/8/2026 |
| 2.2.16 | 115 | 3/8/2026 |