fix(backend/auth): Fix JWT token claim mapping for user ID
- Changed AuthService.GenerateJwtToken to use JWT standard claims: - JwtRegisteredClaimNames.Sub for user ID (instead of ClaimTypes.NameIdentifier) - JwtRegisteredClaimNames.Name for username - JwtRegisteredClaimNames.Email for email - JwtRegisteredClaimNames.UniqueName for additional username claim - Kept ClaimTypes.Role for role - Updated AuthController.GetCurrentUser to use JwtRegisteredClaimNames.Sub - Updated AdminController.DeleteUserAsync to use JwtRegisteredClaimNames.Sub This fixes the 401 error when calling /me after login. The issue was that tokens were being generated with ClaimTypes.NameIdentifier claim, but the JWT middleware doesn't automatically map this to a claim that can be found with User.FindFirst(). Using standard JWT claims (sub, name, email) ensures proper compatibility with ASP.NET Core's JWT authentication. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
c1e3c37843
commit
ef72cbea18
3 changed files with 18 additions and 6 deletions
|
|
@ -151,11 +151,14 @@ public class AuthService : IAuthService
|
||||||
|
|
||||||
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
|
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
|
||||||
|
|
||||||
|
// Use JWT standard claims for better compatibility
|
||||||
|
// "sub" = subject (user identifier), "name" = username, "email" = email, "role" = user role
|
||||||
var claims = new[]
|
var claims = new[]
|
||||||
{
|
{
|
||||||
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
|
new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()), // JWT standard: sub for subject/user ID
|
||||||
new Claim(ClaimTypes.Name, user.Username),
|
new Claim(JwtRegisteredClaimNames.Name, user.Username),
|
||||||
new Claim(ClaimTypes.Email, user.Email),
|
new Claim(JwtRegisteredClaimNames.Email, user.Email),
|
||||||
|
new Claim(JwtRegisteredClaimNames.UniqueName, user.Username), // Additional: unique name
|
||||||
new Claim(ClaimTypes.Role, user.Role) // Use user's actual role (User or Admin)
|
new Claim(ClaimTypes.Role, user.Role) // Use user's actual role (User or Admin)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ using GermanApp.Application.DTOs.Auth;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -114,7 +116,11 @@ public class AdminController : ControllerBase
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var adminUserId = int.Parse(User.FindFirst("nameid")?.Value ?? "0");
|
// Get admin user ID from JWT "sub" claim (standard JWT claim for subject/user ID)
|
||||||
|
var adminUserIdClaim = User.FindFirst(JwtRegisteredClaimNames.Sub) ?? User.FindFirst("sub");
|
||||||
|
if (adminUserIdClaim == null || !int.TryParse(adminUserIdClaim.Value, out var adminUserId) || adminUserId == 0)
|
||||||
|
return Unauthorized();
|
||||||
|
|
||||||
var result = await _adminService.DeleteUserAsync(userId, adminUserId, cancellationToken);
|
var result = await _adminService.DeleteUserAsync(userId, adminUserId, cancellationToken);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ using GermanApp.Application.DTOs.Auth;
|
||||||
using GermanApp.Application.Interfaces;
|
using GermanApp.Application.Interfaces;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
namespace GermanApp.Presentation.Controllers;
|
namespace GermanApp.Presentation.Controllers;
|
||||||
|
|
||||||
|
|
@ -85,8 +87,9 @@ public class AuthController : ControllerBase
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var userId = int.Parse(User.FindFirst("nameid")?.Value ?? "0");
|
// Get user ID from JWT "sub" claim (standard JWT claim for subject/user ID)
|
||||||
if (userId == 0)
|
var userIdClaim = User.FindFirst(JwtRegisteredClaimNames.Sub) ?? User.FindFirst("sub");
|
||||||
|
if (userIdClaim == null || !int.TryParse(userIdClaim.Value, out var userId) || userId == 0)
|
||||||
return Unauthorized();
|
return Unauthorized();
|
||||||
|
|
||||||
var user = await _authService.GetCurrentUserAsync(userId);
|
var user = await _authService.GetCurrentUserAsync(userId);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue