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:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View 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");
}
}