Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
430
docs/components/auth/configuration.md
Normal file
430
docs/components/auth/configuration.md
Normal file
@@ -0,0 +1,430 @@
|
||||
# Auth Module Configuration
|
||||
|
||||
**Konfiguration und Setup** für das Auth Module des Custom PHP Frameworks.
|
||||
|
||||
## Dependency Injection Setup
|
||||
|
||||
### Container Bindings
|
||||
|
||||
```php
|
||||
use App\Framework\Auth\PasswordHasher;
|
||||
use App\Framework\Auth\AuthenticationService;
|
||||
use App\Framework\Cryptography\KeyDerivationFunction;
|
||||
|
||||
// services.php oder Container Initialization
|
||||
$container->singleton(PasswordHasher::class, function(Container $container) {
|
||||
return new PasswordHasher(
|
||||
kdf: $container->get(KeyDerivationFunction::class),
|
||||
defaultAlgorithm: 'argon2id',
|
||||
defaultSecurityLevel: PasswordHasher::LEVEL_STANDARD
|
||||
);
|
||||
});
|
||||
|
||||
$container->singleton(AuthenticationService::class, function(Container $container) {
|
||||
return new AuthenticationService(
|
||||
passwordHasher: $container->get(PasswordHasher::class),
|
||||
sessionIdGenerator: $container->get(SessionIdGenerator::class),
|
||||
repository: $container->get(AuthenticationRepository::class),
|
||||
rateLimiter: $container->get(RateLimitService::class)
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
### Environment Configuration
|
||||
|
||||
```php
|
||||
// .env Konfiguration
|
||||
AUTH_SESSION_TIMEOUT=3600 # Session Timeout in Sekunden (1 Stunde)
|
||||
AUTH_REMEMBER_TOKEN_EXPIRY=2592000 # Remember Token Expiry (30 Tage)
|
||||
AUTH_MAX_LOGIN_ATTEMPTS=5 # Maximale Login-Versuche
|
||||
AUTH_LOCKOUT_DURATION=900 # Account Lockout Duration (15 Minuten)
|
||||
AUTH_RATE_LIMIT_WINDOW=300 # Rate Limit Window (5 Minuten)
|
||||
|
||||
# Password Hashing Configuration
|
||||
AUTH_DEFAULT_ALGORITHM=argon2id # Standard Hash-Algorithmus
|
||||
AUTH_DEFAULT_SECURITY_LEVEL=standard # low|standard|high
|
||||
AUTH_PASSWORD_MIN_LENGTH=8 # Minimale Passwort-Länge
|
||||
AUTH_PASSWORD_MAX_LENGTH=4096 # Maximale Passwort-Länge
|
||||
|
||||
# Session Security
|
||||
AUTH_SESSION_REGENERATE_ON_LOGIN=true # Session ID bei Login regenerieren
|
||||
AUTH_CHECK_IP_CONSISTENCY=false # IP-Konsistenz-Prüfung (optional)
|
||||
AUTH_REMEMBER_TOKEN_LENGTH=32 # Remember Token Länge (Bytes)
|
||||
```
|
||||
|
||||
### Typed Configuration Class
|
||||
|
||||
```php
|
||||
final readonly class AuthConfig
|
||||
{
|
||||
public function __construct(
|
||||
// Session Configuration
|
||||
public int $sessionTimeout = 3600,
|
||||
public int $rememberTokenExpiry = 2592000,
|
||||
public bool $sessionRegenerateOnLogin = true,
|
||||
public bool $checkIpConsistency = false,
|
||||
public int $rememberTokenLength = 32,
|
||||
|
||||
// Security Configuration
|
||||
public int $maxLoginAttempts = 5,
|
||||
public int $lockoutDuration = 900,
|
||||
public int $rateLimitWindow = 300,
|
||||
|
||||
// Password Configuration
|
||||
public string $defaultAlgorithm = 'argon2id',
|
||||
public string $defaultSecurityLevel = 'standard',
|
||||
public int $passwordMinLength = 8,
|
||||
public int $passwordMaxLength = 4096,
|
||||
|
||||
// Validation Configuration
|
||||
public bool $enforcePasswordComplexity = true,
|
||||
public bool $checkCommonPasswords = true,
|
||||
public bool $preventSequentialChars = true,
|
||||
public int $minPasswordScore = 50
|
||||
) {}
|
||||
|
||||
public static function fromEnvironment(Environment $env): self
|
||||
{
|
||||
return new self(
|
||||
sessionTimeout: $env->getInt(EnvKey::AUTH_SESSION_TIMEOUT, 3600),
|
||||
rememberTokenExpiry: $env->getInt(EnvKey::AUTH_REMEMBER_TOKEN_EXPIRY, 2592000),
|
||||
sessionRegenerateOnLogin: $env->getBool(EnvKey::AUTH_SESSION_REGENERATE_ON_LOGIN, true),
|
||||
checkIpConsistency: $env->getBool(EnvKey::AUTH_CHECK_IP_CONSISTENCY, false),
|
||||
rememberTokenLength: $env->getInt(EnvKey::AUTH_REMEMBER_TOKEN_LENGTH, 32),
|
||||
|
||||
maxLoginAttempts: $env->getInt(EnvKey::AUTH_MAX_LOGIN_ATTEMPTS, 5),
|
||||
lockoutDuration: $env->getInt(EnvKey::AUTH_LOCKOUT_DURATION, 900),
|
||||
rateLimitWindow: $env->getInt(EnvKey::AUTH_RATE_LIMIT_WINDOW, 300),
|
||||
|
||||
defaultAlgorithm: $env->get(EnvKey::AUTH_DEFAULT_ALGORITHM, 'argon2id'),
|
||||
defaultSecurityLevel: $env->get(EnvKey::AUTH_DEFAULT_SECURITY_LEVEL, 'standard'),
|
||||
passwordMinLength: $env->getInt(EnvKey::AUTH_PASSWORD_MIN_LENGTH, 8),
|
||||
passwordMaxLength: $env->getInt(EnvKey::AUTH_PASSWORD_MAX_LENGTH, 4096),
|
||||
|
||||
enforcePasswordComplexity: $env->getBool(EnvKey::AUTH_ENFORCE_PASSWORD_COMPLEXITY, true),
|
||||
checkCommonPasswords: $env->getBool(EnvKey::AUTH_CHECK_COMMON_PASSWORDS, true),
|
||||
preventSequentialChars: $env->getBool(EnvKey::AUTH_PREVENT_SEQUENTIAL_CHARS, true),
|
||||
minPasswordScore: $env->getInt(EnvKey::AUTH_MIN_PASSWORD_SCORE, 50)
|
||||
);
|
||||
}
|
||||
|
||||
public function getSecurityLevelParameters(string $algorithm): array
|
||||
{
|
||||
return match ([$algorithm, $this->defaultSecurityLevel]) {
|
||||
['argon2id', 'low'] => [
|
||||
'memory_cost' => 32768, // 32 MB
|
||||
'time_cost' => 2,
|
||||
'threads' => 2
|
||||
],
|
||||
['argon2id', 'standard'] => [
|
||||
'memory_cost' => 65536, // 64 MB
|
||||
'time_cost' => 4,
|
||||
'threads' => 3
|
||||
],
|
||||
['argon2id', 'high'] => [
|
||||
'memory_cost' => 131072, // 128 MB
|
||||
'time_cost' => 6,
|
||||
'threads' => 4
|
||||
],
|
||||
['pbkdf2-sha256', 'low'] => ['iterations' => 50000],
|
||||
['pbkdf2-sha256', 'standard'] => ['iterations' => 100000],
|
||||
['pbkdf2-sha256', 'high'] => ['iterations' => 200000],
|
||||
default => []
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Database Schema
|
||||
|
||||
### Required Tables
|
||||
|
||||
```sql
|
||||
-- Benutzer-Tabelle (beispielhaft)
|
||||
CREATE TABLE users (
|
||||
id VARCHAR(255) PRIMARY KEY,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
username VARCHAR(100) UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
password_algorithm VARCHAR(50) NOT NULL DEFAULT 'argon2id',
|
||||
password_parameters JSON,
|
||||
created_at DATETIME NOT NULL,
|
||||
updated_at DATETIME NOT NULL,
|
||||
last_login_at DATETIME NULL,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
|
||||
INDEX idx_email (email),
|
||||
INDEX idx_username (username),
|
||||
INDEX idx_active (is_active)
|
||||
);
|
||||
|
||||
-- Session-Tabelle
|
||||
CREATE TABLE auth_sessions (
|
||||
id VARCHAR(255) PRIMARY KEY,
|
||||
user_id VARCHAR(255) NOT NULL,
|
||||
ip_address VARCHAR(45),
|
||||
user_agent TEXT,
|
||||
created_at DATETIME NOT NULL,
|
||||
expires_at DATETIME NOT NULL,
|
||||
last_activity DATETIME NOT NULL,
|
||||
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_expires_at (expires_at),
|
||||
INDEX idx_last_activity (last_activity)
|
||||
);
|
||||
|
||||
-- Remember Token Tabelle
|
||||
CREATE TABLE auth_remember_tokens (
|
||||
token_hash VARCHAR(64) PRIMARY KEY,
|
||||
user_id VARCHAR(255) NOT NULL,
|
||||
created_at DATETIME NOT NULL,
|
||||
expires_at DATETIME NOT NULL,
|
||||
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_expires_at (expires_at)
|
||||
);
|
||||
|
||||
-- Failed Login Attempts Tabelle
|
||||
CREATE TABLE auth_failed_attempts (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id VARCHAR(255),
|
||||
identifier VARCHAR(255),
|
||||
ip_address VARCHAR(45),
|
||||
attempted_at DATETIME NOT NULL,
|
||||
reason VARCHAR(100),
|
||||
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_identifier (identifier),
|
||||
INDEX idx_ip_address (ip_address),
|
||||
INDEX idx_attempted_at (attempted_at)
|
||||
);
|
||||
|
||||
-- Security Events Tabelle (optional für Logging)
|
||||
CREATE TABLE auth_security_events (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
event_type VARCHAR(50) NOT NULL,
|
||||
user_id VARCHAR(255),
|
||||
session_id VARCHAR(255),
|
||||
ip_address VARCHAR(45),
|
||||
user_agent TEXT,
|
||||
event_data JSON,
|
||||
created_at DATETIME NOT NULL,
|
||||
|
||||
INDEX idx_event_type (event_type),
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_created_at (created_at),
|
||||
INDEX idx_ip_address (ip_address)
|
||||
);
|
||||
```
|
||||
|
||||
### Migration Commands
|
||||
|
||||
```bash
|
||||
# Migration erstellen
|
||||
php console.php make:migration CreateAuthTables Auth
|
||||
|
||||
# Migration ausführen
|
||||
php console.php db:migrate
|
||||
|
||||
# Migration Status prüfen
|
||||
php console.php db:status
|
||||
```
|
||||
|
||||
## Security Level Configuration
|
||||
|
||||
### Password Hashing Levels
|
||||
|
||||
```php
|
||||
// Niedrige Sicherheit (Development, Testing)
|
||||
$lowSecurity = new PasswordHasher(
|
||||
kdf: $kdf,
|
||||
defaultAlgorithm: 'argon2id',
|
||||
defaultSecurityLevel: PasswordHasher::LEVEL_LOW
|
||||
);
|
||||
|
||||
// Standard Sicherheit (Production Default)
|
||||
$standardSecurity = new PasswordHasher(
|
||||
kdf: $kdf,
|
||||
defaultAlgorithm: 'argon2id',
|
||||
defaultSecurityLevel: PasswordHasher::LEVEL_STANDARD
|
||||
);
|
||||
|
||||
// Hohe Sicherheit (Banking, Healthcare)
|
||||
$highSecurity = new PasswordHasher(
|
||||
kdf: $kdf,
|
||||
defaultAlgorithm: 'argon2id',
|
||||
defaultSecurityLevel: PasswordHasher::LEVEL_HIGH
|
||||
);
|
||||
```
|
||||
|
||||
### Algorithm Performance Comparison
|
||||
|
||||
| Algorithm | Level | Memory | Time | Iterations | Performance | Security |
|
||||
|-----------|-------|---------|------|------------|-------------|----------|
|
||||
| Argon2ID | Low | 32 MB | 2 | - | Fast | Good |
|
||||
| Argon2ID | Standard | 64 MB | 4 | - | Medium | Excellent |
|
||||
| Argon2ID | High | 128 MB | 6 | - | Slow | Maximum |
|
||||
| PBKDF2-SHA256 | Low | - | - | 50,000 | Fast | Good |
|
||||
| PBKDF2-SHA256 | Standard | - | - | 100,000 | Fast | Good |
|
||||
| PBKDF2-SHA256 | High | - | - | 200,000 | Medium | Good |
|
||||
| Scrypt | Standard | 16 MB | - | - | Medium | Good |
|
||||
|
||||
## Rate Limiting Configuration
|
||||
|
||||
### Redis-based Rate Limiting
|
||||
|
||||
```php
|
||||
use App\Framework\Auth\RateLimit\RedisRateLimitService;
|
||||
|
||||
$rateLimiter = new RedisRateLimitService(
|
||||
redis: $redis,
|
||||
config: new RateLimitConfig(
|
||||
maxAttempts: 5,
|
||||
windowSeconds: 300,
|
||||
lockoutDuration: 900
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
### File-based Rate Limiting
|
||||
|
||||
```php
|
||||
use App\Framework\Auth\RateLimit\FileRateLimitService;
|
||||
|
||||
$rateLimiter = new FileRateLimitService(
|
||||
cacheDir: '/tmp/auth_rate_limits',
|
||||
config: new RateLimitConfig(
|
||||
maxAttempts: 5,
|
||||
windowSeconds: 300,
|
||||
lockoutDuration: 900,
|
||||
cleanupInterval: 3600 // Cleanup alte Einträge jede Stunde
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
## Monitoring & Logging
|
||||
|
||||
### Security Event Configuration
|
||||
|
||||
```php
|
||||
// Security Event Handler
|
||||
final readonly class SecurityEventHandler
|
||||
{
|
||||
public function __construct(
|
||||
private Logger $logger,
|
||||
private ?AlertingService $alerting = null
|
||||
) {}
|
||||
|
||||
public function handle(SecurityEvent $event): void
|
||||
{
|
||||
// Log alle Security Events
|
||||
$this->logger->warning('Security Event', [
|
||||
'event_type' => $event->getType(),
|
||||
'user_id' => $event->getUserId(),
|
||||
'ip_address' => (string) $event->getIpAddress(),
|
||||
'data' => $event->getData()
|
||||
]);
|
||||
|
||||
// Kritische Events alarmieren
|
||||
if ($event->isCritical()) {
|
||||
$this->alerting?->sendAlert($event);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Performance Monitoring
|
||||
|
||||
```php
|
||||
// Performance Metrics für Password Hashing
|
||||
$start = microtime(true);
|
||||
$hashedPassword = $passwordHasher->hash($password);
|
||||
$hashTime = microtime(true) - $start;
|
||||
|
||||
$this->metrics->histogram('auth.password_hash_duration', $hashTime, [
|
||||
'algorithm' => $hashedPassword->getAlgorithm(),
|
||||
'security_level' => $securityLevel
|
||||
]);
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### Environment-specific Configuration
|
||||
|
||||
```php
|
||||
// Production
|
||||
AUTH_DEFAULT_SECURITY_LEVEL=high
|
||||
AUTH_SESSION_TIMEOUT=1800 # 30 Minuten
|
||||
AUTH_CHECK_IP_CONSISTENCY=true # Striktere IP-Prüfung
|
||||
AUTH_MAX_LOGIN_ATTEMPTS=3 # Weniger Versuche
|
||||
AUTH_LOCKOUT_DURATION=3600 # 1 Stunde Lockout
|
||||
|
||||
// Development
|
||||
AUTH_DEFAULT_SECURITY_LEVEL=low
|
||||
AUTH_SESSION_TIMEOUT=86400 # 24 Stunden
|
||||
AUTH_CHECK_IP_CONSISTENCY=false
|
||||
AUTH_MAX_LOGIN_ATTEMPTS=10
|
||||
AUTH_LOCKOUT_DURATION=300 # 5 Minuten
|
||||
|
||||
// Testing
|
||||
AUTH_DEFAULT_SECURITY_LEVEL=low
|
||||
AUTH_SESSION_TIMEOUT=3600
|
||||
AUTH_MAX_LOGIN_ATTEMPTS=5
|
||||
AUTH_LOCKOUT_DURATION=60 # 1 Minute
|
||||
```
|
||||
|
||||
### Security Headers Configuration
|
||||
|
||||
```php
|
||||
// Middleware für Auth-bezogene Security Headers
|
||||
final readonly class AuthSecurityHeadersMiddleware
|
||||
{
|
||||
public function handle(HttpRequest $request, callable $next): HttpResponse
|
||||
{
|
||||
$response = $next($request);
|
||||
|
||||
if ($request->getUri()->getPath() === '/login') {
|
||||
$response = $response->withHeader('X-Frame-Options', 'DENY');
|
||||
$response = $response->withHeader('X-Content-Type-Options', 'nosniff');
|
||||
$response = $response->withHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Backup & Recovery
|
||||
|
||||
### Session Cleanup
|
||||
|
||||
```bash
|
||||
# Cron Job für Session Cleanup (täglich)
|
||||
0 2 * * * php /path/to/console.php auth:cleanup-expired-sessions
|
||||
|
||||
# Manual Cleanup
|
||||
php console.php auth:cleanup-expired-sessions
|
||||
php console.php auth:cleanup-expired-tokens
|
||||
```
|
||||
|
||||
### Data Retention
|
||||
|
||||
```php
|
||||
// Cleanup Commands
|
||||
final readonly class CleanupExpiredSessionsCommand
|
||||
{
|
||||
public function execute(): void
|
||||
{
|
||||
$expiredCount = $this->repository->deleteExpiredSessions();
|
||||
$this->output->writeln("Deleted {$expiredCount} expired sessions");
|
||||
|
||||
$tokenCount = $this->repository->deleteExpiredRememberTokens();
|
||||
$this->output->writeln("Deleted {$tokenCount} expired remember tokens");
|
||||
|
||||
$attemptCount = $this->repository->cleanupOldFailedAttempts(days: 30);
|
||||
$this->output->writeln("Cleaned up {$attemptCount} old failed attempts");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user