Rasik
Rasik

Reputation: 2410

IHttpContextAccessor UserId is null

After referring to different questions in StackOverflow, and also following the accepted answer:

IHttpContextAccessor.HttpContext.User.Identity shows all null properties in CurrentUserService service

But still, I couldn't access the UserId from the IHttpContextAccessor, the value of UserId is null when I am trying to access:

var UserId = _currentUserService.UserId;

My CurrentUserService Looks:

 public class CurrentUserService : ICurrentUserService
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        public CurrentUserService(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        private bool _init = false;
        private string _userId;
        public string UserId
        {
            get
            {
                if (!_init)
                {
                    _userId = _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
                    _init = true;
                }
                return _userId;
            }
        }
        ///public string UserId { get { return _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); } }

        public bool IsAuthenticated => _httpContextAccessor.HttpContext.User.Identity.IsAuthenticated;

    }

When I am not logged in and trying to access the controller, it redirects to the login page. And after the login the value of _httpContextAccessor.HttpContext?.User are also being populated as shown in the image below:

enter image description here

Is there something I am missing or it is the problem from the framework by design?

An example where I am trying to invoke the UserId.

In View:

 <div class="row">
        <div class="col-md-12">
            <a asp-action="BorrowRequest" asp-controller="Book" asp-route-bookId="@Model.Id" class="btn btn-primary">
                Request for Borrow
            </a>
        </div>
 </div>

In Controller:

[HttpGet]
[Authorize]
public async Task<ActionResult> BorrowRequest(int bookId)
{
    try
    {
        var UserId = _currentUserService.UserId;

        await Task.Delay(200);
        return RedirectToAction(nameof(Index));
    }
    catch
    {
        return View();
    }
}

Upvotes: 1

Views: 879

Answers (1)

Rasik
Rasik

Reputation: 2410

Something was replacing the name for claims for the user id from ClaimTypes.NameIdentifier to sub, which is shown in the figure.

So, To not let Microsoft Identity override claim names I used:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); just before the app.UseAuthentication() in the API startup.

Referring: Why is ClaimTypes.NameIdentifier not mapping to 'sub'?

Upvotes: 2

Related Questions