PROBLEM:
- Login returns JWT token with 'sub' claim
- /me endpoint tries to read user ID from JWT
- Gets 401 Unauthorized because user ID claim cannot be found
ROOT CAUSE:
ASP.NET Core JWT middleware automatically maps JWT standard claims to .NET claim types:
- JwtRegisteredClaimNames.Sub ('sub') -> ClaimTypes.NameIdentifier ('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier')
Controllers were looking for 'sub' or 'nameid' but JWT middleware creates the claim with the full URI.
SOLUTION:
Updated all controllers to use ClaimTypes.NameIdentifier with fallback to 'sub':
- AuthController.GetCurrentUser()
- AdminController.DeleteUserAsync()
- StoryController.GetUserId()
This ensures the user ID can be found regardless of how the JWT middleware maps the claims.
CHANGES:
- AuthService: Generates JWT tokens with JwtRegisteredClaimNames.Sub (JWT standard)
- AuthController: Uses ClaimTypes.NameIdentifier ?? 'sub' fallback
- AdminController: Uses ClaimTypes.NameIdentifier ?? 'sub' fallback
- StoryController: Uses ClaimTypes.NameIdentifier ?? 'sub' fallback
- LessonsEndpoints.cs: Added .RequireAuthorization() to all GET endpoints
- docs/features/admin-module.md: Updated acceptance criteria and requirements
- Added unit tests in JwtTokenValidationTests.cs to verify the fix
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>