oua-auth 0.3.0__tar.gz

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.
Files changed (61) hide show
  1. oua_auth-0.3.0/LICENSE +21 -0
  2. oua_auth-0.3.0/MANIFEST.in +5 -0
  3. oua_auth-0.3.0/PKG-INFO +533 -0
  4. oua_auth-0.3.0/README.md +469 -0
  5. oua_auth-0.3.0/SECURITY.md +156 -0
  6. oua_auth-0.3.0/docs/README.md +49 -0
  7. oua_auth-0.3.0/docs/configuration.md +450 -0
  8. oua_auth-0.3.0/docs/index.md +83 -0
  9. oua_auth-0.3.0/docs/integration_guide.md +1110 -0
  10. oua_auth-0.3.0/docs/quick_reference.md +569 -0
  11. oua_auth-0.3.0/docs/security_best_practices.md +324 -0
  12. oua_auth-0.3.0/docs/troubleshooting.md +922 -0
  13. oua_auth-0.3.0/oua_auth/__init__.py +57 -0
  14. oua_auth-0.3.0/oua_auth/admin.py +231 -0
  15. oua_auth-0.3.0/oua_auth/apps.py +66 -0
  16. oua_auth-0.3.0/oua_auth/authentication.py +1015 -0
  17. oua_auth-0.3.0/oua_auth/backend.py +177 -0
  18. oua_auth-0.3.0/oua_auth/logging_init.py +58 -0
  19. oua_auth-0.3.0/oua_auth/logging_utils.py +481 -0
  20. oua_auth-0.3.0/oua_auth/management/__init__.py +1 -0
  21. oua_auth-0.3.0/oua_auth/management/commands/__init__.py +1 -0
  22. oua_auth-0.3.0/oua_auth/management/commands/clean_expired_tokens.py +42 -0
  23. oua_auth-0.3.0/oua_auth/middleware.py +700 -0
  24. oua_auth-0.3.0/oua_auth/migrations/0001_initial.py +46 -0
  25. oua_auth-0.3.0/oua_auth/migrations/0002_suspicious_activity_and_user_security.py +109 -0
  26. oua_auth-0.3.0/oua_auth/migrations/__init__.py +1 -0
  27. oua_auth-0.3.0/oua_auth/models.py +233 -0
  28. oua_auth-0.3.0/oua_auth/security_middleware.py +96 -0
  29. oua_auth-0.3.0/oua_auth/token_blacklist.py +78 -0
  30. oua_auth-0.3.0/oua_auth.egg-info/PKG-INFO +533 -0
  31. oua_auth-0.3.0/oua_auth.egg-info/SOURCES.txt +59 -0
  32. oua_auth-0.3.0/oua_auth.egg-info/dependency_links.txt +1 -0
  33. oua_auth-0.3.0/oua_auth.egg-info/not-zip-safe +1 -0
  34. oua_auth-0.3.0/oua_auth.egg-info/requires.txt +26 -0
  35. oua_auth-0.3.0/oua_auth.egg-info/top_level.txt +2 -0
  36. oua_auth-0.3.0/pyproject.toml +3 -0
  37. oua_auth-0.3.0/setup.cfg +4 -0
  38. oua_auth-0.3.0/setup.py +69 -0
  39. oua_auth-0.3.0/tests/__init__.py +1 -0
  40. oua_auth-0.3.0/tests/conftest.py +296 -0
  41. oua_auth-0.3.0/tests/settings.py +82 -0
  42. oua_auth-0.3.0/tests/test_admin.py +343 -0
  43. oua_auth-0.3.0/tests/test_admin_integration.py +195 -0
  44. oua_auth-0.3.0/tests/test_api_integration.py +412 -0
  45. oua_auth-0.3.0/tests/test_apps.py +110 -0
  46. oua_auth-0.3.0/tests/test_authentication.py +539 -0
  47. oua_auth-0.3.0/tests/test_authentication_admin.py +192 -0
  48. oua_auth-0.3.0/tests/test_authentication_extended.py +1029 -0
  49. oua_auth-0.3.0/tests/test_backend.py +290 -0
  50. oua_auth-0.3.0/tests/test_command_clean_expired_tokens.py +129 -0
  51. oua_auth-0.3.0/tests/test_integration.py +393 -0
  52. oua_auth-0.3.0/tests/test_logging.py +184 -0
  53. oua_auth-0.3.0/tests/test_logging_init.py +115 -0
  54. oua_auth-0.3.0/tests/test_logging_utils.py +241 -0
  55. oua_auth-0.3.0/tests/test_middleware.py +510 -0
  56. oua_auth-0.3.0/tests/test_middleware_integration.py +213 -0
  57. oua_auth-0.3.0/tests/test_security_middleware.py +137 -0
  58. oua_auth-0.3.0/tests/test_token_blacklist.py +341 -0
  59. oua_auth-0.3.0/tests/test_token_blacklist_memory.py +80 -0
  60. oua_auth-0.3.0/tests/test_user_security_profile.py +119 -0
  61. oua_auth-0.3.0/tests/urls.py +37 -0
