Overview
RealtimeChat uses ASP.NET Core Identity with Entity Framework Core for user management and authentication. This page covers the Identity configuration, database schema, and user model details.ASP.NET Identity provides a complete membership system with built-in support for password hashing, user lockout, two-factor authentication, and more.
ApplicationUser Model
TheApplicationUser class extends Identity’s IdentityUser to add custom properties specific to RealtimeChat.
Source Code
Infrastructure/RealtimeChat.Infrastructure.DB/Entities/ApplicationUser.cs
Properties Reference
From IdentityUser (Base Class)
Primary key - Unique identifier (GUID as string)
Username - Typically set to the user’s email address
Uppercase username for case-insensitive lookups
User’s email address
Uppercase email for case-insensitive lookups
Indicates if the email address has been verified
Hashed password using PBKDF2 algorithm (never plain text)
Random value that changes when credentials change (used to invalidate cookies)
Token for optimistic concurrency control
Optional phone number
Indicates if phone number has been verified
Whether two-factor authentication is enabled
UTC datetime when lockout ends (null if not locked out)
Whether user can be locked out
Number of failed login attempts (for lockout)
Custom Properties
User’s first name (nullable) - Populated from OAuth or registration
User’s last name (nullable) - Populated from OAuth or registration
Navigation property for all messages sent by the user
Navigation property for all chat rooms the user participates in
Identity Configuration
Database Configuration
TheIdentityConfiguration class configures the Entity Framework Core table names for Identity entities:
Infrastructure/RealtimeChat.Infrastructure.DB/Configurations/IdentityConfiguration.cs
By default, Identity uses table names like “AspNetUsers”. This configuration customizes them to follow snake_case naming conventions.
Service Registration
Identity is registered in the dependency injection container viaAuthExtensions:
Applications/RealtimeChat.API/Extensions/AuthExtensions.cs
AddIdentityApiEndpoints<ApplicationUser>()- Registers Identity services with API endpoint supportAddEntityFrameworkStores<RealtimeChatDbContext>()- Configures EF Core as the storage providerAddApiEndpoints()- Maps RESTful authentication endpoints
Database Schema
Identity Tables
ASP.NET Identity creates the following tables in your PostgreSQL database:users (ApplicationUser)
| Column | Type | Description |
|---|---|---|
| id | string (PK) | Unique user identifier (GUID) |
| user_name | string | Username (typically email) |
| normalized_user_name | string | Uppercase username for lookups |
| string | Email address | |
| normalized_email | string | Uppercase email for lookups |
| email_confirmed | bool | Email verification status |
| password_hash | string | Hashed password (PBKDF2) |
| security_stamp | string | Credential change token |
| concurrency_stamp | string | Concurrency token |
| phone_number | string | Optional phone number |
| phone_number_confirmed | bool | Phone verification status |
| two_factor_enabled | bool | 2FA enabled status |
| lockout_end | datetimeoffset | Lockout expiration |
| lockout_enabled | bool | Can user be locked out |
| access_failed_count | int | Failed login attempts |
| first_name | string | Custom: User’s first name |
| last_name | string | Custom: User’s last name |
user_logins (External OAuth Logins)
| Column | Type | Description |
|---|---|---|
| login_provider | string (PK) | OAuth provider (e.g., “Google”) |
| provider_key | string (PK) | Provider’s user identifier |
| provider_display_name | string | Display name for provider |
| user_id | string (FK) | Foreign key to users table |
This table links external OAuth providers to user accounts, allowing users to sign in with Google.
roles
| Column | Type | Description |
|---|---|---|
| id | string (PK) | Unique role identifier |
| name | string | Role name (e.g., “Admin”) |
| normalized_name | string | Uppercase name for lookups |
| concurrency_stamp | string | Concurrency token |
user_roles (Many-to-Many)
| Column | Type | Description |
|---|---|---|
| user_id | string (PK, FK) | Foreign key to users |
| role_id | string (PK, FK) | Foreign key to roles |
user_claims
| Column | Type | Description |
|---|---|---|
| id | int (PK) | Unique claim identifier |
| user_id | string (FK) | Foreign key to users |
| claim_type | string | Claim type (e.g., “email”) |
| claim_value | string | Claim value |
role_claims
| Column | Type | Description |
|---|---|---|
| id | int (PK) | Unique claim identifier |
| role_id | string (FK) | Foreign key to roles |
| claim_type | string | Claim type |
| claim_value | string | Claim value |
user_tokens
| Column | Type | Description |
|---|---|---|
| user_id | string (PK, FK) | Foreign key to users |
| login_provider | string (PK) | Token provider |
| name | string (PK) | Token name |
| value | string | Token value |
ER Diagram
User Claims
Claims are key-value pairs that represent user attributes. They are used for authorization and can be accessed in your application.Standard Claims
When a user logs in, the following claims are automatically added:Custom Claims from OAuth
When authenticating via Google OAuth, additional claims are extracted:Applications/RealtimeChat.API/Services/ExternalAuthService.cs
Accessing Claims in Code
In your API endpoints, access user claims viaHttpContext.User:
UserManager and SignInManager
ASP.NET Identity provides two key services for user management:UserManager<ApplicationUser>
Manages user operations:SignInManager<ApplicationUser>
Manages sign-in operations:Usage in ExternalAuthService
See how these services are used together:Applications/RealtimeChat.API/Services/ExternalAuthService.cs
Database Migrations
To create or update the Identity database schema:Create Migration
Apply Migration
Connection String
Configure your PostgreSQL connection string inappsettings.json:
Applications/RealtimeChat.API/appsettings.json
Password Hashing
ASP.NET Identity uses PBKDF2 (Password-Based Key Derivation Function 2) for password hashing:- Algorithm: PBKDF2 with HMAC-SHA256
- Iterations: 10,000+ (configurable)
- Salt: Unique random salt per password
- Output: Base64-encoded hash including algorithm metadata
Example Password Hash
AQ- Version 1 of the hash formatAAAAIA- PBKDF2-HMAC-SHA256AYag- Iteration count- Remaining bytes - Salt + hash
You never need to implement password hashing manually. ASP.NET Identity handles this automatically when you call
userManager.CreateAsync(user, password).Security Considerations
Database Security
- Use parameterized queries - EF Core does this automatically
- Encrypt connection strings - Use Azure Key Vault or environment variables
- Restrict database access - Use least-privilege database users
- Enable SSL/TLS - For database connections in production
Password Policy
Configure password requirements inAddIdentity:
User Lockout
Protect against brute force attacks:Security Stamp
TheSecurityStamp invalidates all existing authentication cookies when:
- Password is changed
- External login is added/removed
- Two-factor authentication is enabled/disabled
Next Steps
Authentication Overview
Learn about the overall authentication system
OAuth Setup
Configure Google OAuth authentication