Files
pgsql-jellyfin/docs/exception-middleware-authentication-messaging.md
wjones c76853a442 PostgreSQL: Production fixes—UPSERT, remote backup, auth logs
- Fix: Atomic UPSERT for BaseItemProviders (resolves duplicate key errors during concurrent metadata refresh; clears navigation property to prevent EF Core tracking conflicts)
- Add: Remote PostgreSQL backup support (removes localhost-only restriction; works with pg_dump/pg_restore for both local and remote DBs)
- Add: Configurable backup disable option (`disable-backups`)
- Fix: Query timeout and performance (documented `command-timeout` config, added performance index scripts)
- Fix: Authentication errors now log as warnings with clear messages (ExceptionMiddleware), reducing log noise
- Fix: SyncPlay authorization handler validates user before lookup, logs warnings for unauthenticated/unknown users (returns 403/404)
- Fix: Database deadlock detection logs warnings and allows EF Core auto-retry
- Add: Configurable LibraryMonitorDelay (min 30s, default 60s)
- Fix: SQLite migration filtering—skip SQLite-only migrations on PostgreSQL
- Chore: Suppress StyleCop warnings (SA1137, etc.) for project consistency
- Docs: 21 documentation files added/updated (config, backup, performance, troubleshooting, session summary)
- All changes are backward compatible and production-ready
2026-03-03 16:35:27 -05:00

236 lines
6.2 KiB
Markdown

# Exception Middleware - Authentication Error Messaging Improvement
## Problem
When users accessed endpoints without proper authentication (e.g., WebSocket `/socket` endpoint), the error was logged as:
```
[ERR] Error processing request: Token is required. URL GET /socket
```
This made it appear as a bug or system error to end users and administrators, when it's actually expected behavior for unauthenticated requests.
## Solution
Modified `ExceptionMiddleware.cs` to:
1. Detect authentication-related exceptions
2. Log them as **WARNING** instead of **ERROR**
3. Provide user-friendly message explaining the issue
### Changes Made
#### Detection Logic
Added check for authentication errors:
```csharp
bool isAuthenticationError = ex is SecurityException || ex is AuthenticationException;
```
#### Improved Logging
**Before:**
```csharp
_logger.LogError(
"Error processing request: {ExceptionMessage}. URL {Method} {Url}.",
ex.Message.TrimEnd('.'),
context.Request.Method,
context.Request.Path);
```
**After:**
```csharp
if (isAuthenticationError)
{
// Log authentication errors as warnings with user-friendly message
_logger.LogWarning(
"Access denied: Unable to process request. Authentication token missing or invalid. URL {Method} {Url}.",
context.Request.Method,
context.Request.Path);
}
else
{
// Other errors still logged as errors
_logger.LogError(
"Error processing request: {ExceptionMessage}. URL {Method} {Url}.",
ex.Message.TrimEnd('.'),
context.Request.Method,
context.Request.Path);
}
```
## Impact
### Before
```
[ERR] [7] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request: Token is required. URL GET /socket
```
**Issues:**
- ❌ Logged as ERROR (suggests a bug)
- ❌ Generic message "Token is required"
- ❌ Looks like something is broken
### After
```
[WRN] [7] Jellyfin.Api.Middleware.ExceptionMiddleware: Access denied: Unable to process request. Authentication token missing or invalid. URL GET /socket
```
**Improvements:**
- ✅ Logged as WARNING (expected behavior)
- ✅ Clear explanation: "Authentication token missing or invalid"
- ✅ Shows the URL where authentication was required
- ✅ Administrators understand this is normal
## Affected Endpoints
This improvement applies to all endpoints that require authentication:
### Common Examples:
- `/socket` - WebSocket connections
- `/Sessions` - Session management
- `/Users/{userId}` - User operations
- `/System/` - System configuration
- `/Library/` - Library operations
### When This Occurs:
1. **Unauthenticated client connects**
- Browser without cookies
- Mobile app without saved token
- API request without Authorization header
2. **Expired token**
- User's session expired
- Token was invalidated
- Server restarted and tokens were lost
3. **Invalid token**
- Corrupted or malformed token
- Token for different server
- Manually crafted invalid token
## Error Levels
The middleware now properly categorizes exceptions:
| Exception Type | Log Level | Example |
|----------------|-----------|---------|
| **AuthenticationException** | WARNING | Token missing/invalid |
| **SecurityException** | WARNING | Access forbidden |
| **SocketException** | ERROR | Network issues |
| **IOException** | ERROR | File access issues |
| **OperationCanceledException** | ERROR | Request cancelled |
| **FileNotFoundException** | ERROR | Resource not found |
| **Other exceptions** | ERROR | Unexpected errors |
## Testing
### Test 1: WebSocket Without Authentication
```bash
# Connect to WebSocket without token
wscat -c ws://localhost:8096/socket
```
**Expected Log:**
```
[WRN] Access denied: Unable to process request. Authentication token missing or invalid. URL GET /socket
```
### Test 2: API Request Without Token
```bash
curl http://localhost:8096/System/Info
```
**Expected Log:**
```
[WRN] Access denied: Unable to process request. Authentication token missing or invalid. URL GET /System/Info
```
### Test 3: Expired Token
```bash
curl -H "Authorization: MediaBrowser Token=expired_token" http://localhost:8096/Users/Me
```
**Expected Log:**
```
[WRN] Access denied: Unable to process request. Authentication token missing or invalid. URL GET /Users/Me
```
### Test 4: Other Errors Still Show as Errors
```bash
# Trigger a different type of error (e.g., malformed request)
curl -X POST http://localhost:8096/Items -H "Content-Type: application/json" -d "invalid json"
```
**Expected Log:**
```
[ERR] Error processing request: [actual error message]. URL POST /Items
```
## Benefits
1. **Reduced False Alarms**
- Administrators won't panic when seeing authentication warnings
- Easier to identify real errors vs expected authentication failures
2. **Better Log Analysis**
- Filter out authentication warnings when troubleshooting
- Focus on actual errors using `[ERR]` filter
3. **User-Friendly Messages**
- Clear explanation of what went wrong
- Includes the URL that required authentication
- Helps users understand they need to log in
4. **Proper HTTP Status Codes**
- Authentication failures return 401 Unauthorized (unchanged)
- Log level now matches the severity
## Related Files
- **`Jellyfin.Api/Middleware/ExceptionMiddleware.cs`**
- Modified exception handling logic
- Added authentication error detection
- Improved log messages and levels
## Configuration
No configuration changes needed. The improvement automatically applies to all authentication failures.
### Log Level Configuration
If you want to see or hide authentication warnings, adjust your logging configuration:
**Hide authentication warnings:**
```json
{
"Serilog": {
"MinimumLevel": {
"Override": {
"Jellyfin.Api.Middleware.ExceptionMiddleware": "Error"
}
}
}
}
```
**Show all warnings (default):**
```json
{
"Serilog": {
"MinimumLevel": {
"Default": "Information"
}
}
}
```
## Future Enhancements
Consider similar improvements for:
- Rate limiting errors (should be warnings)
- Client disconnection errors (often expected)
- Cancelled request errors (user action, not system error)
These could follow the same pattern of detecting expected scenarios and logging them appropriately.