This new documentation file provides comprehensive instructions on configuring login credentials, generating password hashes, and managing user roles for both development and production environments. It includes best practices for security and troubleshooting tips to enhance user experience and system integrity.
14 KiB
Authentication Setup Guide
This guide explains how to configure login credentials for the TSA Chapter Organizer application. The application uses BCrypt password hashing and supports multiple authentication methods depending on your environment.
Table of Contents
- Overview
- Available Roles
- Generating Password Hashes
- Development Setup
- Production Setup
- Managing Users
- Security Best Practices
- Troubleshooting
Overview
The TSA Chapter Organizer uses cookie-based authentication with BCrypt password hashing. User credentials are stored securely and never in plain text. The authentication system supports:
- BCrypt password hashing (work factor 11)
- Case-insensitive email matching
- Role-based access control
- Rate limiting (5 failed attempts result in 15-minute lockout)
- Session management (20 minutes default, 30 days with "Remember Me")
Available Roles
The application supports two user roles:
- Administrator - Full access to all features
- Advisor - Standard user access
Roles are defined in WebApp/Authentication/AuthRoles.cs and can be customized if needed.
Generating Password Hashes
Before setting up authentication, you need to generate BCrypt hashes for your passwords. The application provides a development endpoint for this purpose.
Method 1: Development Endpoint (Recommended)
- Start the application in Development mode
- Navigate to:
https://localhost:<port>/dev/hash-password?password=YourPassword - Copy the
hashvalue from the JSON response
Example:
https://localhost:5001/dev/hash-password?password=MySecurePass123
Response:
{
"password": "MySecurePass123",
"hash": "$2a$11$xyz123...",
"message": "Copy the hash value to your User Secrets configuration"
}
Method 2: Programmatic (for automation)
You can also generate hashes programmatically using the PasswordHashGenerator class:
using WebApp.Authentication;
var hash = PasswordHashGenerator.GenerateHash("YourPassword");
Development Setup
For local development, the application uses .NET User Secrets to store authentication credentials securely.
Prerequisites
- .NET SDK installed
- User Secrets ID configured in
WebApp.csproj(already configured:73972335-ec46-4ad6-a959-8ebe0b06147d)
Steps
-
Generate password hashes using the development endpoint (see above)
-
Configure User Secrets using the .NET CLI:
cd WebApp # Set authentication configuration dotnet user-secrets set "Authentication:Users:0:Email" "admin@example.com" dotnet user-secrets set "Authentication:Users:0:PasswordHash" "$2a$11$your_hash_here" dotnet user-secrets set "Authentication:Users:0:Role" "Administrator" dotnet user-secrets set "Authentication:Users:0:DisplayName" "Administrator" # Add additional users (increment the index) dotnet user-secrets set "Authentication:Users:1:Email" "advisor@example.com" dotnet user-secrets set "Authentication:Users:1:PasswordHash" "$2a$11$your_hash_here" dotnet user-secrets set "Authentication:Users:1:Role" "Advisor" dotnet user-secrets set "Authentication:Users:1:DisplayName" "Chapter Advisor" -
Verify your configuration:
dotnet user-secrets list -
Run the application:
dotnet run -
Login at
https://localhost:<port>/login
Example: Complete Development Setup
# 1. Navigate to WebApp directory
cd WebApp
# 2. Generate hash (via browser or curl)
# Visit: https://localhost:5001/dev/hash-password?password=admin123
# 3. Configure admin user
dotnet user-secrets set "Authentication:Users:0:Email" "admin@myschool.edu"
dotnet user-secrets set "Authentication:Users:0:PasswordHash" "$2a$11$REPLACE_WITH_GENERATED_HASH"
dotnet user-secrets set "Authentication:Users:0:Role" "Administrator"
dotnet user-secrets set "Authentication:Users:0:DisplayName" "TSA Admin"
# 4. Configure advisor user (optional)
dotnet user-secrets set "Authentication:Users:1:Email" "advisor@myschool.edu"
dotnet user-secrets set "Authentication:Users:1:PasswordHash" "$2a$11$REPLACE_WITH_GENERATED_HASH"
dotnet user-secrets set "Authentication:Users:1:Role" "Advisor"
dotnet user-secrets set "Authentication:Users:1:DisplayName" "Chapter Advisor"
# 5. Verify
dotnet user-secrets list
# 6. Run
dotnet run
Production Setup
For production environments (Docker, deployed servers), you have two options for configuring authentication credentials.
Option 1: Volume-Mounted JSON File (Recommended)
This approach allows you to edit credentials without rebuilding the container.
Steps
-
Generate Password Hashes (on your development machine):
- Use the development endpoint or programmatic method
-
Create
auth-secrets.jsonon your Docker host:cp auth-secrets.example.json auth-secrets.json -
Edit
auth-secrets.jsonand replace the placeholder hashes:{ "Authentication": { "Users": [ { "Email": "admin@example.com", "PasswordHash": "$2a$11$actual.hash.here", "Role": "Administrator", "DisplayName": "Administrator" }, { "Email": "advisor@example.com", "PasswordHash": "$2a$11$actual.hash.here", "Role": "Advisor", "DisplayName": "Chapter Advisor" } ] } } -
Set proper file permissions:
chmod 600 auth-secrets.json chown root:root auth-secrets.json # Adjust user/group as needed -
Configure Docker Compose (see
docker-compose.example.yml):volumes: - ./auth-secrets.json:/app/Data/auth-secrets.json:ro -
Update credentials: Simply edit
auth-secrets.jsonon the host and restart the container:docker-compose restart webapp
Security Note: Never commit auth-secrets.json to version control. It should be in .gitignore.
Option 2: Environment Variables
This approach is useful for container orchestration platforms (Kubernetes, Docker Swarm, etc.).
Docker Compose Example
environment:
- TSA_Authentication__Users__0__Email=admin@example.com
- TSA_Authentication__Users__0__PasswordHash=$2a$11$hash...
- TSA_Authentication__Users__0__Role=Administrator
- TSA_Authentication__Users__0__DisplayName=Administrator
- TSA_Authentication__Users__1__Email=advisor@example.com
- TSA_Authentication__Users__1__PasswordHash=$2a$11$hash...
- TSA_Authentication__Users__1__Role=Advisor
- TSA_Authentication__Users__1__DisplayName=Chapter Advisor
Docker Run Example
docker run -d \
-p 8080:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e TSA_Authentication__Users__0__Email=admin@example.com \
-e TSA_Authentication__Users__0__PasswordHash='$2a$11$hash...' \
-e TSA_Authentication__Users__0__Role=Administrator \
-e TSA_Authentication__Users__0__DisplayName=Administrator \
tsa-chapter-organizer:latest
Kubernetes Secret Example
apiVersion: v1
kind: Secret
metadata:
name: tsa-auth-secrets
type: Opaque
stringData:
TSA_Authentication__Users__0__Email: "admin@example.com"
TSA_Authentication__Users__0__PasswordHash: "$2a$11$hash..."
TSA_Authentication__Users__0__Role: "Administrator"
TSA_Authentication__Users__0__DisplayName: "Administrator"
Note: Environment variable names use double underscores (__) to represent nested configuration paths, with the TSA_ prefix.
Managing Users
Adding a New User
Development (User Secrets)
# Find the next available index (check existing users first)
dotnet user-secrets list | grep "Authentication:Users"
# Add new user (replace N with the next index)
dotnet user-secrets set "Authentication:Users:N:Email" "newuser@example.com"
dotnet user-secrets set "Authentication:Users:N:PasswordHash" "$2a$11$hash..."
dotnet user-secrets set "Authentication:Users:N:Role" "Advisor"
dotnet user-secrets set "Authentication:Users:N:DisplayName" "New User Name"
Production (JSON File)
- Edit
auth-secrets.jsonon the host - Add a new entry to the
Usersarray:{ "Email": "newuser@example.com", "PasswordHash": "$2a$11$hash...", "Role": "Advisor", "DisplayName": "New User Name" } - Restart the container:
docker-compose restart webapp
Production (Environment Variables)
Add new environment variables with the next index number and recreate the container.
Changing a Password
-
Generate a new password hash:
- Development: Use
/dev/hash-passwordendpoint - Production: Generate on local dev machine
- Development: Use
-
Update the configuration:
- Development:
dotnet user-secrets set "Authentication:Users:N:PasswordHash" "$2a$11$new_hash" - Production (JSON): Edit
auth-secrets.jsonand update thePasswordHashvalue - Production (Env Vars): Update the environment variable
- Development:
-
Restart the application:
- Development: Restart the app (automatic on file change for User Secrets)
- Production:
docker-compose restart webapp
Removing a User
-
Remove from configuration:
- Development: Remove the User Secrets entries for that user index
- Production (JSON): Remove the user entry from
auth-secrets.json - Production (Env Vars): Remove the environment variables
-
Restart the application
Note: When removing users from JSON or environment variables, you may need to renumber remaining users' indices, or leave gaps (both approaches work).
Security Best Practices
-
Strong Passwords: Use strong, unique passwords for each user. Consider using a password manager.
-
File Permissions (Production):
chmod 600 auth-secrets.json chown root:root auth-secrets.json -
Never Commit Secrets: Ensure the following are in
.gitignore:auth-secrets.jsondocker-compose.yml(if it contains secrets)- User Secrets files (automatically ignored by .NET)
-
Use HTTPS in Production: Always configure SSL/TLS certificates for production deployments.
-
Backup Credentials Securely: Store encrypted backups of
auth-secrets.jsonin a secure location. -
Password Rotation: Periodically regenerate password hashes and update credentials.
-
Monitor Access: Review application logs for failed login attempts:
docker-compose logs webapp | grep "Failed login" -
Limit Access: Only grant Administrator role to trusted users. Use Advisor role for general access.
-
Rate Limiting: The application automatically enforces rate limiting (5 failed attempts = 15 minute lockout). Monitor logs for suspicious activity.
Troubleshooting
Can't Login
-
Verify configuration is loaded:
- Development: Check User Secrets are configured:
dotnet user-secrets list - Production: Check if file is mounted:
docker exec tsa-app ls -la /app/Data/auth-secrets.json
- Development: Check User Secrets are configured:
-
Check JSON syntax (if using JSON file):
cat auth-secrets.json | jq .Or validate online using a JSON validator.
-
Verify password hash: Ensure the hash was copied completely (BCrypt hashes are ~60 characters)
-
Check application logs:
docker-compose logs webapp | grep -i "authentication\|login" -
Verify email is correct: Email matching is case-insensitive, but ensure it matches exactly what you configured.
Rate Limited / Locked Out
If you see "Too many failed attempts" error:
- Wait 15 minutes for the lockout to expire
- Or restart the container (resets rate limit tracking):
docker-compose restart webapp
Forgot Admin Password
- Generate a new password hash using the dev endpoint (on local dev machine)
- Update
auth-secrets.json(production) or User Secrets (development) - Restart the application
No Users Configured Error
If you see "Authentication system not configured" or "No users configured":
-
Development: Verify User Secrets are set:
dotnet user-secrets list | grep Authentication -
Production: Check that
auth-secrets.jsonexists and is properly mounted:docker exec tsa-app cat /app/Data/auth-secrets.json -
Verify the JSON structure matches the expected format (see
auth-secrets.example.json)
Container Won't Start
Check logs for configuration errors:
docker-compose logs webapp
Common issues:
- JSON syntax error in
auth-secrets.json - File permissions preventing file access
- Missing required configuration values
Example: Complete Production Setup
# 1. Generate password hash locally (in development)
# Visit: https://localhost:5001/dev/hash-password?password=SecurePass123
# 2. Create secrets file
cat > auth-secrets.json <<EOF
{
"Authentication": {
"Users": [
{
"Email": "admin@myschool.edu",
"PasswordHash": "$2a$11$paste_generated_hash_here",
"Role": "Administrator",
"DisplayName": "TSA Admin"
},
{
"Email": "advisor@myschool.edu",
"PasswordHash": "$2a$11$paste_generated_hash_here",
"Role": "Advisor",
"DisplayName": "Chapter Advisor"
}
]
}
}
EOF
# 3. Set permissions
chmod 600 auth-secrets.json
# 4. Create docker-compose.yml (copy and customize from example)
cp docker-compose.example.yml docker-compose.yml
# 5. Ensure volume mount is configured in docker-compose.yml:
# volumes:
# - ./auth-secrets.json:/app/Data/auth-secrets.json:ro
# 6. Start the application
docker-compose up -d
# 7. Check it's running
docker-compose ps
curl http://localhost:8080
# 8. Login
# Navigate to http://localhost:8080/login
# Use configured credentials
Additional Resources
- See
DEPLOYMENT.mdfor Docker deployment details - See
auth-secrets.example.jsonfor the expected JSON structure - See
docker-compose.example.ymlfor Docker Compose configuration examples - Authentication implementation:
WebApp/Authentication/