oua_auth-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Organization Unified Access
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,5 @@
1
+ include LICENSE
2
+ include README.md
3
+ include SECURITY.md
4
+ recursive-include oua_auth *.py
5
+ recursive-include docs *.md
@@ -0,0 +1,533 @@
1
+ Metadata-Version: 2.4
2
+ Name: oua-auth
3
+ Version: 0.3.0
4
+ Summary: A Django authentication middleware package for integrating with OUA SSO server
5
+ Home-page: https://gitlab.com/lexnjugz/Organization_Unified_Access_Authentication
6
+ Author: Organization Unified Access
7
+ Author-email: alexmungai964@gmail.com
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Web Environment
10
+ Classifier: Framework :: Django
11
+ Classifier: Framework :: Django :: 3.2
12
+ Classifier: Framework :: Django :: 4.0
13
+ Classifier: Framework :: Django :: 4.1
14
+ Classifier: Framework :: Django :: 4.2
15
+ Classifier: Framework :: Django :: 5.0
16
+ Classifier: Framework :: Django :: 5.1
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Internet :: WWW/HTTP
24
+ Classifier: Topic :: Security
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Requires-Python: >=3.11
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: Django>=3.2
30
+ Requires-Dist: python-jose>=3.3.0
31
+ Requires-Dist: bleach>=5.0.0
32
+ Requires-Dist: requests>=2.25.0
33
+ Requires-Dist: djangorestframework>=3.12.0
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
36
+ Requires-Dist: pytest-django>=4.7.0; extra == "dev"
37
+ Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
38
+ Requires-Dist: pytest-mock>=3.14.0; extra == "dev"
39
+ Requires-Dist: PyJWT>=2.6.0; extra == "dev"
40
+ Requires-Dist: cryptography>=41.0.0; extra == "dev"
41
+ Requires-Dist: black>=24.2.0; extra == "dev"
42
+ Requires-Dist: isort>=5.12.0; extra == "dev"
43
+ Requires-Dist: flake8>=7.0.0; extra == "dev"
44
+ Requires-Dist: build>=1.0.3; extra == "dev"
45
+ Requires-Dist: twine>=5.0.0; extra == "dev"
46
+ Provides-Extra: test
47
+ Requires-Dist: pytest>=8.0.0; extra == "test"
48
+ Requires-Dist: pytest-django>=4.7.0; extra == "test"
49
+ Requires-Dist: pytest-cov>=4.1.0; extra == "test"
50
+ Requires-Dist: pytest-mock>=3.14.0; extra == "test"
51
+ Requires-Dist: PyJWT>=2.6.0; extra == "test"
52
+ Requires-Dist: cryptography>=41.0.0; extra == "test"
53
+ Dynamic: author
54
+ Dynamic: author-email
55
+ Dynamic: classifier
56
+ Dynamic: description
57
+ Dynamic: description-content-type
58
+ Dynamic: home-page
59
+ Dynamic: license-file
60
+ Dynamic: provides-extra
61
+ Dynamic: requires-dist
62
+ Dynamic: requires-python
63
+ Dynamic: summary
64
+
65
+ # Organization Unified Access Authentication
66
+
67
+ A Django authentication middleware package for integrating with OrganizationUnifiedAccess (OUA) SSO server.
68
+
69
+ ## Installation
70
+
71
+ ```bash
72
+ pip install oua-auth
73
+ ```
74
+
75
+ ## Configuration
76
+
77
+ Add the following settings to your Django settings.py:
78
+
79
+ ```python
80
+ # OUA SSO Settings
81
+ OUA_SSO_URL = 'https://your-sso-server.com' # Your OUA SSO server URL
82
+ OUA_PUBLIC_KEY = '''
83
+ -----BEGIN PUBLIC KEY-----
84
+ Your SSO public key here
85
+ -----END PUBLIC KEY-----
86
+ '''
87
+ OUA_CLIENT_ID = 'your-client-id' # Your client ID from OUA SSO
88
+
89
+ # Optional: Paths to exclude from authentication
90
+ OUA_EXCLUDE_PATHS = [
91
+ '/public/',
92
+ '/api/health/',
93
+ ]
94
+
95
+ # Security settings (recommended)
96
+ OUA_TRUSTED_ADMIN_DOMAINS = ['yourdomain.com'] # Domains allowed admin access
97
+ OUA_TRUSTED_ADMIN_EMAILS = ['admin@example.com'] # Specific emails allowed admin access
98
+ OUA_TOKEN_SIGNING_KEY = 'your-separate-signing-key' # For internal token generation
99
+ OUA_INTERNAL_TOKEN_LIFETIME = 3600 # 1 hour in seconds
100
+ OUA_REQUEST_TIMEOUT = 5 # Timeout for SSO requests in seconds
101
+ OUA_MAX_REQUESTS_PER_MINUTE = 60 # Rate limiting for SSO API requests
102
+ OUA_MAX_AUTH_FAILURES = 5 # Maximum number of authentication failures before rate limiting
103
+ OUA_AUTH_FAILURE_WINDOW = 300 # Time window for rate limiting (seconds)
104
+
105
+ # Rate limiting cache configuration (optional)
106
+ OUA_RATELIMIT_CACHE_PREFIX = "oua_auth_failure" # Prefix for cache keys
107
+ OUA_RATELIMIT_CACHE_TIMEOUT = 300 # Cache timeout for rate limit entries (seconds)
108
+
109
+ # User validation options (optional)
110
+ OUA_ALLOWED_DOMAINS = ['company.com', 'partner.org'] # Only these domains are allowed
111
+ OUA_RESTRICTED_DOMAINS = ['competitor.com', 'spam.org'] # These domains are blocked
112
+ OUA_REQUIRED_TOKEN_ATTRIBUTES = ['email', 'name', 'sub'] # Token must include these attributes
113
+
114
+ # Account locking (optional)
115
+ OUA_MAX_SUSPICIOUS_ACTIVITIES = 3 # Number of suspicious activities before account lock
116
+ OUA_SUSPICIOUS_ACTIVITY_WINDOW = 86400 # Time window for counting suspicious activities (seconds)
117
+ OUA_ACCOUNT_LOCK_DURATION = 86400 # How long accounts remain locked (seconds)
118
+ OUA_SUSPICIOUS_ACTIVITY_TYPES = [ # Activity types that count toward locking
119
+ 'token_reuse',
120
+ 'invalid_origin',
121
+ 'unusual_location',
122
+ 'multiple_failed_attempts'
123
+ ]
124
+
125
+ # Add the authentication backend
126
+ AUTHENTICATION_BACKENDS = [
127
+ 'oua_auth.OUAAuthBackend',
128
+ 'django.contrib.auth.backends.ModelBackend', # Optional: Keep Django's default backend
129
+ ]
130
+
131
+ # Add the middleware
132
+ MIDDLEWARE = [
133
+ # ... other middleware ...
134
+ 'oua_auth.OUAAuthMiddleware',
135
+ 'oua_auth.OUAUserMiddleware', # Optional: For user data sync
136
+ 'oua_auth.SecurityHeadersMiddleware', # Optional: For security headers
137
+ ]
138
+
139
+ # If using Django Rest Framework
140
+ REST_FRAMEWORK = {
141
+ 'DEFAULT_AUTHENTICATION_CLASSES': [
142
+ 'oua_auth.OUAJWTAuthentication',
143
+ 'rest_framework.authentication.SessionAuthentication', # Optional
144
+ ],
145
+ # ... other DRF settings
146
+ }
147
+ ```
148
+
149
+ ## Usage
150
+
151
+ ### Authentication Flow
152
+
153
+ 1. Your frontend obtains a JWT token from the OUA SSO server
154
+ 2. Include the token in the Authorization header for API requests:
155
+ ```
156
+ Authorization: Bearer <your-jwt-token>
157
+ ```
158
+ 3. The middleware will:
159
+ - Validate the JWT token
160
+ - Create/update the Django user based on the token claims
161
+ - Set request.user to the authenticated user
162
+ - Store the token and claims in request.oua_token and request.oua_claims
163
+ - Generate an internal token for added security
164
+
165
+ ### Protecting Views
166
+
167
+ Use Django's standard authentication decorators:
168
+
169
+ ```python
170
+ from django.contrib.auth.decorators import login_required
171
+
172
+ @login_required
173
+ def protected_view(request):
174
+ # Only authenticated users can access this view
175
+ return HttpResponse("Hello " + request.user.email)
176
+ ```
177
+
178
+ For class-based views:
179
+
180
+ ```python
181
+ from django.contrib.auth.mixins import LoginRequiredMixin
182
+
183
+ class ProtectedView(LoginRequiredMixin, View):
184
+ def get(self, request):
185
+ return HttpResponse("Hello " + request.user.email)
186
+ ```
187
+
188
+ ### Accessing Token Claims
189
+
190
+ The middleware stores the decoded JWT claims in the request:
191
+
192
+ ```python
193
+ def my_view(request):
194
+ if request.user.is_authenticated:
195
+ roles = request.oua_claims.get('roles', [])
196
+ if 'admin' in roles:
197
+ # Handle admin user
198
+ pass
199
+ ```
200
+
201
+ ### Using the Internal Token
202
+
203
+ For extra security, you can use the internal token for downstream services:
204
+
205
+ ```python
206
+ def api_call(request):
207
+ if request.user.is_authenticated:
208
+ # Use the internal token for internal service calls
209
+ internal_token = request.internal_token
210
+ response = requests.get(
211
+ 'https://your-internal-service.com/api/resource',
212
+ headers={"Authorization": f"Bearer {internal_token}"},
213
+ )
214
+ return JsonResponse(response.json())
215
+ ```
216
+
217
+ ### Token Blacklisting
218
+
219
+ This package includes persistent token blacklisting to revoke access for specific tokens:
220
+
221
+ ```python
222
+ from oua_auth import OUAJWTAuthentication
223
+
224
+ def logout_user(request):
225
+ """Revoke the current user's token and log them out."""
226
+ if hasattr(request, 'oua_token'):
227
+ # Blacklist the token
228
+ OUAJWTAuthentication.revoke_token(
229
+ token=request.oua_token,
230
+ blacklisted_by=request.user.email,
231
+ reason="User logout"
232
+ )
233
+
234
+ # Continue with standard Django logout
235
+ from django.contrib.auth import logout
236
+ logout(request)
237
+ return redirect('login')
238
+
239
+ def admin_revoke_token(request, user_id, token_id):
240
+ """Admin functionality to revoke a specific user's token."""
241
+ if not request.user.is_staff:
242
+ return HttpResponseForbidden()
243
+
244
+ # Get the token from your token storage
245
+ token = get_token_by_id(token_id)
246
+
247
+ # Blacklist it
248
+ OUAJWTAuthentication.revoke_token(
249
+ token=token,
250
+ blacklisted_by=f"Admin: {request.user.email}",
251
+ reason=f"Admin revocation for user {user_id}"
252
+ )
253
+
254
+ return JsonResponse({"status": "success"})
255
+ ```
256
+
257
+ The token blacklist is stored in the database using the `BlacklistedToken` model. Make sure to include `oua_auth` in your `INSTALLED_APPS` setting:
258
+
259
+ ```python
260
+ INSTALLED_APPS = [
261
+ # ... other apps ...
262
+ 'oua_auth',
263
+ # ... other apps ...
264
+ ]
265
+ ```
266
+
267
+ After adding the app, run migrations to create the token blacklist table:
268
+
269
+ ```bash
270
+ python manage.py migrate oua_auth
271
+ ```
272
+
273
+ The blacklist automatically cleans up expired tokens during validation checks to prevent database growth. You can also set up a periodic task to clean expired tokens:
274
+
275
+ ```python
276
+ from django.core.management.base import BaseCommand
277
+ from oua_auth.models import BlacklistedToken
278
+
279
+ class Command(BaseCommand):
280
+ help = 'Clean expired tokens from the blacklist'
281
+
282
+ def handle(self, *args, **options):
283
+ count = BlacklistedToken.clean_expired_tokens()
284
+ self.stdout.write(self.style.SUCCESS(f'Removed {count} expired tokens from blacklist'))
285
+ ```
286
+
287
+ ### Security Headers Middleware
288
+
289
+ The package includes a security headers middleware that adds recommended HTTP security headers to all responses:
290
+
291
+ ```python
292
+ # Add the middleware to your MIDDLEWARE setting
293
+ MIDDLEWARE = [
294
+ # ... other middleware ...
295
+ 'oua_auth.SecurityHeadersMiddleware',
296
+ ]
297
+
298
+ # Optional: Configure security headers (these are the defaults)
299
+ OUA_CONTENT_SECURITY_POLICY = "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'"
300
+ OUA_FRAME_OPTIONS = "SAMEORIGIN" # X-Frame-Options
301
+ OUA_XSS_PROTECTION = "1; mode=block" # X-XSS-Protection
302
+ OUA_CONTENT_TYPE_OPTIONS = "nosniff" # X-Content-Type-Options
303
+ OUA_REFERRER_POLICY = "strict-origin-when-cross-origin"
304
+ OUA_PERMISSIONS_POLICY = "geolocation=(), microphone=(), camera=(), payment=()"
305
+
306
+ # HSTS is disabled by default; enable and configure if your site uses HTTPS
307
+ OUA_ENABLE_HSTS = False # Set to True to enable HSTS
308
+ OUA_HSTS_SECONDS = 31536000 # 1 year
309
+ OUA_HSTS_INCLUDE_SUBDOMAINS = True
310
+ OUA_HSTS_PRELOAD = False
311
+
312
+ # Exclude paths from security headers (optional)
313
+ OUA_SECURITY_HEADERS_EXCLUDE_PATHS = ['/api/public/', '/healthcheck/']
314
+ ```
315
+
316
+ This middleware helps protect against common web vulnerabilities:
317
+
318
+ - **Content Security Policy (CSP)**: Controls what resources can be loaded
319
+ - **X-Frame-Options**: Protects against clickjacking
320
+ - **X-XSS-Protection**: Enables browser's XSS filtering
321
+ - **X-Content-Type-Options**: Prevents MIME-type sniffing
322
+ - **Referrer-Policy**: Controls what information is sent in the Referer header
323
+ - **Permissions-Policy**: Restricts which browser features can be used
324
+ - **HTTP Strict Transport Security (HSTS)**: Forces secure connections
325
+
326
+ ## Security Features
327
+
328
+ This package implements several security measures:
329
+
330
+ - **JWT Token Security**: RSA256 signature verification, expiration validation
331
+ - **Privilege Protection**: Admin roles only granted to trusted email domains/addresses
332
+ - **Input Validation**:
333
+ - Email format validation
334
+ - XSS protection using the `bleach` library to sanitize all user inputs
335
+ - HTML tag stripping and attribute filtering
336
+ - Input length limitations to prevent DoS attacks
337
+ - **Network Security**: HTTPS enforcement, connection pooling, timeout controls
338
+ - **Internal Tokens**: Separate signing key, unique token IDs, expiration control
339
+ - **Distributed Rate Limiting**:
340
+ - Cache-based tracking of authentication failures
341
+ - IP-based rate limiting that works across multiple servers/instances
342
+ - Configurable thresholds and time windows
343
+ - Automatic cleanup of old failure records
344
+ - **Token Blacklisting**: Persistent revocation of compromised tokens
345
+ - **Security Headers**: Protection against XSS, CSRF, clickjacking and other web vulnerabilities
346
+ - **Structured Logging**: Sanitized logging with sensitive data redaction
347
+ - **User Validation Rules**:
348
+ - Domain allowlisting and blocklisting for all users (not just admins)
349
+ - Required token attributes validation
350
+ - Automatic account locking after suspicious activity
351
+ - **Suspicious Activity Monitoring**:
352
+ - Tracking and logging of suspicious authentication activities
353
+ - Automatic account locking based on configurable thresholds
354
+ - Protection against brute force, token reuse, and unusual access patterns
355
+
356
+ See [SECURITY.md](SECURITY.md) for more details on security features and vulnerability reporting.
357
+
358
+ ### User Validation and Security Configuration
359
+
360
+ The package includes enhanced user validation to control access and detect potentially malicious activities:
361
+
362
+ ```python
363
+ # Domain Restrictions (Optional)
364
+ OUA_ALLOWED_DOMAINS = ['company.com', 'partner.org'] # Only these domains can access
365
+ OUA_RESTRICTED_DOMAINS = ['competitor.com'] # These domains are blocked
366
+
367
+ # Token Attribute Requirements (Optional)
368
+ OUA_REQUIRED_TOKEN_ATTRIBUTES = ['email', 'name', 'sub', 'groups']
369
+
370
+ # Account Locking Configuration
371
+ OUA_MAX_SUSPICIOUS_ACTIVITIES = 3 # Activities before locking
372
+ OUA_SUSPICIOUS_ACTIVITY_WINDOW = 86400 # 24 hour window
373
+ OUA_ACCOUNT_LOCK_DURATION = 86400 # Lock for 24 hours
374
+ ```
375
+
376
+ These features provide several important security benefits:
377
+
378
+ 1. **Domain Control**: Limit access to specific trusted domains or block known malicious domains
379
+ 2. **Token Validation**: Ensure tokens contain all required claims for your application's needs
380
+ 3. **Suspicious Activity Detection**: Identify and respond to unusual authentication patterns
381
+ 4. **Account Protection**: Automatically lock accounts when suspicious behavior is detected
382
+ 5. **Audit Trail**: Track all security events for compliance and forensic analysis
383
+
384
+ All security events are logged in a structured format and can be reviewed in the Django admin interface or forwarded to security information and event management (SIEM) systems.
385
+
386
+ ### Rate Limiting Configuration
387
+
388
+ The package includes a distributed rate limiting system that uses Django's cache framework to prevent brute force attacks:
389
+
390
+ ```python
391
+ # Rate Limiting Configuration (add to your settings.py)
392
+ OUA_MAX_AUTH_FAILURES = 5 # Maximum authentication failures before rate limiting
393
+ OUA_AUTH_FAILURE_WINDOW = 300 # Time window for counting failures (seconds)
394
+
395
+ # Cache backend settings (optional)
396
+ OUA_RATELIMIT_CACHE_PREFIX = "oua_auth_failure" # Prefix for cache keys
397
+ OUA_RATELIMIT_CACHE_TIMEOUT = 300 # Cache entry timeout (seconds)
398
+ ```
399
+
400
+ For optimal security in production environments, configure Django's cache framework with a distributed backend:
401
+
402
+ ```python
403
+ # Example: Redis cache backend (requires django-redis)
404
+ CACHES = {
405
+ "default": {
406
+ "BACKEND": "django_redis.cache.RedisCache",
407
+ "LOCATION": "redis://redis:6379/1",
408
+ "OPTIONS": {
409
+ "CLIENT_CLASS": "django_redis.client.DefaultClient",
410
+ }
411
+ }
412
+ }
413
+
414
+ # Example: Memcached backend
415
+ CACHES = {
416
+ 'default': {
417
+ 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
418
+ 'LOCATION': '127.0.0.1:11211',
419
+ }
420
+ }
421
+ ```
422
+
423
+ The rate limiting system:
424
+
425
+ - Tracks authentication failures by client IP address
426
+ - Blocks access after too many failed attempts
427
+ - Works across multiple server instances
428
+ - Automatically expires old failure records
429
+ - Provides detailed logging for security monitoring
430
+
431
+ ### Structured Logging Configuration
432
+
433
+ The package includes a comprehensive logging system with structured log output and sensitive data redaction:
434
+
435
+ ```python
436
+ # Logging Configuration (add to your settings.py)
437
+ OUA_LOG_LEVEL = "INFO" # Global log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
438
+ OUA_CONSOLE_LOG_LEVEL = "INFO" # Console-specific log level
439
+ OUA_FILE_LOG_LEVEL = "DEBUG" # File-specific log level
440
+ OUA_LOG_FILE = "/var/log/django/oua_auth.log" # Log file path (None for no file logging)
441
+ OUA_LOG_JSON = True # Output logs in JSON format for log aggregation systems
442
+ OUA_LOG_CONSOLE = True # Output logs to console
443
+ OUA_EAGER_LOGGING = False # Configure logging during import (vs. Django app initialization)
444
+ ```
445
+
446
+ The logging system provides:
447
+
448
+ - **Structured JSON Output**: For better integration with log management systems like ELK, Splunk, or Graylog
449
+ - **Sensitive Data Redaction**: Automatically redacts tokens, passwords and other sensitive information
450
+ - **Contextual Information**: Includes request IDs, user information, and process details for easier debugging
451
+ - **Configurable Verbosity**: Control log level globally or per output channel
452
+ - **File Rotation**: Automatically rotates log files to prevent disk space issues
453
+
454
+ You can use the built-in logging utilities in your own code:
455
+
456
+ ```python
457
+ from oua_auth import setup_logging
458
+
459
+ # Create a logger for your module
460
+ logger = setup_logging(__name__)
461
+
462
+ # Log with context data
463
+ logger.info("User action completed", extra={"user_id": user.id, "action": "login"})
464
+
465
+ # Create a logger with default context
466
+ user_logger = logger.with_context(user_id=user.id, user_email=user.email)
467
+ user_logger.info("Profile updated") # Will include user context automatically
468
+
469
+ # Use decorator to log requests (with timing)
470
+ from oua_auth import log_request
471
+
472
+ @log_request()
473
+ def my_view(request):
474
+ # Request start and end will be logged automatically with timing
475
+ return HttpResponse("Hello World")
476
+ ```
477
+
478
+ The structured logs include consistent fields that make it easy to filter and analyze:
479
+
480
+ - **level**: Log level (INFO, WARNING, ERROR, etc.)
481
+ - **time**: ISO-8601 timestamp with timezone
482
+ - **message**: The log message
483
+ - **module**: Source module name
484
+ - **function**: Source function name
485
+ - **line**: Source line number
486
+ - **request_id**: Unique identifier for the request (for correlation)
487
+ - **user_id**: User ID if available
488
+ - **ip_address**: Client IP address if available
489
+ - **component**: Component name (e.g., "authentication", "middleware")
490
+ - **extra**: Additional context-specific information
491
+
492
+ ## Features
493
+
494
+ - JWT token validation
495
+ - Automatic user creation and updates
496
+ - Role-based authorization with security controls
497
+ - User data synchronization with SSO server
498
+ - Path-based authentication exclusion
499
+ - Django admin integration
500
+ - Django Rest Framework support
501
+
502
+ ## Contributing
503
+
504
+ Contributions are welcome! Please feel free to submit a Pull Request.
505
+
506
+ ## Testing
507
+
508
+ The package includes a comprehensive test suite to ensure its functionality and security:
509
+
510
+ ```bash
511
+ # Install test dependencies
512
+ pip install -e ".[test]"
513
+
514
+ # Run the test suite
515
+ python -m pytest
516
+
517
+ # Run tests with coverage report
518
+ python -m pytest --cov=oua_auth --cov-report=term-missing
519
+ ```
520
+
521
+ The test suite covers:
522
+
523
+ - JWT token validation and verification
524
+ - User creation and updates
525
+ - Admin privilege management
526
+ - Error handling
527
+ - Security features
528
+
529
+ See [tests/README.md](tests/README.md) for more details on the test suite.
530
+
531
+ ## License
532
+
533
+ This project is licensed under the MIT License - see the LICENSE file for details.