343 lines
9.9 KiB
Markdown
343 lines
9.9 KiB
Markdown
# Two-Factor Authentication (2FA) Implementation
|
|
|
|
## Overview
|
|
|
|
This document describes the two-factor authentication (2FA) implementation for the DBOIS application. The system supports two methods:
|
|
|
|
1. **Email OTP**: Users receive a one-time password via email
|
|
2. **Google Authenticator**: Users use an authenticator app (Google Authenticator, Authy, etc.)
|
|
|
|
## Installation Steps
|
|
|
|
### 1. Database Migration
|
|
|
|
Run the SQL migration to add the necessary database tables and columns:
|
|
|
|
```bash
|
|
mysql -u your_username -p your_database < application/migrations/001_add_two_factor_authentication.sql
|
|
```
|
|
|
|
Or manually execute the SQL:
|
|
|
|
```sql
|
|
-- Add 2FA columns to users table
|
|
ALTER TABLE `users`
|
|
ADD COLUMN `two_factor_enabled` VARCHAR(1) NOT NULL DEFAULT 'F' COMMENT 'T=enabled, F=disabled' AFTER `role`,
|
|
ADD COLUMN `two_factor_method` VARCHAR(20) NULL DEFAULT NULL COMMENT 'email or authenticator' AFTER `two_factor_enabled`,
|
|
ADD COLUMN `two_factor_secret` VARCHAR(255) NULL DEFAULT NULL COMMENT 'TOTP secret for Google Authenticator' AFTER `two_factor_method`;
|
|
|
|
-- Create table for email OTP codes
|
|
CREATE TABLE `user_otp_codes` (
|
|
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`user_id` INT(11) UNSIGNED NOT NULL,
|
|
`otp_code` VARCHAR(6) NOT NULL,
|
|
`expires_at` TIMESTAMP NOT NULL,
|
|
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`used` VARCHAR(1) NOT NULL DEFAULT 'F' COMMENT 'T=used, F=not used',
|
|
PRIMARY KEY (`id`),
|
|
KEY `idx_user_id` (`user_id`),
|
|
KEY `idx_expires_at` (`expires_at`),
|
|
CONSTRAINT `fk_otp_user` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
|
|
|
-- Create index for faster lookups
|
|
CREATE INDEX `idx_users_two_factor` ON `users` (`two_factor_enabled`, `two_factor_method`);
|
|
```
|
|
|
|
### 2. File Structure
|
|
|
|
The following files have been created/modified:
|
|
|
|
#### New Files:
|
|
- `application/libraries/TwoFactorAuth.php` - TOTP library for Google Authenticator
|
|
- `application/models/beheer/UserOtp_model.php` - Model for managing email OTP codes
|
|
- `application/libraries/beheer/twofactor/SendOtpEmail.php` - Library for sending OTP emails
|
|
- `application/controllers/beheer/TwoFactorController.php` - Controller for 2FA settings
|
|
- `application/views/pages/beheer/twofactor/settings_view.php` - 2FA settings page
|
|
- `application/views/pages/login/verify2fa_view.php` - 2FA verification page during login
|
|
- `application/views/emails/twofactor_otp_email.php` - Email template for OTP codes
|
|
- `application/migrations/001_add_two_factor_authentication.sql` - Database migration
|
|
|
|
#### Modified Files:
|
|
- `application/controllers/Login.php` - Added 2FA verification logic
|
|
- `public/js/lib/modules/login/loginModule.js` - Updated to handle 2FA redirect
|
|
|
|
## Usage
|
|
|
|
### For End Users
|
|
|
|
#### Enabling 2FA
|
|
|
|
1. Log in to the application
|
|
2. Navigate to: `/beheer/TwoFactorController`
|
|
3. Select a 2FA method:
|
|
- **Email**: Receive codes via email
|
|
- **Google Authenticator**: Use an authenticator app
|
|
|
|
#### Email Method Setup
|
|
|
|
1. Click on "E-mail" card
|
|
2. Click "2FA Inschakelen" (Enable 2FA)
|
|
3. Done! You'll receive OTP codes via email on each login
|
|
|
|
#### Google Authenticator Method Setup
|
|
|
|
1. Click on "Google Authenticator" card
|
|
2. Click "2FA Inschakelen" (Enable 2FA)
|
|
3. A QR code will appear
|
|
4. Scan the QR code with your authenticator app (Google Authenticator, Authy, etc.)
|
|
5. Enter the 6-digit code from your app to verify
|
|
6. Click "Verifiëren" (Verify)
|
|
7. Done! You'll use the authenticator app on each login
|
|
|
|
#### Changing 2FA Method
|
|
|
|
1. Go to 2FA settings page
|
|
2. Select a different method
|
|
3. Click "Methode Wijzigen" (Change Method)
|
|
4. If switching to authenticator, scan the new QR code and verify
|
|
|
|
#### Disabling 2FA
|
|
|
|
1. Go to 2FA settings page
|
|
2. Click "2FA Uitschakelen" (Disable 2FA)
|
|
3. Confirm the action
|
|
|
|
#### Login with 2FA
|
|
|
|
1. Enter username and password as usual
|
|
2. If 2FA is enabled, you'll be redirected to a verification page
|
|
3. For email method:
|
|
- Check your email for the 6-digit code
|
|
- Enter the code on the verification page
|
|
- Click "Verifiëren" (Verify)
|
|
- Can resend code if needed
|
|
4. For authenticator method:
|
|
- Open your authenticator app
|
|
- Enter the current 6-digit code
|
|
- Click "Verifiëren" (Verify)
|
|
|
|
### For Administrators
|
|
|
|
#### Setting up Email Configuration
|
|
|
|
Ensure your CodeIgniter email configuration is properly set up in `application/config/email.php`. The system sends OTP emails from `noreply@dbois.nl`.
|
|
|
|
#### OTP Code Settings
|
|
|
|
OTP codes:
|
|
- Are 6 digits long
|
|
- Are valid for 10 minutes
|
|
- Are automatically cleaned up after use or expiration
|
|
|
|
#### Google Authenticator Settings
|
|
|
|
- TOTP codes are generated using RFC 6238 standard
|
|
- Codes are 6 digits long
|
|
- Time step is 30 seconds
|
|
- Verification allows ±30 seconds time window for clock drift
|
|
|
|
#### Monitoring and Maintenance
|
|
|
|
**Clean up expired OTP codes:**
|
|
```php
|
|
$this->load->model('beheer/UserOtp_model');
|
|
$deletedCount = $this->UserOtp_model->cleanupExpiredOTPs();
|
|
```
|
|
|
|
**Check user's 2FA status:**
|
|
```php
|
|
$user = $this->User_model->get($userId);
|
|
if ($user->two_factor_enabled === 'T') {
|
|
// User has 2FA enabled
|
|
$method = $user->two_factor_method; // 'email' or 'authenticator'
|
|
}
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### 2FA Settings Management
|
|
|
|
#### Get 2FA Status
|
|
```
|
|
GET /beheer/TwoFactorController/status
|
|
Response: { enabled: boolean, method: string|null }
|
|
```
|
|
|
|
#### Enable 2FA
|
|
```
|
|
POST /beheer/TwoFactorController/enable
|
|
Data: { method: 'email'|'authenticator' }
|
|
Response: {
|
|
success: boolean,
|
|
message: string,
|
|
method: string,
|
|
secret?: string (if authenticator),
|
|
qrCodeUrl?: string (if authenticator)
|
|
}
|
|
```
|
|
|
|
#### Verify Authenticator Setup
|
|
```
|
|
POST /beheer/TwoFactorController/verifySetup
|
|
Data: { code: string (6 digits) }
|
|
Response: { success: boolean, message: string }
|
|
```
|
|
|
|
#### Disable 2FA
|
|
```
|
|
POST /beheer/TwoFactorController/disable
|
|
Response: { success: boolean, message: string }
|
|
```
|
|
|
|
#### Change 2FA Method
|
|
```
|
|
POST /beheer/TwoFactorController/changeMethod
|
|
Data: { method: 'email'|'authenticator' }
|
|
Response: {
|
|
success: boolean,
|
|
message: string,
|
|
method: string,
|
|
secret?: string (if authenticator),
|
|
qrCodeUrl?: string (if authenticator)
|
|
}
|
|
```
|
|
|
|
### Login Flow
|
|
|
|
#### Initial Login
|
|
```
|
|
POST /login
|
|
Data: { username: string, password: string }
|
|
Response (with 2FA): { result: '2FA-REQUIRED', method: string }
|
|
Response (without 2FA): boolean
|
|
```
|
|
|
|
#### Show 2FA Verification Page
|
|
```
|
|
GET /login/showVerify2fa
|
|
Displays verification page with temporary session
|
|
```
|
|
|
|
#### Verify 2FA Code
|
|
```
|
|
POST /login/verify2fa
|
|
Data: { code: string (6 digits) }
|
|
Response: { success: boolean, message: string }
|
|
```
|
|
|
|
#### Resend OTP (Email method only)
|
|
```
|
|
POST /login/resendOtp
|
|
Response: { success: boolean, message: string }
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **Session Management**: During 2FA verification, only a temporary session with user ID is created. Full session is created only after successful 2FA verification.
|
|
|
|
2. **OTP Expiration**: Email OTP codes expire after 10 minutes and are marked as used after verification to prevent replay attacks.
|
|
|
|
3. **Time-Based Codes**: Google Authenticator codes are time-based with a 30-second window, making them resistant to replay attacks.
|
|
|
|
4. **Rate Limiting**: Consider implementing rate limiting on:
|
|
- `/login/verify2fa` endpoint to prevent brute force
|
|
- `/login/resendOtp` endpoint to prevent email flooding
|
|
|
|
5. **HTTPS**: The system enforces HTTPS in production (already implemented in MY_Controller).
|
|
|
|
6. **QR Code Security**: QR codes contain sensitive TOTP secrets. They should only be displayed over HTTPS and users should be advised to never share them.
|
|
|
|
## Troubleshooting
|
|
|
|
### Email OTP Not Received
|
|
|
|
1. Check email configuration in `application/config/email.php`
|
|
2. Check spam/junk folders
|
|
3. Use "Code opnieuw verzenden" (Resend code) button
|
|
4. Check application logs for email send failures
|
|
|
|
### Authenticator Code Not Working
|
|
|
|
1. Ensure device time is synchronized (critical for TOTP)
|
|
2. Check if user scanned the correct QR code
|
|
3. Try codes within ±30 seconds window
|
|
4. Re-setup authenticator if issues persist
|
|
|
|
### Locked Out of Account
|
|
|
|
If a user loses access to their 2FA method:
|
|
|
|
1. Admin can directly disable 2FA in database:
|
|
```sql
|
|
UPDATE users
|
|
SET two_factor_enabled = 'F',
|
|
two_factor_method = NULL,
|
|
two_factor_secret = NULL
|
|
WHERE id = [user_id];
|
|
```
|
|
|
|
2. Admin should then securely verify user identity before re-enabling 2FA
|
|
|
|
### Session Issues
|
|
|
|
If users are stuck in 2FA verification:
|
|
|
|
1. Clear temporary session variables:
|
|
```php
|
|
$this->session->unset_userdata('pending_2fa_user_id');
|
|
$this->session->unset_userdata('pending_2fa_method');
|
|
```
|
|
|
|
2. User can click "Annuleren" (Cancel) to return to login page
|
|
|
|
## Testing
|
|
|
|
### Test Email Method
|
|
|
|
1. Enable 2FA with email method for test user
|
|
2. Log out
|
|
3. Log in with test user credentials
|
|
4. Verify OTP code received via email
|
|
5. Test "resend code" functionality
|
|
6. Test expired code (wait 10+ minutes)
|
|
7. Test invalid code
|
|
|
|
### Test Authenticator Method
|
|
|
|
1. Enable 2FA with authenticator method for test user
|
|
2. Scan QR code with Google Authenticator app
|
|
3. Verify setup code works
|
|
4. Log out
|
|
5. Log in with test user credentials
|
|
6. Verify authenticator code
|
|
7. Test with time-synced codes
|
|
8. Test invalid code
|
|
|
|
### Test Method Switching
|
|
|
|
1. Enable with one method
|
|
2. Switch to another method
|
|
3. Verify new method works
|
|
4. Disable 2FA
|
|
5. Re-enable with different method
|
|
|
|
## Future Enhancements
|
|
|
|
Possible improvements:
|
|
|
|
1. **Backup Codes**: Generate one-time backup codes for account recovery
|
|
2. **Remember Device**: Option to skip 2FA on trusted devices for X days
|
|
3. **SMS OTP**: Add SMS as a third 2FA method
|
|
4. **Admin Dashboard**: View 2FA adoption metrics
|
|
5. **Rate Limiting**: Implement built-in rate limiting for security
|
|
6. **Audit Logs**: Log 2FA events (enable, disable, failed attempts)
|
|
7. **Mandatory 2FA**: Require 2FA for specific user roles
|
|
|
|
## Support
|
|
|
|
For issues or questions, please contact the development team or refer to:
|
|
- CodeIgniter Documentation: https://codeigniter.com/userguide3/
|
|
- Google Authenticator: https://github.com/google/google-authenticator
|
|
- RFC 6238 (TOTP): https://tools.ietf.org/html/rfc6238
|