mcp-security-framework 1.1.0__py3-none-any.whl → 1.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_security_framework/__init__.py +26 -15
- mcp_security_framework/cli/__init__.py +1 -1
- mcp_security_framework/cli/cert_cli.py +233 -197
- mcp_security_framework/cli/security_cli.py +324 -234
- mcp_security_framework/constants.py +21 -27
- mcp_security_framework/core/auth_manager.py +41 -22
- mcp_security_framework/core/cert_manager.py +210 -147
- mcp_security_framework/core/permission_manager.py +9 -9
- mcp_security_framework/core/rate_limiter.py +2 -2
- mcp_security_framework/core/security_manager.py +284 -229
- mcp_security_framework/examples/__init__.py +6 -0
- mcp_security_framework/examples/comprehensive_example.py +349 -279
- mcp_security_framework/examples/django_example.py +247 -206
- mcp_security_framework/examples/fastapi_example.py +315 -283
- mcp_security_framework/examples/flask_example.py +274 -203
- mcp_security_framework/examples/gateway_example.py +304 -237
- mcp_security_framework/examples/microservice_example.py +258 -189
- mcp_security_framework/examples/standalone_example.py +255 -230
- mcp_security_framework/examples/test_all_examples.py +151 -135
- mcp_security_framework/middleware/__init__.py +46 -55
- mcp_security_framework/middleware/auth_middleware.py +62 -63
- mcp_security_framework/middleware/fastapi_auth_middleware.py +119 -118
- mcp_security_framework/middleware/fastapi_middleware.py +156 -148
- mcp_security_framework/middleware/flask_auth_middleware.py +160 -147
- mcp_security_framework/middleware/flask_middleware.py +183 -157
- mcp_security_framework/middleware/mtls_middleware.py +106 -117
- mcp_security_framework/middleware/rate_limit_middleware.py +105 -101
- mcp_security_framework/middleware/security_middleware.py +109 -124
- mcp_security_framework/schemas/config.py +2 -1
- mcp_security_framework/schemas/models.py +18 -6
- mcp_security_framework/utils/cert_utils.py +14 -8
- mcp_security_framework/utils/datetime_compat.py +116 -0
- {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/METADATA +4 -3
- mcp_security_framework-1.1.2.dist-info/RECORD +84 -0
- tests/conftest.py +63 -66
- tests/test_cli/test_cert_cli.py +184 -146
- tests/test_cli/test_security_cli.py +274 -247
- tests/test_core/test_cert_manager.py +24 -10
- tests/test_core/test_security_manager.py +2 -2
- tests/test_examples/test_comprehensive_example.py +190 -137
- tests/test_examples/test_fastapi_example.py +124 -101
- tests/test_examples/test_flask_example.py +124 -101
- tests/test_examples/test_standalone_example.py +73 -80
- tests/test_integration/test_auth_flow.py +213 -197
- tests/test_integration/test_certificate_flow.py +180 -149
- tests/test_integration/test_fastapi_integration.py +108 -111
- tests/test_integration/test_flask_integration.py +141 -140
- tests/test_integration/test_standalone_integration.py +290 -259
- tests/test_middleware/test_fastapi_auth_middleware.py +195 -174
- tests/test_middleware/test_fastapi_middleware.py +147 -132
- tests/test_middleware/test_flask_auth_middleware.py +260 -202
- tests/test_middleware/test_flask_middleware.py +201 -179
- tests/test_middleware/test_security_middleware.py +145 -130
- tests/test_utils/test_datetime_compat.py +147 -0
- mcp_security_framework-1.1.0.dist-info/RECORD +0 -82
- {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/WHEEL +0 -0
- {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/entry_points.txt +0 -0
- {mcp_security_framework-1.1.0.dist-info → mcp_security_framework-1.1.2.dist-info}/top_level.txt +0 -0
@@ -28,70 +28,70 @@ Last Modified: 2024-01-20
|
|
28
28
|
|
29
29
|
import json
|
30
30
|
import logging
|
31
|
-
from typing import Any, Dict,
|
31
|
+
from typing import Any, Dict, List, Optional
|
32
32
|
|
33
33
|
from fastapi import Request, Response, status
|
34
34
|
from fastapi.responses import JSONResponse
|
35
35
|
from starlette.middleware.base import BaseHTTPMiddleware
|
36
36
|
|
37
37
|
from mcp_security_framework.middleware.auth_middleware import AuthMiddleware
|
38
|
-
from mcp_security_framework.schemas.models import AuthResult, AuthStatus, AuthMethod
|
39
38
|
from mcp_security_framework.schemas.config import SecurityConfig
|
39
|
+
from mcp_security_framework.schemas.models import AuthMethod, AuthResult, AuthStatus
|
40
40
|
|
41
41
|
|
42
42
|
class FastAPIAuthMiddleware(AuthMiddleware):
|
43
43
|
"""
|
44
44
|
FastAPI Authentication Middleware Implementation
|
45
|
-
|
45
|
+
|
46
46
|
This class provides FastAPI-specific authentication middleware that
|
47
47
|
handles authentication-only processing for FastAPI applications.
|
48
|
-
|
48
|
+
|
49
49
|
The middleware implements:
|
50
50
|
- FastAPI request/response handling
|
51
51
|
- Authentication caching and optimization
|
52
52
|
- Framework-specific error responses
|
53
53
|
- Security event logging
|
54
|
-
|
54
|
+
|
55
55
|
Attributes:
|
56
56
|
config (SecurityConfig): Security configuration settings
|
57
57
|
security_manager: Security manager instance
|
58
58
|
logger (Logger): Logger instance for authentication operations
|
59
59
|
_auth_cache (Dict): Authentication result cache
|
60
|
-
|
60
|
+
|
61
61
|
Example:
|
62
62
|
>>> from mcp_security_framework.middleware import create_auth_middleware
|
63
63
|
>>> middleware = create_auth_middleware(config, framework="fastapi")
|
64
64
|
>>> app.add_middleware(middleware)
|
65
|
-
|
65
|
+
|
66
66
|
Raises:
|
67
67
|
AuthMiddlewareError: When authentication processing fails
|
68
68
|
"""
|
69
|
-
|
69
|
+
|
70
70
|
def __init__(self, security_manager: Any):
|
71
71
|
"""
|
72
72
|
Initialize FastAPI Authentication Middleware.
|
73
|
-
|
73
|
+
|
74
74
|
Args:
|
75
75
|
security_manager: Security manager instance
|
76
76
|
"""
|
77
77
|
super().__init__(security_manager)
|
78
78
|
self.logger = logging.getLogger(__name__)
|
79
|
-
|
79
|
+
|
80
80
|
async def __call__(self, request: Request, call_next: Any) -> Response:
|
81
81
|
"""
|
82
82
|
Process FastAPI request through authentication middleware.
|
83
|
-
|
83
|
+
|
84
84
|
This method implements the authentication-only processing
|
85
85
|
pipeline for FastAPI requests, focusing solely on user
|
86
86
|
authentication without authorization checks.
|
87
|
-
|
87
|
+
|
88
88
|
Args:
|
89
89
|
request (Request): FastAPI request object
|
90
90
|
call_next: FastAPI call_next function
|
91
|
-
|
91
|
+
|
92
92
|
Returns:
|
93
93
|
Response: FastAPI response object
|
94
|
-
|
94
|
+
|
95
95
|
Raises:
|
96
96
|
AuthMiddlewareError: If authentication processing fails
|
97
97
|
"""
|
@@ -99,73 +99,75 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
99
99
|
# Check if path is public (bypasses authentication)
|
100
100
|
if self._is_public_path(request):
|
101
101
|
return await call_next(request)
|
102
|
-
|
102
|
+
|
103
103
|
# Perform authentication
|
104
104
|
auth_result = self._authenticate_only(request)
|
105
|
-
|
105
|
+
|
106
106
|
if not auth_result.is_valid:
|
107
107
|
return self._auth_error_response(auth_result)
|
108
|
-
|
108
|
+
|
109
109
|
# Add authentication info to request state
|
110
110
|
request.state.auth_result = auth_result
|
111
111
|
request.state.username = auth_result.username
|
112
112
|
request.state.user_roles = auth_result.roles
|
113
113
|
request.state.auth_method = auth_result.auth_method
|
114
|
-
|
114
|
+
|
115
115
|
# Process request
|
116
116
|
response = await call_next(request)
|
117
|
-
|
117
|
+
|
118
118
|
# Log successful authentication
|
119
|
-
self._log_auth_event(
|
120
|
-
"
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
119
|
+
self._log_auth_event(
|
120
|
+
"authentication_successful",
|
121
|
+
{
|
122
|
+
"ip_address": self._get_client_ip(request),
|
123
|
+
"username": auth_result.username,
|
124
|
+
"path": str(request.url.path),
|
125
|
+
"method": request.method,
|
126
|
+
"auth_method": auth_result.auth_method,
|
127
|
+
},
|
128
|
+
)
|
129
|
+
|
127
130
|
return response
|
128
|
-
|
131
|
+
|
129
132
|
except Exception as e:
|
130
133
|
self.logger.error(
|
131
134
|
"FastAPI authentication middleware processing failed",
|
132
135
|
extra={"error": str(e)},
|
133
|
-
exc_info=True
|
136
|
+
exc_info=True,
|
134
137
|
)
|
135
138
|
raise AuthMiddlewareError(
|
136
|
-
f"Authentication processing failed: {str(e)}",
|
137
|
-
error_code=-32035
|
139
|
+
f"Authentication processing failed: {str(e)}", error_code=-32035
|
138
140
|
)
|
139
|
-
|
141
|
+
|
140
142
|
def _is_public_path(self, request: Request) -> bool:
|
141
143
|
"""
|
142
144
|
Check if the request path is public (bypasses authentication).
|
143
|
-
|
145
|
+
|
144
146
|
Args:
|
145
147
|
request (Request): FastAPI request object
|
146
|
-
|
148
|
+
|
147
149
|
Returns:
|
148
150
|
bool: True if path is public, False otherwise
|
149
151
|
"""
|
150
152
|
path = str(request.url.path)
|
151
|
-
|
153
|
+
|
152
154
|
# Check configured public paths
|
153
|
-
if hasattr(self.config.auth,
|
155
|
+
if hasattr(self.config.auth, "public_paths"):
|
154
156
|
for public_path in self.config.auth.public_paths:
|
155
157
|
if path.startswith(public_path):
|
156
158
|
return True
|
157
|
-
|
159
|
+
|
158
160
|
# Check common public paths
|
159
161
|
public_paths = ["/health", "/status", "/metrics", "/docs", "/openapi.json"]
|
160
162
|
return any(path.startswith(public_path) for public_path in public_paths)
|
161
|
-
|
163
|
+
|
162
164
|
def _get_client_ip(self, request: Request) -> str:
|
163
165
|
"""
|
164
166
|
Get client IP address from FastAPI request.
|
165
|
-
|
167
|
+
|
166
168
|
Args:
|
167
169
|
request (Request): FastAPI request object
|
168
|
-
|
170
|
+
|
169
171
|
Returns:
|
170
172
|
str: Client IP address
|
171
173
|
"""
|
@@ -173,33 +175,35 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
173
175
|
forwarded_for = request.headers.get("X-Forwarded-For")
|
174
176
|
if forwarded_for:
|
175
177
|
return forwarded_for.split(",")[0].strip()
|
176
|
-
|
178
|
+
|
177
179
|
# Try X-Real-IP header
|
178
180
|
real_ip = request.headers.get("X-Real-IP")
|
179
181
|
if real_ip:
|
180
182
|
return real_ip
|
181
|
-
|
183
|
+
|
182
184
|
# Use client host
|
183
|
-
if hasattr(request,
|
185
|
+
if hasattr(request, "client") and request.client:
|
184
186
|
return request.client.host
|
185
|
-
|
187
|
+
|
186
188
|
# Fallback to default IP from config or environment
|
187
|
-
default_ip = getattr(self.config,
|
189
|
+
default_ip = getattr(self.config, "default_client_ip", None)
|
188
190
|
if default_ip:
|
189
191
|
return default_ip
|
190
|
-
|
192
|
+
|
191
193
|
# Use environment variable or default
|
192
194
|
import os
|
195
|
+
|
193
196
|
from ..constants import DEFAULT_CLIENT_IP
|
194
|
-
|
195
|
-
|
197
|
+
|
198
|
+
return os.environ.get("DEFAULT_CLIENT_IP", DEFAULT_CLIENT_IP)
|
199
|
+
|
196
200
|
def _get_cache_key(self, request: Request) -> str:
|
197
201
|
"""
|
198
202
|
Generate cache key for authentication result.
|
199
|
-
|
203
|
+
|
200
204
|
Args:
|
201
205
|
request (Request): FastAPI request object
|
202
|
-
|
206
|
+
|
203
207
|
Returns:
|
204
208
|
str: Cache key
|
205
209
|
"""
|
@@ -207,15 +211,15 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
207
211
|
ip = self._get_client_ip(request)
|
208
212
|
user_agent = request.headers.get("User-Agent", "")
|
209
213
|
return f"auth:{ip}:{hash(user_agent)}"
|
210
|
-
|
214
|
+
|
211
215
|
def _try_auth_method(self, request: Request, method: str) -> AuthResult:
|
212
216
|
"""
|
213
217
|
Try authentication using specific method with FastAPI request.
|
214
|
-
|
218
|
+
|
215
219
|
Args:
|
216
220
|
request (Request): FastAPI request object
|
217
221
|
method (str): Authentication method to try
|
218
|
-
|
222
|
+
|
219
223
|
Returns:
|
220
224
|
AuthResult: Authentication result
|
221
225
|
"""
|
@@ -236,13 +240,13 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
236
240
|
roles=[],
|
237
241
|
auth_method=None,
|
238
242
|
error_code=-32022,
|
239
|
-
error_message=f"Unsupported authentication method: {method}"
|
243
|
+
error_message=f"Unsupported authentication method: {method}",
|
240
244
|
)
|
241
245
|
except Exception as e:
|
242
246
|
self.logger.error(
|
243
247
|
f"Authentication method {method} failed",
|
244
248
|
extra={"error": str(e)},
|
245
|
-
exc_info=True
|
249
|
+
exc_info=True,
|
246
250
|
)
|
247
251
|
return AuthResult(
|
248
252
|
is_valid=False,
|
@@ -251,16 +255,16 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
251
255
|
roles=[],
|
252
256
|
auth_method=None,
|
253
257
|
error_code=-32023,
|
254
|
-
error_message=f"Authentication method {method} failed: {str(e)}"
|
258
|
+
error_message=f"Authentication method {method} failed: {str(e)}",
|
255
259
|
)
|
256
|
-
|
260
|
+
|
257
261
|
def _try_api_key_auth(self, request: Request) -> AuthResult:
|
258
262
|
"""
|
259
263
|
Try API key authentication with FastAPI request.
|
260
|
-
|
264
|
+
|
261
265
|
Args:
|
262
266
|
request (Request): FastAPI request object
|
263
|
-
|
267
|
+
|
264
268
|
Returns:
|
265
269
|
AuthResult: Authentication result
|
266
270
|
"""
|
@@ -271,7 +275,7 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
271
275
|
auth_header = request.headers.get("Authorization")
|
272
276
|
if auth_header and auth_header.startswith("Bearer "):
|
273
277
|
api_key = auth_header[7:] # Remove "Bearer " prefix
|
274
|
-
|
278
|
+
|
275
279
|
if not api_key:
|
276
280
|
return AuthResult(
|
277
281
|
is_valid=False,
|
@@ -280,19 +284,19 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
280
284
|
roles=[],
|
281
285
|
auth_method=AuthMethod.API_KEY,
|
282
286
|
error_code=-32012,
|
283
|
-
error_message="API key not found in request"
|
287
|
+
error_message="API key not found in request",
|
284
288
|
)
|
285
|
-
|
289
|
+
|
286
290
|
# Authenticate using security manager
|
287
291
|
return self.security_manager.auth_manager.authenticate_api_key(api_key)
|
288
|
-
|
292
|
+
|
289
293
|
def _try_jwt_auth(self, request: Request) -> AuthResult:
|
290
294
|
"""
|
291
295
|
Try JWT authentication with FastAPI request.
|
292
|
-
|
296
|
+
|
293
297
|
Args:
|
294
298
|
request (Request): FastAPI request object
|
295
|
-
|
299
|
+
|
296
300
|
Returns:
|
297
301
|
AuthResult: Authentication result
|
298
302
|
"""
|
@@ -306,21 +310,21 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
306
310
|
roles=[],
|
307
311
|
auth_method=AuthMethod.JWT,
|
308
312
|
error_code=-32013,
|
309
|
-
error_message="JWT token not found in Authorization header"
|
313
|
+
error_message="JWT token not found in Authorization header",
|
310
314
|
)
|
311
|
-
|
315
|
+
|
312
316
|
token = auth_header[7:] # Remove "Bearer " prefix
|
313
|
-
|
317
|
+
|
314
318
|
# Authenticate using security manager
|
315
319
|
return self.security_manager.auth_manager.authenticate_jwt_token(token)
|
316
|
-
|
320
|
+
|
317
321
|
def _try_certificate_auth(self, request: Request) -> AuthResult:
|
318
322
|
"""
|
319
323
|
Try certificate authentication with FastAPI request.
|
320
|
-
|
324
|
+
|
321
325
|
Args:
|
322
326
|
request (Request): FastAPI request object
|
323
|
-
|
327
|
+
|
324
328
|
Returns:
|
325
329
|
AuthResult: Authentication result
|
326
330
|
"""
|
@@ -334,16 +338,16 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
334
338
|
roles=[],
|
335
339
|
auth_method=AuthMethod.CERTIFICATE,
|
336
340
|
error_code=-32014,
|
337
|
-
error_message="Certificate authentication not implemented"
|
341
|
+
error_message="Certificate authentication not implemented",
|
338
342
|
)
|
339
|
-
|
343
|
+
|
340
344
|
def _try_basic_auth(self, request: Request) -> AuthResult:
|
341
345
|
"""
|
342
346
|
Try basic authentication with FastAPI request.
|
343
|
-
|
347
|
+
|
344
348
|
Args:
|
345
349
|
request (Request): FastAPI request object
|
346
|
-
|
350
|
+
|
347
351
|
Returns:
|
348
352
|
AuthResult: Authentication result
|
349
353
|
"""
|
@@ -357,9 +361,9 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
357
361
|
roles=[],
|
358
362
|
auth_method=AuthMethod.BASIC,
|
359
363
|
error_code=-32015,
|
360
|
-
error_message="Basic authentication credentials not found"
|
364
|
+
error_message="Basic authentication credentials not found",
|
361
365
|
)
|
362
|
-
|
366
|
+
|
363
367
|
# Basic auth is not implemented in this version
|
364
368
|
return AuthResult(
|
365
369
|
is_valid=False,
|
@@ -368,16 +372,16 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
368
372
|
roles=[],
|
369
373
|
auth_method=AuthMethod.BASIC,
|
370
374
|
error_code=-32016,
|
371
|
-
error_message="Basic authentication not implemented"
|
375
|
+
error_message="Basic authentication not implemented",
|
372
376
|
)
|
373
|
-
|
377
|
+
|
374
378
|
def _auth_error_response(self, auth_result: AuthResult) -> JSONResponse:
|
375
379
|
"""
|
376
380
|
Create authentication error response for FastAPI.
|
377
|
-
|
381
|
+
|
378
382
|
Args:
|
379
383
|
auth_result (AuthResult): Authentication result with error
|
380
|
-
|
384
|
+
|
381
385
|
Returns:
|
382
386
|
JSONResponse: FastAPI error response
|
383
387
|
"""
|
@@ -385,24 +389,23 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
385
389
|
"error": "Authentication failed",
|
386
390
|
"error_code": auth_result.error_code,
|
387
391
|
"error_message": auth_result.error_message,
|
388
|
-
"auth_method":
|
389
|
-
|
390
|
-
|
391
|
-
headers = {
|
392
|
-
"WWW-Authenticate": "Bearer",
|
393
|
-
"Content-Type": "application/json"
|
392
|
+
"auth_method": (
|
393
|
+
auth_result.auth_method.value if auth_result.auth_method else None
|
394
|
+
),
|
394
395
|
}
|
395
|
-
|
396
|
+
|
397
|
+
headers = {"WWW-Authenticate": "Bearer", "Content-Type": "application/json"}
|
398
|
+
|
396
399
|
return JSONResponse(
|
397
400
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
398
401
|
content=error_data,
|
399
|
-
headers=headers
|
402
|
+
headers=headers,
|
400
403
|
)
|
401
|
-
|
404
|
+
|
402
405
|
def _log_auth_event(self, event_type: str, details: Dict[str, Any]) -> None:
|
403
406
|
"""
|
404
407
|
Log authentication event.
|
405
|
-
|
408
|
+
|
406
409
|
Args:
|
407
410
|
event_type (str): Type of authentication event
|
408
411
|
details (Dict[str, Any]): Event details
|
@@ -418,97 +421,95 @@ class FastAPIAuthMiddleware(AuthMiddleware):
|
|
418
421
|
"path": details.get("path"),
|
419
422
|
"method": details.get("method"),
|
420
423
|
"auth_method": details.get("auth_method"),
|
421
|
-
**details
|
422
|
-
}
|
424
|
+
**details,
|
425
|
+
},
|
423
426
|
)
|
424
427
|
except Exception as e:
|
425
428
|
self.logger.error(
|
426
429
|
"Failed to log authentication event",
|
427
430
|
extra={"error": str(e)},
|
428
|
-
exc_info=True
|
431
|
+
exc_info=True,
|
429
432
|
)
|
430
|
-
|
433
|
+
|
431
434
|
# Abstract method implementations
|
432
|
-
|
435
|
+
|
433
436
|
def _get_rate_limit_identifier(self, request: Request) -> str:
|
434
437
|
"""
|
435
438
|
Get rate limit identifier from FastAPI request.
|
436
|
-
|
439
|
+
|
437
440
|
Args:
|
438
441
|
request (Request): FastAPI request object
|
439
|
-
|
442
|
+
|
440
443
|
Returns:
|
441
444
|
str: Rate limit identifier (IP address)
|
442
445
|
"""
|
443
446
|
return self._get_client_ip(request)
|
444
|
-
|
447
|
+
|
445
448
|
def _get_request_path(self, request: Request) -> str:
|
446
449
|
"""
|
447
450
|
Get request path from FastAPI request.
|
448
|
-
|
451
|
+
|
449
452
|
Args:
|
450
453
|
request (Request): FastAPI request object
|
451
|
-
|
454
|
+
|
452
455
|
Returns:
|
453
456
|
str: Request path
|
454
457
|
"""
|
455
458
|
return str(request.url.path)
|
456
|
-
|
459
|
+
|
457
460
|
def _get_required_permissions(self, request: Request) -> List[str]:
|
458
461
|
"""
|
459
462
|
Get required permissions for FastAPI request.
|
460
|
-
|
463
|
+
|
461
464
|
Args:
|
462
465
|
request (Request): FastAPI request object
|
463
|
-
|
466
|
+
|
464
467
|
Returns:
|
465
468
|
List[str]: List of required permissions
|
466
469
|
"""
|
467
470
|
# For authentication-only middleware, no permissions are required
|
468
471
|
return []
|
469
|
-
|
470
|
-
def _apply_security_headers(
|
472
|
+
|
473
|
+
def _apply_security_headers(
|
474
|
+
self, response: Response, headers: Dict[str, str]
|
475
|
+
) -> None:
|
471
476
|
"""
|
472
477
|
Apply security headers to FastAPI response.
|
473
|
-
|
478
|
+
|
474
479
|
Args:
|
475
480
|
response (Response): FastAPI response object
|
476
481
|
headers (Dict[str, str]): Headers to apply
|
477
482
|
"""
|
478
483
|
for header, value in headers.items():
|
479
484
|
response.headers[header] = value
|
480
|
-
|
485
|
+
|
481
486
|
def _create_error_response(self, status_code: int, message: str) -> JSONResponse:
|
482
487
|
"""
|
483
488
|
Create error response for FastAPI.
|
484
|
-
|
489
|
+
|
485
490
|
Args:
|
486
491
|
status_code (int): HTTP status code
|
487
492
|
message (str): Error message
|
488
|
-
|
493
|
+
|
489
494
|
Returns:
|
490
495
|
JSONResponse: FastAPI error response object
|
491
496
|
"""
|
492
497
|
return JSONResponse(
|
493
|
-
status_code=status_code,
|
494
|
-
content={
|
495
|
-
"error": message,
|
496
|
-
"error_code": -32000
|
497
|
-
}
|
498
|
+
status_code=status_code, content={"error": message, "error_code": -32000}
|
498
499
|
)
|
499
500
|
|
500
501
|
|
501
502
|
class AuthMiddlewareError(Exception):
|
502
503
|
"""
|
503
504
|
Authentication Middleware Error
|
504
|
-
|
505
|
+
|
505
506
|
This exception is raised when authentication middleware processing fails.
|
506
|
-
|
507
|
+
|
507
508
|
Attributes:
|
508
509
|
message (str): Error message
|
509
510
|
error_code (int): Error code for programmatic handling
|
510
511
|
"""
|
511
|
-
|
512
|
+
|
512
513
|
def __init__(self, message: str, error_code: int = -32030):
|
513
514
|
self.message = message
|
514
515
|
self.error_code = error_code
|