mcp-security-framework 0.1.0__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 +96 -0
- mcp_security_framework/cli/__init__.py +18 -0
- mcp_security_framework/cli/cert_cli.py +511 -0
- mcp_security_framework/cli/security_cli.py +791 -0
- mcp_security_framework/constants.py +209 -0
- mcp_security_framework/core/__init__.py +61 -0
- mcp_security_framework/core/auth_manager.py +1011 -0
- mcp_security_framework/core/cert_manager.py +1663 -0
- mcp_security_framework/core/permission_manager.py +735 -0
- mcp_security_framework/core/rate_limiter.py +602 -0
- mcp_security_framework/core/security_manager.py +943 -0
- mcp_security_framework/core/ssl_manager.py +735 -0
- mcp_security_framework/examples/__init__.py +75 -0
- mcp_security_framework/examples/django_example.py +615 -0
- mcp_security_framework/examples/fastapi_example.py +472 -0
- mcp_security_framework/examples/flask_example.py +506 -0
- mcp_security_framework/examples/gateway_example.py +803 -0
- mcp_security_framework/examples/microservice_example.py +690 -0
- mcp_security_framework/examples/standalone_example.py +576 -0
- mcp_security_framework/middleware/__init__.py +250 -0
- mcp_security_framework/middleware/auth_middleware.py +292 -0
- mcp_security_framework/middleware/fastapi_auth_middleware.py +447 -0
- mcp_security_framework/middleware/fastapi_middleware.py +757 -0
- mcp_security_framework/middleware/flask_auth_middleware.py +465 -0
- mcp_security_framework/middleware/flask_middleware.py +591 -0
- mcp_security_framework/middleware/mtls_middleware.py +439 -0
- mcp_security_framework/middleware/rate_limit_middleware.py +403 -0
- mcp_security_framework/middleware/security_middleware.py +507 -0
- mcp_security_framework/schemas/__init__.py +109 -0
- mcp_security_framework/schemas/config.py +694 -0
- mcp_security_framework/schemas/models.py +709 -0
- mcp_security_framework/schemas/responses.py +686 -0
- mcp_security_framework/tests/__init__.py +0 -0
- mcp_security_framework/utils/__init__.py +121 -0
- mcp_security_framework/utils/cert_utils.py +525 -0
- mcp_security_framework/utils/crypto_utils.py +475 -0
- mcp_security_framework/utils/validation_utils.py +571 -0
- mcp_security_framework-0.1.0.dist-info/METADATA +411 -0
- mcp_security_framework-0.1.0.dist-info/RECORD +76 -0
- mcp_security_framework-0.1.0.dist-info/WHEEL +5 -0
- mcp_security_framework-0.1.0.dist-info/entry_points.txt +3 -0
- mcp_security_framework-0.1.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/test_cli/__init__.py +0 -0
- tests/test_cli/test_cert_cli.py +379 -0
- tests/test_cli/test_security_cli.py +657 -0
- tests/test_core/__init__.py +0 -0
- tests/test_core/test_auth_manager.py +582 -0
- tests/test_core/test_cert_manager.py +795 -0
- tests/test_core/test_permission_manager.py +395 -0
- tests/test_core/test_rate_limiter.py +626 -0
- tests/test_core/test_security_manager.py +841 -0
- tests/test_core/test_ssl_manager.py +532 -0
- tests/test_examples/__init__.py +8 -0
- tests/test_examples/test_fastapi_example.py +264 -0
- tests/test_examples/test_flask_example.py +238 -0
- tests/test_examples/test_standalone_example.py +292 -0
- tests/test_integration/__init__.py +0 -0
- tests/test_integration/test_auth_flow.py +502 -0
- tests/test_integration/test_certificate_flow.py +527 -0
- tests/test_integration/test_fastapi_integration.py +341 -0
- tests/test_integration/test_flask_integration.py +398 -0
- tests/test_integration/test_standalone_integration.py +493 -0
- tests/test_middleware/__init__.py +0 -0
- tests/test_middleware/test_fastapi_middleware.py +523 -0
- tests/test_middleware/test_flask_middleware.py +582 -0
- tests/test_middleware/test_security_middleware.py +493 -0
- tests/test_schemas/__init__.py +0 -0
- tests/test_schemas/test_config.py +811 -0
- tests/test_schemas/test_models.py +879 -0
- tests/test_schemas/test_responses.py +1054 -0
- tests/test_schemas/test_serialization.py +493 -0
- tests/test_utils/__init__.py +0 -0
- tests/test_utils/test_cert_utils.py +510 -0
- tests/test_utils/test_crypto_utils.py +603 -0
- tests/test_utils/test_validation_utils.py +477 -0
@@ -0,0 +1,250 @@
|
|
1
|
+
"""
|
2
|
+
MCP Security Framework Middleware Package
|
3
|
+
|
4
|
+
This package provides comprehensive security middleware implementations
|
5
|
+
for various web frameworks, including FastAPI, Flask, and others.
|
6
|
+
|
7
|
+
Key Features:
|
8
|
+
- Framework-agnostic base middleware
|
9
|
+
- Framework-specific implementations
|
10
|
+
- Specialized middleware components
|
11
|
+
- Factory functions for easy integration
|
12
|
+
- Comprehensive security processing
|
13
|
+
|
14
|
+
Modules:
|
15
|
+
security_middleware: Base security middleware class
|
16
|
+
fastapi_middleware: FastAPI-specific implementation
|
17
|
+
flask_middleware: Flask-specific implementation
|
18
|
+
auth_middleware: Authentication-only middleware
|
19
|
+
rate_limit_middleware: Rate limiting-only middleware
|
20
|
+
mtls_middleware: mTLS-specific middleware
|
21
|
+
|
22
|
+
Factory Functions:
|
23
|
+
create_fastapi_security_middleware: Create FastAPI security middleware
|
24
|
+
create_flask_security_middleware: Create Flask security middleware
|
25
|
+
create_auth_middleware: Create authentication-only middleware
|
26
|
+
create_rate_limit_middleware: Create rate limiting middleware
|
27
|
+
create_mtls_middleware: Create mTLS middleware
|
28
|
+
|
29
|
+
Author: MCP Security Team
|
30
|
+
Version: 1.0.0
|
31
|
+
License: MIT
|
32
|
+
"""
|
33
|
+
|
34
|
+
from typing import Optional
|
35
|
+
|
36
|
+
from .security_middleware import SecurityMiddleware, SecurityMiddlewareError
|
37
|
+
from .fastapi_middleware import FastAPISecurityMiddleware, FastAPIMiddlewareError
|
38
|
+
from .flask_middleware import FlaskSecurityMiddleware, FlaskMiddlewareError
|
39
|
+
from .auth_middleware import AuthMiddleware, AuthMiddlewareError
|
40
|
+
from .rate_limit_middleware import RateLimitMiddleware, RateLimitMiddlewareError
|
41
|
+
from .mtls_middleware import MTLSMiddleware, MTLSMiddlewareError
|
42
|
+
|
43
|
+
from ..core.security_manager import SecurityManager
|
44
|
+
from ..schemas.config import SecurityConfig
|
45
|
+
|
46
|
+
|
47
|
+
def create_fastapi_security_middleware(
|
48
|
+
security_manager: SecurityManager
|
49
|
+
) -> FastAPISecurityMiddleware:
|
50
|
+
"""
|
51
|
+
Create FastAPI security middleware.
|
52
|
+
|
53
|
+
Args:
|
54
|
+
security_manager (SecurityManager): Security manager instance
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
FastAPISecurityMiddleware: Configured FastAPI security middleware
|
58
|
+
|
59
|
+
Raises:
|
60
|
+
FastAPIMiddlewareError: If middleware creation fails
|
61
|
+
|
62
|
+
Example:
|
63
|
+
>>> from mcp_security_framework.middleware import create_fastapi_security_middleware
|
64
|
+
>>> from fastapi import FastAPI
|
65
|
+
>>>
|
66
|
+
>>> app = FastAPI()
|
67
|
+
>>> security_manager = SecurityManager(config)
|
68
|
+
>>> middleware = create_fastapi_security_middleware(security_manager)
|
69
|
+
>>> app.add_middleware(middleware)
|
70
|
+
"""
|
71
|
+
return FastAPISecurityMiddleware(security_manager)
|
72
|
+
|
73
|
+
|
74
|
+
def create_flask_security_middleware(
|
75
|
+
security_manager: SecurityManager
|
76
|
+
) -> FlaskSecurityMiddleware:
|
77
|
+
"""
|
78
|
+
Create Flask security middleware.
|
79
|
+
|
80
|
+
Args:
|
81
|
+
security_manager (SecurityManager): Security manager instance
|
82
|
+
|
83
|
+
Returns:
|
84
|
+
FlaskSecurityMiddleware: Configured Flask security middleware
|
85
|
+
|
86
|
+
Raises:
|
87
|
+
FlaskMiddlewareError: If middleware creation fails
|
88
|
+
|
89
|
+
Example:
|
90
|
+
>>> from mcp_security_framework.middleware import create_flask_security_middleware
|
91
|
+
>>> from flask import Flask
|
92
|
+
>>>
|
93
|
+
>>> app = Flask(__name__)
|
94
|
+
>>> security_manager = SecurityManager(config)
|
95
|
+
>>> middleware = create_flask_security_middleware(security_manager)
|
96
|
+
>>> app.wsgi_app = middleware(app.wsgi_app)
|
97
|
+
"""
|
98
|
+
return FlaskSecurityMiddleware(security_manager)
|
99
|
+
|
100
|
+
|
101
|
+
def create_auth_middleware(
|
102
|
+
security_manager: SecurityManager,
|
103
|
+
framework: str = "fastapi",
|
104
|
+
cache_ttl: int = 300
|
105
|
+
) -> AuthMiddleware:
|
106
|
+
"""
|
107
|
+
Create authentication-only middleware for specified framework.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
security_manager (SecurityManager): Security manager instance
|
111
|
+
framework (str): Target framework ("fastapi", "flask", "django")
|
112
|
+
cache_ttl (int): Cache TTL in seconds (default: 300)
|
113
|
+
|
114
|
+
Returns:
|
115
|
+
AuthMiddleware: Framework-specific authentication middleware
|
116
|
+
|
117
|
+
Raises:
|
118
|
+
ValueError: If framework is not supported
|
119
|
+
AuthMiddlewareError: If middleware creation fails
|
120
|
+
|
121
|
+
Example:
|
122
|
+
>>> from mcp_security_framework.middleware import create_auth_middleware
|
123
|
+
>>>
|
124
|
+
>>> security_manager = SecurityManager(config)
|
125
|
+
>>> auth_middleware = create_auth_middleware(security_manager, "fastapi")
|
126
|
+
"""
|
127
|
+
if framework == "fastapi":
|
128
|
+
from .fastapi_auth_middleware import FastAPIAuthMiddleware
|
129
|
+
return FastAPIAuthMiddleware(security_manager.config, security_manager)
|
130
|
+
elif framework == "flask":
|
131
|
+
from .flask_auth_middleware import FlaskAuthMiddleware
|
132
|
+
return FlaskAuthMiddleware(security_manager.config, security_manager)
|
133
|
+
else:
|
134
|
+
raise ValueError(f"Unsupported framework: {framework}")
|
135
|
+
|
136
|
+
|
137
|
+
def create_rate_limit_middleware(
|
138
|
+
security_manager: SecurityManager
|
139
|
+
) -> RateLimitMiddleware:
|
140
|
+
"""
|
141
|
+
Create rate limiting middleware.
|
142
|
+
|
143
|
+
Args:
|
144
|
+
security_manager (SecurityManager): Security manager instance
|
145
|
+
|
146
|
+
Returns:
|
147
|
+
RateLimitMiddleware: Configured rate limiting middleware
|
148
|
+
|
149
|
+
Raises:
|
150
|
+
RateLimitMiddlewareError: If middleware creation fails
|
151
|
+
|
152
|
+
Example:
|
153
|
+
>>> from mcp_security_framework.middleware import create_rate_limit_middleware
|
154
|
+
>>>
|
155
|
+
>>> security_manager = SecurityManager(config)
|
156
|
+
>>> rate_limit_middleware = create_rate_limit_middleware(security_manager)
|
157
|
+
"""
|
158
|
+
return RateLimitMiddleware(security_manager)
|
159
|
+
|
160
|
+
|
161
|
+
def create_mtls_middleware(
|
162
|
+
security_manager: SecurityManager
|
163
|
+
) -> MTLSMiddleware:
|
164
|
+
"""
|
165
|
+
Create mTLS middleware.
|
166
|
+
|
167
|
+
Args:
|
168
|
+
security_manager (SecurityManager): Security manager instance
|
169
|
+
|
170
|
+
Returns:
|
171
|
+
MTLSMiddleware: Configured mTLS middleware
|
172
|
+
|
173
|
+
Raises:
|
174
|
+
MTLSMiddlewareError: If middleware creation fails
|
175
|
+
|
176
|
+
Example:
|
177
|
+
>>> from mcp_security_framework.middleware import create_mtls_middleware
|
178
|
+
>>>
|
179
|
+
>>> security_manager = SecurityManager(config)
|
180
|
+
>>> mtls_middleware = create_mtls_middleware(security_manager)
|
181
|
+
"""
|
182
|
+
return MTLSMiddleware(security_manager)
|
183
|
+
|
184
|
+
|
185
|
+
def create_security_middleware(
|
186
|
+
security_manager: SecurityManager,
|
187
|
+
framework: str = "fastapi"
|
188
|
+
) -> SecurityMiddleware:
|
189
|
+
"""
|
190
|
+
Create security middleware for specified framework.
|
191
|
+
|
192
|
+
Args:
|
193
|
+
security_manager (SecurityManager): Security manager instance
|
194
|
+
framework (str): Target framework ("fastapi", "flask", etc.)
|
195
|
+
|
196
|
+
Returns:
|
197
|
+
SecurityMiddleware: Configured security middleware
|
198
|
+
|
199
|
+
Raises:
|
200
|
+
SecurityMiddlewareError: If middleware creation fails
|
201
|
+
|
202
|
+
Example:
|
203
|
+
>>> from mcp_security_framework.middleware import create_security_middleware
|
204
|
+
>>>
|
205
|
+
>>> security_manager = SecurityManager(config)
|
206
|
+
>>> middleware = create_security_middleware(security_manager, "fastapi")
|
207
|
+
"""
|
208
|
+
framework = framework.lower()
|
209
|
+
|
210
|
+
if framework == "fastapi":
|
211
|
+
return create_fastapi_security_middleware(security_manager)
|
212
|
+
elif framework == "flask":
|
213
|
+
return create_flask_security_middleware(security_manager)
|
214
|
+
else:
|
215
|
+
raise SecurityMiddlewareError(
|
216
|
+
f"Unsupported framework: {framework}",
|
217
|
+
error_code=-32041
|
218
|
+
)
|
219
|
+
|
220
|
+
|
221
|
+
# Export all middleware classes and exceptions
|
222
|
+
__all__ = [
|
223
|
+
# Base classes
|
224
|
+
"SecurityMiddleware",
|
225
|
+
"SecurityMiddlewareError",
|
226
|
+
|
227
|
+
# FastAPI middleware
|
228
|
+
"FastAPISecurityMiddleware",
|
229
|
+
"FastAPIMiddlewareError",
|
230
|
+
|
231
|
+
# Flask middleware
|
232
|
+
"FlaskSecurityMiddleware",
|
233
|
+
"FlaskMiddlewareError",
|
234
|
+
|
235
|
+
# Specialized middleware
|
236
|
+
"AuthMiddleware",
|
237
|
+
"AuthMiddlewareError",
|
238
|
+
"RateLimitMiddleware",
|
239
|
+
"RateLimitMiddlewareError",
|
240
|
+
"MTLSMiddleware",
|
241
|
+
"MTLSMiddlewareError",
|
242
|
+
|
243
|
+
# Factory functions
|
244
|
+
"create_fastapi_security_middleware",
|
245
|
+
"create_flask_security_middleware",
|
246
|
+
"create_auth_middleware",
|
247
|
+
"create_rate_limit_middleware",
|
248
|
+
"create_mtls_middleware",
|
249
|
+
"create_security_middleware",
|
250
|
+
]
|
@@ -0,0 +1,292 @@
|
|
1
|
+
"""
|
2
|
+
Authentication Middleware Module
|
3
|
+
|
4
|
+
This module provides specialized authentication-only middleware that
|
5
|
+
focuses solely on user authentication without authorization checks.
|
6
|
+
|
7
|
+
Key Features:
|
8
|
+
- Authentication-only processing
|
9
|
+
- Multiple authentication method support
|
10
|
+
- Authentication result caching
|
11
|
+
- Authentication event logging
|
12
|
+
- Framework-agnostic design
|
13
|
+
|
14
|
+
Classes:
|
15
|
+
AuthMiddleware: Authentication-only middleware
|
16
|
+
AuthMiddlewareError: Authentication middleware-specific error exception
|
17
|
+
|
18
|
+
Author: MCP Security Team
|
19
|
+
Version: 1.0.0
|
20
|
+
License: MIT
|
21
|
+
"""
|
22
|
+
|
23
|
+
import logging
|
24
|
+
from abc import ABC, abstractmethod
|
25
|
+
from typing import Any, Dict, List, Optional
|
26
|
+
|
27
|
+
from .security_middleware import SecurityMiddleware, SecurityMiddlewareError
|
28
|
+
from ..schemas.models import AuthResult
|
29
|
+
|
30
|
+
|
31
|
+
class AuthMiddlewareError(SecurityMiddlewareError):
|
32
|
+
"""Raised when authentication middleware encounters an error."""
|
33
|
+
|
34
|
+
def __init__(self, message: str, error_code: int = -32032):
|
35
|
+
self.message = message
|
36
|
+
self.error_code = error_code
|
37
|
+
super().__init__(self.message)
|
38
|
+
|
39
|
+
|
40
|
+
class AuthMiddleware(SecurityMiddleware):
|
41
|
+
"""
|
42
|
+
Authentication-Only Middleware Class
|
43
|
+
|
44
|
+
This class provides authentication-only middleware that focuses
|
45
|
+
solely on user authentication without performing authorization
|
46
|
+
checks. It's useful for scenarios where authentication and
|
47
|
+
authorization are handled separately.
|
48
|
+
|
49
|
+
The AuthMiddleware implements:
|
50
|
+
- Authentication-only request processing
|
51
|
+
- Multiple authentication method support
|
52
|
+
- Authentication result caching
|
53
|
+
- Authentication event logging
|
54
|
+
- Framework-agnostic design
|
55
|
+
|
56
|
+
Key Responsibilities:
|
57
|
+
- Process requests through authentication pipeline only
|
58
|
+
- Handle multiple authentication methods
|
59
|
+
- Cache authentication results for performance
|
60
|
+
- Log authentication events and failures
|
61
|
+
- Provide authentication status to downstream components
|
62
|
+
|
63
|
+
Attributes:
|
64
|
+
Inherits all attributes from SecurityMiddleware
|
65
|
+
_auth_cache (Dict): Cache for authentication results
|
66
|
+
_cache_ttl (int): Time-to-live for cached results
|
67
|
+
|
68
|
+
Example:
|
69
|
+
>>> from mcp_security_framework.middleware import AuthMiddleware
|
70
|
+
>>>
|
71
|
+
>>> security_manager = SecurityManager(config)
|
72
|
+
>>> auth_middleware = AuthMiddleware(security_manager)
|
73
|
+
>>> app.add_middleware(auth_middleware)
|
74
|
+
|
75
|
+
Note:
|
76
|
+
This middleware only handles authentication. Authorization
|
77
|
+
should be handled separately by other middleware or
|
78
|
+
application logic.
|
79
|
+
"""
|
80
|
+
|
81
|
+
def __init__(self, security_manager, cache_ttl: int = 300):
|
82
|
+
"""
|
83
|
+
Initialize Authentication-Only Middleware.
|
84
|
+
|
85
|
+
Args:
|
86
|
+
security_manager: Security manager instance containing
|
87
|
+
all security components and configuration.
|
88
|
+
cache_ttl (int): Time-to-live for cached authentication
|
89
|
+
results in seconds. Defaults to 300 seconds (5 minutes).
|
90
|
+
|
91
|
+
Raises:
|
92
|
+
AuthMiddlewareError: If initialization fails
|
93
|
+
"""
|
94
|
+
super().__init__(security_manager)
|
95
|
+
self.logger = logging.getLogger(f"{__name__}.{self.__class__.__name__}")
|
96
|
+
self._cache_ttl = cache_ttl
|
97
|
+
|
98
|
+
self.logger.info(
|
99
|
+
"Authentication middleware initialized",
|
100
|
+
extra={"cache_ttl": cache_ttl}
|
101
|
+
)
|
102
|
+
|
103
|
+
@abstractmethod
|
104
|
+
def __call__(self, request: Any, call_next: Any) -> Any:
|
105
|
+
"""
|
106
|
+
Process request through authentication middleware.
|
107
|
+
|
108
|
+
This method implements the authentication-only processing
|
109
|
+
pipeline, focusing solely on user authentication.
|
110
|
+
|
111
|
+
Args:
|
112
|
+
request: Framework-specific request object
|
113
|
+
call_next: Framework-specific call_next function
|
114
|
+
|
115
|
+
Returns:
|
116
|
+
Framework-specific response object
|
117
|
+
|
118
|
+
Raises:
|
119
|
+
AuthMiddlewareError: If authentication processing fails
|
120
|
+
"""
|
121
|
+
pass
|
122
|
+
|
123
|
+
def _authenticate_only(self, request: Any) -> AuthResult:
|
124
|
+
"""
|
125
|
+
Perform authentication-only processing.
|
126
|
+
|
127
|
+
This method handles authentication without authorization
|
128
|
+
checks, making it suitable for scenarios where auth and
|
129
|
+
authz are separated.
|
130
|
+
|
131
|
+
Args:
|
132
|
+
request: Framework-specific request object
|
133
|
+
|
134
|
+
Returns:
|
135
|
+
AuthResult: Authentication result with user information
|
136
|
+
|
137
|
+
Raises:
|
138
|
+
AuthMiddlewareError: If authentication process fails
|
139
|
+
"""
|
140
|
+
try:
|
141
|
+
if not self.config.auth.enabled:
|
142
|
+
return AuthResult(
|
143
|
+
is_valid=True,
|
144
|
+
status=AuthStatus.SUCCESS,
|
145
|
+
username="anonymous",
|
146
|
+
roles=[],
|
147
|
+
auth_method=None
|
148
|
+
)
|
149
|
+
|
150
|
+
# Check cache first
|
151
|
+
cache_key = self._get_cache_key(request)
|
152
|
+
if cache_key in self._auth_cache:
|
153
|
+
cached_result = self._auth_cache[cache_key]
|
154
|
+
if self._is_cache_valid(cached_result):
|
155
|
+
self.logger.debug(
|
156
|
+
"Using cached authentication result",
|
157
|
+
extra={"username": cached_result.username}
|
158
|
+
)
|
159
|
+
return cached_result
|
160
|
+
|
161
|
+
# Try each authentication method in order
|
162
|
+
for method in self.config.auth.methods:
|
163
|
+
auth_result = self._try_auth_method(request, method)
|
164
|
+
if auth_result.is_valid:
|
165
|
+
# Cache successful authentication result
|
166
|
+
self._cache_auth_result(cache_key, auth_result)
|
167
|
+
|
168
|
+
self.logger.info(
|
169
|
+
"Authentication successful",
|
170
|
+
extra={
|
171
|
+
"username": auth_result.username,
|
172
|
+
"auth_method": auth_result.auth_method,
|
173
|
+
"user_roles": auth_result.roles
|
174
|
+
}
|
175
|
+
)
|
176
|
+
return auth_result
|
177
|
+
|
178
|
+
# All authentication methods failed
|
179
|
+
self.logger.warning(
|
180
|
+
"All authentication methods failed",
|
181
|
+
extra={"auth_methods": self.config.auth.methods}
|
182
|
+
)
|
183
|
+
|
184
|
+
failed_result = AuthResult(
|
185
|
+
is_valid=False,
|
186
|
+
status=AuthStatus.FAILED,
|
187
|
+
username=None,
|
188
|
+
roles=[],
|
189
|
+
auth_method=None,
|
190
|
+
error_code=-32033,
|
191
|
+
error_message="All authentication methods failed"
|
192
|
+
)
|
193
|
+
|
194
|
+
# Cache failed result briefly to prevent repeated attempts
|
195
|
+
self._cache_auth_result(cache_key, failed_result, ttl=60)
|
196
|
+
return failed_result
|
197
|
+
|
198
|
+
except Exception as e:
|
199
|
+
self.logger.error(
|
200
|
+
"Authentication process failed",
|
201
|
+
extra={"error": str(e)},
|
202
|
+
exc_info=True
|
203
|
+
)
|
204
|
+
raise AuthMiddlewareError(
|
205
|
+
f"Authentication process failed: {str(e)}",
|
206
|
+
error_code=-32034
|
207
|
+
)
|
208
|
+
|
209
|
+
def _get_cache_key(self, request: Any) -> str:
|
210
|
+
"""
|
211
|
+
Generate cache key for authentication result.
|
212
|
+
|
213
|
+
Args:
|
214
|
+
request: Framework-specific request object
|
215
|
+
|
216
|
+
Returns:
|
217
|
+
str: Cache key for authentication result
|
218
|
+
"""
|
219
|
+
# Use a combination of IP and user agent for cache key
|
220
|
+
ip = self._get_rate_limit_identifier(request)
|
221
|
+
user_agent = self._get_user_agent(request)
|
222
|
+
return f"auth:{ip}:{user_agent}"
|
223
|
+
|
224
|
+
def _is_cache_valid(self, auth_result: AuthResult) -> bool:
|
225
|
+
"""
|
226
|
+
Check if cached authentication result is still valid.
|
227
|
+
|
228
|
+
Args:
|
229
|
+
auth_result (AuthResult): Cached authentication result
|
230
|
+
|
231
|
+
Returns:
|
232
|
+
bool: True if cache is valid, False otherwise
|
233
|
+
"""
|
234
|
+
# For now, assume cache is valid if it exists
|
235
|
+
# In a real implementation, you might check timestamps
|
236
|
+
return True
|
237
|
+
|
238
|
+
def _cache_auth_result(self, cache_key: str, auth_result: AuthResult, ttl: int = None) -> None:
|
239
|
+
"""
|
240
|
+
Cache authentication result.
|
241
|
+
|
242
|
+
Args:
|
243
|
+
cache_key (str): Cache key for the result
|
244
|
+
auth_result (AuthResult): Authentication result to cache
|
245
|
+
ttl (int): Time-to-live in seconds (optional)
|
246
|
+
"""
|
247
|
+
if ttl is None:
|
248
|
+
ttl = self._cache_ttl
|
249
|
+
|
250
|
+
# In a real implementation, you would store with timestamp
|
251
|
+
self._auth_cache[cache_key] = auth_result
|
252
|
+
|
253
|
+
def _clear_auth_cache(self) -> None:
|
254
|
+
"""Clear all cached authentication results."""
|
255
|
+
self._auth_cache.clear()
|
256
|
+
self.logger.info("Authentication cache cleared")
|
257
|
+
|
258
|
+
def _get_user_agent(self, request: Any) -> str:
|
259
|
+
"""
|
260
|
+
Get user agent from request.
|
261
|
+
|
262
|
+
Args:
|
263
|
+
request: Framework-specific request object
|
264
|
+
|
265
|
+
Returns:
|
266
|
+
str: User agent string
|
267
|
+
"""
|
268
|
+
# This should be implemented by framework-specific subclasses
|
269
|
+
return "unknown"
|
270
|
+
|
271
|
+
def _log_auth_event(self, event_type: str, auth_result: AuthResult,
|
272
|
+
request_details: Dict[str, Any]) -> None:
|
273
|
+
"""
|
274
|
+
Log authentication event.
|
275
|
+
|
276
|
+
Args:
|
277
|
+
event_type (str): Type of authentication event
|
278
|
+
auth_result (AuthResult): Authentication result
|
279
|
+
request_details (Dict[str, Any]): Request details
|
280
|
+
"""
|
281
|
+
self.logger.info(
|
282
|
+
f"Authentication event: {event_type}",
|
283
|
+
extra={
|
284
|
+
"event_type": event_type,
|
285
|
+
"username": auth_result.username,
|
286
|
+
"auth_method": auth_result.auth_method,
|
287
|
+
"is_valid": auth_result.is_valid,
|
288
|
+
"error_code": auth_result.error_code,
|
289
|
+
"error_message": auth_result.error_message,
|
290
|
+
**request_details
|
291
|
+
}
|
292
|
+
)
|