Fingent-ASPNet-Identity
1.0.1
dotnet add package Fingent-ASPNet-Identity --version 1.0.1
NuGet\Install-Package Fingent-ASPNet-Identity -Version 1.0.1
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="Fingent-ASPNet-Identity" Version="1.0.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Fingent-ASPNet-Identity" Version="1.0.1" />
<PackageReference Include="Fingent-ASPNet-Identity" />
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 Fingent-ASPNet-Identity --version 1.0.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Fingent-ASPNet-Identity, 1.0.1"
#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 Fingent-ASPNet-Identity@1.0.1
#: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=Fingent-ASPNet-Identity&version=1.0.1
#tool nuget:?package=Fingent-ASPNet-Identity&version=1.0.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Fingent ASP.NET Identity
A comprehensive ASP.NET Core Identity implementation for .NET applications. Provides a complete authentication and authorization system with user management, role-based security, and extensible identity features built on top of Microsoft's Identity framework.
?? Features
- Complete Identity System: User registration, authentication, and authorization
- Role-Based Security: Comprehensive role and claims management
- Entity Framework Integration: Built on EF Core with customizable data models
- Password Security: Advanced password policies and security features
- Two-Factor Authentication: Support for 2FA with multiple providers
- External Login Providers: Integration with Google, Microsoft, Facebook, etc.
- Account Management: Email confirmation, password reset, and account lockout
- Extensible User Model: Customizable user properties and data
?? Installation
dotnet add package Fingent-ASPNet-Identity
?? Dependencies
- .NET 8.0
- Microsoft.AspNetCore.Identity 2.1.39
- Microsoft.AspNetCore.Identity.EntityFrameworkCore 8.0.8
- Microsoft.AspNetCore.Identity.UI 8.0.8
- Microsoft.Extensions.DependencyInjection 8.0.0
- Fingent.Shared.Core
?? Usage
Basic Setup
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add Identity services
builder.Services.AddFingentIdentity<ApplicationDbContext>(options =>
{
// Password requirements
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequiredLength = 8;
// Lockout settings
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(15);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings
options.User.RequireUniqueEmail = true;
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
// Sign-in settings
options.SignIn.RequireConfirmedEmail = true;
options.SignIn.RequireConfirmedPhoneNumber = false;
});
var app = builder.Build();
// Configure authentication middleware
app.UseAuthentication();
app.UseAuthorization();
Custom User Model
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
public string ProfilePicture { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? LastLoginAt { get; set; }
public bool IsActive { get; set; } = true;
public string Department { get; set; }
public string JobTitle { get; set; }
// Navigation properties
public ICollection<UserRole> UserRoles { get; set; } = new List<UserRole>();
public ICollection<UserClaim> UserClaims { get; set; } = new List<UserClaim>();
}
public class ApplicationRole : IdentityRole
{
public string Description { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public bool IsSystem { get; set; } = false;
public ICollection<UserRole> UserRoles { get; set; } = new List<UserRole>();
}
public class UserRole : IdentityUserRole<string>
{
public DateTime AssignedAt { get; set; } = DateTime.UtcNow;
public string AssignedBy { get; set; }
public ApplicationUser User { get; set; }
public ApplicationRole Role { get; set; }
}
DbContext Configuration
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string,
IdentityUserClaim<string>, UserRole, IdentityUserLogin<string>,
IdentityRoleClaim<string>, IdentityUserToken<string>>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Configure Identity tables
builder.Entity<ApplicationUser>(entity =>
{
entity.Property(e => e.FirstName).HasMaxLength(50);
entity.Property(e => e.LastName).HasMaxLength(50);
entity.Property(e => e.Department).HasMaxLength(100);
entity.Property(e => e.JobTitle).HasMaxLength(100);
});
builder.Entity<ApplicationRole>(entity =>
{
entity.Property(e => e.Description).HasMaxLength(255);
});
builder.Entity<UserRole>(entity =>
{
entity.HasKey(ur => new { ur.UserId, ur.RoleId });
entity.HasOne(ur => ur.User)
.WithMany(u => u.UserRoles)
.HasForeignKey(ur => ur.UserId);
entity.HasOne(ur => ur.Role)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.RoleId);
});
// Seed default roles
SeedRoles(builder);
}
private void SeedRoles(ModelBuilder builder)
{
var roles = new[]
{
new ApplicationRole { Id = "1", Name = "Administrator", NormalizedName = "ADMINISTRATOR", Description = "Full system access", IsSystem = true },
new ApplicationRole { Id = "2", Name = "Manager", NormalizedName = "MANAGER", Description = "Management access", IsSystem = true },
new ApplicationRole { Id = "3", Name = "User", NormalizedName = "USER", Description = "Standard user access", IsSystem = true }
};
builder.Entity<ApplicationRole>().HasData(roles);
}
}
User Management Service
public class UserManagementService
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ILogger<UserManagementService> _logger;
public UserManagementService(
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
SignInManager<ApplicationUser> signInManager,
ILogger<UserManagementService> logger)
{
_userManager = userManager;
_roleManager = roleManager;
_signInManager = signInManager;
_logger = logger;
}
public async Task<IdentityResult> CreateUserAsync(CreateUserRequest request)
{
var user = new ApplicationUser
{
UserName = request.Email,
Email = request.Email,
FirstName = request.FirstName,
LastName = request.LastName,
Department = request.Department,
JobTitle = request.JobTitle,
EmailConfirmed = !request.RequireEmailConfirmation
};
var result = await _userManager.CreateAsync(user, request.Password);
if (result.Succeeded)
{
// Assign default role
await _userManager.AddToRoleAsync(user, "User");
// Add additional roles if specified
if (request.Roles?.Any() == true)
{
await _userManager.AddToRolesAsync(user, request.Roles);
}
_logger.LogInformation("User created: {Email}", request.Email);
}
return result;
}
public async Task<ApplicationUser> GetUserByIdAsync(string userId)
{
return await _userManager.FindByIdAsync(userId);
}
public async Task<ApplicationUser> GetUserByEmailAsync(string email)
{
return await _userManager.FindByEmailAsync(email);
}
public async Task<IdentityResult> UpdateUserAsync(string userId, UpdateUserRequest request)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
user.FirstName = request.FirstName;
user.LastName = request.LastName;
user.Department = request.Department;
user.JobTitle = request.JobTitle;
user.PhoneNumber = request.PhoneNumber;
var result = await _userManager.UpdateAsync(user);
if (result.Succeeded)
{
_logger.LogInformation("User updated: {UserId}", userId);
}
return result;
}
public async Task<IdentityResult> DeleteUserAsync(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
var result = await _userManager.DeleteAsync(user);
if (result.Succeeded)
{
_logger.LogInformation("User deleted: {UserId}", userId);
}
return result;
}
}
Authentication Service
public class AuthenticationService
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ILogger<AuthenticationService> _logger;
public AuthenticationService(
SignInManager<ApplicationUser> signInManager,
UserManager<ApplicationUser> userManager,
ILogger<AuthenticationService> logger)
{
_signInManager = signInManager;
_userManager = userManager;
_logger = logger;
}
public async Task<SignInResult> SignInAsync(SignInRequest request)
{
var user = await _userManager.FindByEmailAsync(request.Email);
if (user == null)
{
_logger.LogWarning("Sign-in attempt with non-existent email: {Email}", request.Email);
return SignInResult.Failed;
}
// Update last login time
user.LastLoginAt = DateTime.UtcNow;
await _userManager.UpdateAsync(user);
var result = await _signInManager.PasswordSignInAsync(
user.UserName,
request.Password,
request.RememberMe,
lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation("User signed in: {Email}", request.Email);
}
else if (result.IsLockedOut)
{
_logger.LogWarning("User account locked: {Email}", request.Email);
}
else if (result.RequiresTwoFactor)
{
_logger.LogInformation("Two-factor authentication required: {Email}", request.Email);
}
return result;
}
public async Task SignOutAsync()
{
await _signInManager.SignOutAsync();
_logger.LogInformation("User signed out");
}
public async Task<string> GenerateEmailConfirmationTokenAsync(ApplicationUser user)
{
return await _userManager.GenerateEmailConfirmationTokenAsync(user);
}
public async Task<IdentityResult> ConfirmEmailAsync(string userId, string token)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
var result = await _userManager.ConfirmEmailAsync(user, token);
if (result.Succeeded)
{
_logger.LogInformation("Email confirmed for user: {UserId}", userId);
}
return result;
}
public async Task<string> GeneratePasswordResetTokenAsync(string email)
{
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
return null;
return await _userManager.GeneratePasswordResetTokenAsync(user);
}
public async Task<IdentityResult> ResetPasswordAsync(string email, string token, string newPassword)
{
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
var result = await _userManager.ResetPasswordAsync(user, token, newPassword);
if (result.Succeeded)
{
_logger.LogInformation("Password reset for user: {Email}", email);
}
return result;
}
}
Role Management Service
public class RoleManagementService
{
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ILogger<RoleManagementService> _logger;
public RoleManagementService(
RoleManager<ApplicationRole> roleManager,
UserManager<ApplicationUser> userManager,
ILogger<RoleManagementService> logger)
{
_roleManager = roleManager;
_userManager = userManager;
_logger = logger;
}
public async Task<IdentityResult> CreateRoleAsync(string roleName, string description)
{
var role = new ApplicationRole
{
Name = roleName,
Description = description
};
var result = await _roleManager.CreateAsync(role);
if (result.Succeeded)
{
_logger.LogInformation("Role created: {RoleName}", roleName);
}
return result;
}
public async Task<IdentityResult> AssignRoleToUserAsync(string userId, string roleName)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
var result = await _userManager.AddToRoleAsync(user, roleName);
if (result.Succeeded)
{
_logger.LogInformation("Role {RoleName} assigned to user {UserId}", roleName, userId);
}
return result;
}
public async Task<IdentityResult> RemoveRoleFromUserAsync(string userId, string roleName)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
var result = await _userManager.RemoveFromRoleAsync(user, roleName);
if (result.Succeeded)
{
_logger.LogInformation("Role {RoleName} removed from user {UserId}", roleName, userId);
}
return result;
}
public async Task<IList<string>> GetUserRolesAsync(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return new List<string>();
return await _userManager.GetRolesAsync(user);
}
public async Task<IList<ApplicationUser>> GetUsersInRoleAsync(string roleName)
{
return await _userManager.GetUsersInRoleAsync(roleName);
}
}
Two-Factor Authentication
public class TwoFactorAuthenticationService
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ILogger<TwoFactorAuthenticationService> _logger;
public TwoFactorAuthenticationService(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ILogger<TwoFactorAuthenticationService> logger)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}
public async Task<IdentityResult> EnableTwoFactorAsync(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
await _userManager.SetTwoFactorEnabledAsync(user, true);
_logger.LogInformation("Two-factor authentication enabled for user: {UserId}", userId);
return IdentityResult.Success;
}
public async Task<IdentityResult> DisableTwoFactorAsync(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
await _userManager.SetTwoFactorEnabledAsync(user, false);
_logger.LogInformation("Two-factor authentication disabled for user: {UserId}", userId);
return IdentityResult.Success;
}
public async Task<string> GenerateTwoFactorTokenAsync(string userId, string provider)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return null;
return await _userManager.GenerateTwoFactorTokenAsync(user, provider);
}
public async Task<SignInResult> TwoFactorSignInAsync(string provider, string code, bool rememberMe, bool rememberMachine)
{
var result = await _signInManager.TwoFactorSignInAsync(provider, code, rememberMe, rememberMachine);
if (result.Succeeded)
{
_logger.LogInformation("Two-factor authentication successful");
}
return result;
}
}
Claims-Based Authorization
public class ClaimsService
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly ILogger<ClaimsService> _logger;
public ClaimsService(
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
ILogger<ClaimsService> logger)
{
_userManager = userManager;
_roleManager = roleManager;
_logger = logger;
}
public async Task<IdentityResult> AddClaimToUserAsync(string userId, string claimType, string claimValue)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
var claim = new Claim(claimType, claimValue);
var result = await _userManager.AddClaimAsync(user, claim);
if (result.Succeeded)
{
_logger.LogInformation("Claim added to user {UserId}: {ClaimType} = {ClaimValue}", userId, claimType, claimValue);
}
return result;
}
public async Task<IdentityResult> RemoveClaimFromUserAsync(string userId, string claimType, string claimValue)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return IdentityResult.Failed(new IdentityError { Description = "User not found" });
var claim = new Claim(claimType, claimValue);
var result = await _userManager.RemoveClaimAsync(user, claim);
if (result.Succeeded)
{
_logger.LogInformation("Claim removed from user {UserId}: {ClaimType} = {ClaimValue}", userId, claimType, claimValue);
}
return result;
}
public async Task<IList<Claim>> GetUserClaimsAsync(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
return new List<Claim>();
return await _userManager.GetClaimsAsync(user);
}
}
// Custom claims
public static class CustomClaims
{
public const string Permission = "permission";
public const string Department = "department";
public const string CanViewReports = "can_view_reports";
public const string CanEditUsers = "can_edit_users";
public const string CanDeleteData = "can_delete_data";
}
// Authorization policies
public static class AuthorizationPolicies
{
public const string RequireAdminRole = "RequireAdminRole";
public const string RequireManagerRole = "RequireManagerRole";
public const string CanViewReports = "CanViewReports";
public const string CanEditUsers = "CanEditUsers";
}
// In Program.cs - Configure authorization policies
builder.Services.AddAuthorization(options =>
{
options.AddPolicy(AuthorizationPolicies.RequireAdminRole,
policy => policy.RequireRole("Administrator"));
options.AddPolicy(AuthorizationPolicies.RequireManagerRole,
policy => policy.RequireRole("Administrator", "Manager"));
options.AddPolicy(AuthorizationPolicies.CanViewReports,
policy => policy.RequireClaim(CustomClaims.CanViewReports, "true"));
options.AddPolicy(AuthorizationPolicies.CanEditUsers,
policy => policy.RequireClaim(CustomClaims.CanEditUsers, "true"));
});
External Login Providers
// In Program.cs - Configure external providers
builder.Services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = builder.Configuration["Authentication:Google:ClientId"];
options.ClientSecret = builder.Configuration["Authentication:Google:ClientSecret"];
})
.AddMicrosoftAccount(options =>
{
options.ClientId = builder.Configuration["Authentication:Microsoft:ClientId"];
options.ClientSecret = builder.Configuration["Authentication:Microsoft:ClientSecret"];
})
.AddFacebook(options =>
{
options.AppId = builder.Configuration["Authentication:Facebook:AppId"];
options.AppSecret = builder.Configuration["Authentication:Facebook:AppSecret"];
});
public class ExternalLoginService
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ILogger<ExternalLoginService> _logger;
public ExternalLoginService(
SignInManager<ApplicationUser> signInManager,
UserManager<ApplicationUser> userManager,
ILogger<ExternalLoginService> logger)
{
_signInManager = signInManager;
_userManager = userManager;
_logger = logger;
}
public async Task<SignInResult> ExternalSignInAsync(string provider, string returnUrl = null)
{
var info = await _signInManager.GetExternalLoginInfoAsync();
if (info == null)
return SignInResult.Failed;
var result = await _signInManager.ExternalLoginSignInAsync(
info.LoginProvider,
info.ProviderKey,
isPersistent: false,
bypassTwoFactor: true);
if (result.Succeeded)
{
_logger.LogInformation("User signed in with {Provider}", provider);
return result;
}
// If the user doesn't have an account, create one
if (result.IsNotAllowed || result.IsLockedOut)
{
return result;
}
var email = info.Principal.FindFirstValue(ClaimTypes.Email);
if (email != null)
{
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
user = new ApplicationUser
{
UserName = email,
Email = email,
EmailConfirmed = true,
FirstName = info.Principal.FindFirstValue(ClaimTypes.GivenName),
LastName = info.Principal.FindFirstValue(ClaimTypes.Surname)
};
await _userManager.CreateAsync(user);
await _userManager.AddToRoleAsync(user, "User");
}
await _userManager.AddLoginAsync(user, info);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation("User created and signed in with {Provider}", provider);
return SignInResult.Success;
}
return SignInResult.Failed;
}
}
?? Configuration Models
public class CreateUserRequest
{
public string Email { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Department { get; set; }
public string JobTitle { get; set; }
public bool RequireEmailConfirmation { get; set; } = true;
public List<string> Roles { get; set; } = new();
}
public class UpdateUserRequest
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Department { get; set; }
public string JobTitle { get; set; }
public string PhoneNumber { get; set; }
}
public class SignInRequest
{
public string Email { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
}
??? Architecture
The Identity system provides:
- Security: Comprehensive authentication and authorization
- Flexibility: Customizable user models and claims
- Scalability: Role-based and claims-based security
- Integration: Seamless EF Core and ASP.NET Core integration
- Extensibility: Support for external providers and custom features
????? Author
Frebin Francis
Fingent Technology Solutions Pvt Ltd
?? License
Copyright � 2025 Fingent Technology Solutions Pvt Ltd
| 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. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Fingent-Shared-Core (>= 1.0.2)
- Microsoft.AspNetCore.Identity (>= 2.1.39)
- Microsoft.AspNetCore.Identity.EntityFrameworkCore (>= 8.0.8)
- Microsoft.AspNetCore.Identity.UI (>= 8.0.8)
- Microsoft.Extensions.DependencyInjection (>= 8.0.0)
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.1 | 358 | 9/24/2025 |