Authentication Password
A secure password-based authentication module that integrates with the MasLazu.AspNet.Authentication.Core framework. This module provides password authentication functionality with BCrypt hashing, user registration, and login capabilities.
๐ฏ Purposeโ
The Authentication.Password module extends the core authentication system with password-based login functionality:
- User Registration - Account creation with password-based authentication
- Password Login - Secure authentication using BCrypt hashing
- Password Management - Change password functionality
- Email Verification - Optional email verification integration
- Clean Architecture - Follows framework patterns with clear separation of concerns
๐ฆ Package Structureโ
๐๏ธ Architecture Overviewโ
This module integrates with the existing Authentication.Core framework:
๐ Installationโ
# Core password authentication
dotnet add package MasLazu.AspNet.Authentication.Password
# Database layer
dotnet add package MasLazu.AspNet.Authentication.Password.EfCore
# API endpoints
dotnet add package MasLazu.AspNet.Authentication.Password.Endpoint
# Abstractions (for DI)
dotnet add package MasLazu.AspNet.Authentication.Password.Abstraction
โ๏ธ Configurationโ
1. Service Registrationโ
// Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add Authentication.Core (required dependency)
builder.Services.AddAuthenticationCoreApplication(builder.Configuration);
// Add Password Authentication
builder.Services.AddAuthenticationPasswordApplication(builder.Configuration);
// Add EF Core for Password entities
builder.Services.AddAuthenticationPasswordEntityFrameworkCore();
// Add endpoints
builder.Services.AddFastEndpoints();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.UseFastEndpoints();
app.Run();
2. Configuration Settingsโ
{
"PasswordLoginMethod": {
"RequireVerification": true,
"PasswordValidation": {
"MinLength": 8,
"RequireUppercase": true,
"RequireLowercase": true,
"RequireDigit": true,
"RequireSpecialCharacter": false
}
}
}
๐ Core Featuresโ
1. User Registrationโ
public record PasswordRegisterRequest(
string Name,
string Username,
string Email,
string Password
);
// API: POST /auth/register
var request = new PasswordRegisterRequest(
Name: "John Doe",
Username: "johndoe",
Email: "john.doe@example.com",
Password: "SecurePass123!"
);
2. User Loginโ
public record PasswordLoginRequest(
string Identifier, // Email or Username
string Password
);
// API: POST /auth/login
var loginRequest = new PasswordLoginRequest(
Identifier: "john.doe@example.com", // or "johndoe"
Password: "SecurePass123!"
);
3. Password Changeโ
public record ChangePasswordRequest(
string CurrentPassword,
string NewPassword
);
// API: POST /auth/change-password (requires authentication)
var changeRequest = new ChangePasswordRequest(
CurrentPassword: "OldPass123!",
NewPassword: "NewSecurePass456!"
);
๐ก๏ธ Security Implementationโ
1. BCrypt Password Hashingโ
public static class PasswordHasher
{
private const int WorkFactor = 12; // 2^12 = 4096 iterations
public static string HashPassword(string password)
{
return BCrypt.Net.BCrypt.HashPassword(password, WorkFactor);
}
public static bool VerifyPassword(string hashedPassword, string providedPassword)
{
return BCrypt.Net.BCrypt.Verify(providedPassword, hashedPassword);
}
}
2. Password Validation Configurationโ
public class PasswordValidationConfiguration
{
public int MinLength { get; set; } = 8;
public bool RequireUppercase { get; set; } = true;
public bool RequireLowercase { get; set; } = true;
public bool RequireDigit { get; set; } = true;
public bool RequireSpecialCharacter { get; set; } = false;
}
๐ Database Schemaโ
UserPasswordLogin Entityโ
public class UserPasswordLogin : BaseEntity
{
public Guid UserId { get; set; }
public Guid UserLoginMethodId { get; set; }
public bool IsVerified { get; set; }
public string PasswordHash { get; set; } = string.Empty;
public DateTime? LastLoginDate { get; set; }
}
Entity Configurationโ
public class UserPasswordLoginConfiguration : IEntityTypeConfiguration<UserPasswordLogin>
{
public void Configure(EntityTypeBuilder<UserPasswordLogin> builder)
{
builder.HasKey(upl => upl.Id);
builder.Property(upl => upl.UserLoginMethodId)
.IsRequired();
builder.Property(upl => upl.PasswordHash)
.IsRequired()
.HasMaxLength(500);
builder.HasIndex(upl => upl.UserLoginMethodId)
.IsUnique();
}
}
๐ API Endpointsโ
All endpoints are grouped under /auth
prefix:
Method | Endpoint | Description | Request | Authentication |
---|---|---|---|---|
POST | /auth/register | Register new user | PasswordRegisterRequest | None |
POST | /auth/login | User login | PasswordLoginRequest | None |
POST | /auth/change-password | Change password | ChangePasswordRequest | Required |
Registration Flowโ
// 1. Register user
var registerResponse = await httpClient.PostAsJsonAsync("/auth/register", new PasswordRegisterRequest(
Name: "John Doe",
Username: "johndoe",
Email: "john@example.com",
Password: "SecurePass123!"
));
// 2. Email verification sent automatically (if configured)
// 3. User can login after verification (if required)
Login Flowโ
// Login with email or username
var loginResponse = await httpClient.PostAsJsonAsync("/auth/login", new PasswordLoginRequest(
Identifier: "john@example.com", // or "johndoe"
Password: "SecurePass123!"
));
var loginResult = await loginResponse.Content.ReadFromJsonAsync<PasswordLoginResponse>();
// Returns JWT tokens from Authentication.Core
๐ง Service Implementationโ
Core Service Interfaceโ
public interface IUserPasswordLoginService : ICrudService<UserPasswordLoginDto, CreateUserPasswordLoginRequest, UpdateUserPasswordLoginRequest>
{
Task<PasswordLoginResponse> LoginAsync(PasswordLoginRequest request, CancellationToken ct);
Task RegisterAsync(PasswordRegisterRequest request, CancellationToken ct);
Task ChangePasswordAsync(Guid userId, ChangePasswordRequest request, CancellationToken ct);
}
Registration Processโ
The service integrates with multiple systems:
- User Creation - Uses
IUserService
from Authentication.Core - Login Method - Creates entry in
IUserLoginMethodService
- Password Storage - Stores BCrypt hash in
UserPasswordLogin
- Email Verification - Triggers verification email if enabled
Login Validationโ
public async Task<PasswordLoginResponse> LoginAsync(PasswordLoginRequest request, CancellationToken ct)
{
// 1. Find user by email or username
UserDto user = await _userService.GetByUsernameOrEmailAsync(request.Identifier, ct);
// 2. Get password login record
UserPasswordLogin? userPasswordLogin = await ReadRepository.FirstOrDefaultAsync(upl => upl.UserId == user.Id, ct);
// 3. Verify password with BCrypt
if (!PasswordHasher.VerifyPassword(userPasswordLogin.PasswordHash, request.Password))
throw new UnauthorizedException("Invalid username/email or password.");
// 4. Check verification status
if (_passwordConfig.RequireVerification && !userPasswordLogin.IsVerified)
throw new UnauthorizedException("Account not verified.");
// 5. Generate JWT tokens via Authentication.Core
return (await _authService.LoginAsync(userPasswordLogin.UserLoginMethodId, ct)).Adapt<PasswordLoginResponse>();
}
๐งช Testing Examplesโ
Integration Test Setupโ
public class PasswordAuthenticationTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly HttpClient _client;
public PasswordAuthenticationTests(WebApplicationFactory<Program> factory)
{
_client = factory.CreateClient();
}
[Fact]
public async Task Register_ValidRequest_ReturnsSuccess()
{
var request = new PasswordRegisterRequest(
Name: "Test User",
Username: "testuser",
Email: "test@example.com",
Password: "TestPass123!"
);
var response = await _client.PostAsJsonAsync("/auth/register", request);
response.StatusCode.Should().Be(HttpStatusCode.OK);
}
[Fact]
public async Task Login_ValidCredentials_ReturnsTokens()
{
// Arrange: First register a user
await RegisterTestUser();
// Act: Login
var loginRequest = new PasswordLoginRequest("test@example.com", "TestPass123!");
var response = await _client.PostAsJsonAsync("/auth/login", loginRequest);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var loginResponse = await response.Content.ReadFromJsonAsync<PasswordLoginResponse>();
loginResponse.AccessToken.Should().NotBeNullOrEmpty();
}
}
๐ Project Structureโ
Based on actual implementation:
MasLazu.AspNet.Authentication.Password/
โโโ src/
โ โโโ MasLazu.AspNet.Authentication.Password.Abstraction/
โ โ โโโ Interfaces/
โ โ โ โโโ IUserPasswordLoginService.cs
โ โ โโโ Models/
โ โ โโโ PasswordRegisterRequest.cs
โ โ โโโ PasswordLoginRequest.cs
โ โ โโโ ChangePasswordRequest.cs
โ โ โโโ UserPasswordLoginDto.cs
โ โ
โ โโโ MasLazu.AspNet.Authentication.Password.Domain/
โ โ โโโ Entities/
โ โ โโโ UserPasswordLogin.cs
โ โ
โ โโโ MasLazu.AspNet.Authentication.Password/
โ โ โโโ Services/
โ โ โ โโโ UserPasswordLoginService.cs
โ โ โโโ Utils/
โ โ โ โโโ PasswordHasher.cs
โ โ โโโ Configurations/
โ โ โ โโโ PasswordLoginMethodConfiguration.cs
โ โ โโโ Extensions/
โ โ โโโ AuthenticationPasswordApplicationExtension.cs
โ โ
โ โโโ MasLazu.AspNet.Authentication.Password.EfCore/
โ โ โโโ Configurations/
โ โ โ โโโ UserPasswordLoginConfiguration.cs
โ โ โโโ Extensions/
โ โ โโโ ServiceCollectionExtensions.cs
โ โ
โ โโโ MasLazu.AspNet.Authentication.Password.Endpoint/
โ โโโ Endpoints/
โ โ โโโ RegisterEndpoint.cs
โ โ โโโ LoginEndpoint.cs
โ โ โโโ ChangePasswordEndpoint.cs
โ โโโ EndpointGroups/
โ โโโ AuthEndpointGroup.cs
โ
โโโ MasLazu.AspNet.Authentication.Password.sln
๐ Dependenciesโ
Required Framework Componentsโ
MasLazu.AspNet.Authentication.Core.Abstraction
- Core authentication servicesMasLazu.AspNet.Framework.Application
- Base application layerMasLazu.AspNet.Verification.Abstraction
- Email verification (optional)
External Packagesโ
BCrypt.Net-Next
- Password hashingFastEndpoints
- API endpointsEntity Framework Core
- Data access
โ Best Practicesโ
โ Security Do'sโ
- Use BCrypt with work factor 12 for password hashing
- Integrate with verification for email confirmation
- Leverage Authentication.Core for JWT token management
- Validate all inputs with FluentValidation
- Use records for immutable request/response models
โ Security Don'tsโ
- Don't store plain passwords - always use BCrypt hash
- Don't skip verification when security is critical
- Don't bypass the core auth system - use provided services
- Don't log sensitive data - exclude passwords from logs
๐ฏ Integration Pointsโ
With Authentication.Coreโ
// Password module uses core services for:
// - User management (IUserService)
// - JWT tokens (IAuthService)
// - Login methods (IUserLoginMethodService)
With Verification Moduleโ
// Email verification integration:
await _userService.SendEmailVerificationAsync(userDto.Email!, ct);
With Frameworkโ
// Extends framework base classes:
// - CrudService for standard operations
// - BaseEntity for domain entities
// - BaseEndpoint for API endpoints
๐ฏ Next Stepsโ
- Authentication.Core - Core JWT authentication and user management
- Verification Module - Email verification integration
- Framework Overview - Understanding the base framework
๐ Related Documentationโ
- Authentication.Core Module - Core authentication system
- Verification Module - Email verification workflows
- Framework Application Layer - Base service patterns
- Framework Domain Layer - Entity base classes