User.FindFirst(ClaimTypes.NameIdentifier) doesn't retrieve anything

Asjad Butt 71 Reputation points
2022-09-19T14:10:45.663+00:00

I'm trying to make an update user endpoint and to get the user i use the return user.FindFirst(ClaimTypes.NameIdentifier)?.Value; method but when i call this my controller update user endpoint it doesnt return any value the user variable which it is assigned to is null after its execution and when i execute this method in post man the following error occurs

{
"statusCode": 500,
"message": "Value cannot be null. (Parameter 'entity')",
"details": " at Microsoft.EntityFrameworkCore.Utilities.Check.NotNullT\r\n at Microsoft.EntityFrameworkCore.DbContext.EntryTEntity\r\n at API.Repository.UserRepository.Update(AppUser user) in D:\Dating App\DatingAppAPI\API\API\Repository\UserRepository.cs:line 64\r\n at API.Controllers.UsersController.UpdateUser(MemberUpdateDto memberUpdateDto) in D:\Dating App\DatingAppAPI\API\API\Controllers\UsersController.cs:line 47\r\n at lambda_method13(Closure , Object )\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)\r\n at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)\r\n at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)\r\n at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)\r\n at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)\r\n at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)\r\n at API.MiddleWare.ExceptionMiddleware.InvokeAsync(HttpContext httpContext) in D:\Dating App\DatingAppAPI\API\API\MiddleWare\ExceptionMiddleware.cs:line 24"
}
242536-error-2.png242479-error-1.png

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,208 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,308 questions
{count} vote

4 answers

Sort by: Most helpful
  1. Michael Taylor 48,826 Reputation points
    2022-09-19T14:56:00.01+00:00

    Put a breakpoint in your controller on the line var user = . Debug the code and when the breakpoint is hit confirm what is in the object.

    Note that the user name in most auth systems is read by simply looking at User.Identity.Name. This should map to the user name.

    If you really want to use the claim then you need to be aware of how your identity system sets it. There are actually 2 different claims that can be used. NameIdentifier is generally an immutable ID (often a GUID) that uniquely represents the user. Name is the display-friendly version. They may both be set or not. It depends on your identity provider.


  2. Zhi Lv - MSFT 32,021 Reputation points Microsoft Vendor
    2022-09-20T09:27:44.68+00:00

    Hi @Asjad Butt ,

    First, try to use the online JWT token Decode tools to check whether the JWT token contains the claims or not? If not, the issue relates the token generate method, check your token service and the CreateToken method.

    Second, check the JWT token when using postman to call the API method, make sure it is correct.

    According to your description, I create a sample and using the following code to generate the token and add claims:

        [AllowAnonymous]  
        [HttpPost]  
        public IActionResult Login([FromBody] UserModel login)  
        {  
            IActionResult response = Unauthorized();  
            var user = AuthenticateUser(login);  
    
            if (user != null)  
            {  
                var tokenString = GenerateJSONWebToken(user);  
                response = Ok(new { token = tokenString });  
            }  
    
            return response;  
        }  
    
        private string GenerateJSONWebToken(UserModel userInfo)  
        {   
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));  
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);  
    
            var claims = new[] {  
                new Claim(JwtRegisteredClaimNames.Sub, userInfo.Username),  
                new Claim(JwtRegisteredClaimNames.Email, userInfo.EmailAddress),  
                new Claim("DateOfJoing", DateTime.Now.ToString()),  
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())  
            };  
    
            var token = new JwtSecurityToken(_config["Jwt:Issuer"],  
                _config["Jwt:Issuer"],  
                claims,  
                expires: DateTime.Now.AddMinutes(120),  
                signingCredentials: credentials);  
            return new JwtSecurityTokenHandler().WriteToken(token);  
        }  
    

    After generate the token, if we decode it, the result like this: we can see it contains the relate claims:

    242860-image.png

    Then use postman to call the API method with this token, the result like this: we can get the claims using the FindFirst method.

    242906-1.gif

    More detail information about the JWT Auth, see JWT Authentication In ASP.NET Core


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Dillion

    0 comments No comments

  3. Luis Fernando da Silva 0 Reputation points
    2023-09-14T11:10:03.78+00:00

    Confirm that the Controller have the [Authorize] annotation.

    0 comments No comments

  4. Vinay Kumar Suboji 0 Reputation points
    2024-03-04T14:29:34.95+00:00

    Hi. Asjad,i have got same error can I know howyou resolved it

    0 comments No comments