I'm trying to get the current User from the Context outside a controller in my Web API. I'm using the OpenIddict to authenticate users, so the authorization is made by tokens.
I have registered the HttpContextAcessor as a singleton in my Startup.cs:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
After that, I inject the HttpContexrAcessor in my hub, like this:
public class NotificationHub : Hub
{
private IHttpContextAccessor _contextAccessor;
private HttpContext _context { get { return _contextAccessor.HttpContext; } }
public NotificationHub(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public async Task JoinGroup()
{
Groups.Add(Context.ConnectionId, $"notification_{_context.User.Identity.Name}");
}
public void Send(JsonResult notification)
{
Clients.Client(Context.ConnectionId).sendNotification(notification);
}
}
The problem is that _context.User.Identity.Name is always null.
Is there some way to do that?
ClaimTypes. NameIdentifier gives the current user id, and ClaimTypes.Name gives the username.
You can create a method to get the current user : private Task<ApplicationUser> GetCurrentUserAsync() => _userManager. GetUserAsync(HttpContext. User);
HTTP context accessor. Finally, you can use the IHttpContextAccessor helper service to get the HTTP context in any class that is managed by the ASP.NET Core dependency injection system. This is useful when you have a common service that is used by your controllers.
In my case using .Net Core 2.0, where I needed to get the User Id outside the controller, in Application Service, I did the following:
in Startup.cs I added this line under ConfigureServices
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
I created the following class
public class UserResolverService
{
private readonly IHttpContextAccessor _httpContext;
private readonly UserManager<ApplicationUser> _userManager;
public UserResolverService(IHttpContextAccessor httpContext, UserManager<ApplicationUser> userManager)
{
_httpContext = httpContext;
_userManager = userManager;
}
public string GetUserId()
{
var userId = _userManager.GetUserId(_httpContext.HttpContext.User);
return userId;
}
}
In my Application Service class, I called the UserResolverService
public class MyApplicationService
{
private readonly ApplicationDbContext _context;
private readonly UserResolverService _userResolverService;
public MyApplicationService(ApplicationDbContext context, UserResolverService userResolverService)
{
_context = context;
_userResolverService = userResolverService;
}
public async Task Create(MyModel entity)
{
entity.CreatorUserId = _userResolverService.GetUserId();
_context.MyModel.Add(entity);
await _context.SaveChangesAsync();
}
}
Also, if you don't want to user the UserManager, you can simply make the UserResolverService class like this:
public class UserResolverService
{
private readonly IHttpContextAccessor _httpContext;
public UserResolverService(IHttpContextAccessor httpContext)
{
_httpContext = httpContext;
}
public string GetUserId()
{
var user = _httpContext?.HttpContext?.User as ClaimsPrincipal;
var userId = user.Claims.ElementAt(0).Value;
return userId;
}
}
Try this: https://msdn.microsoft.com/pt-br/library/system.threading.thread.currentprincipal(v=vs.110).aspx
System.Threading.Thread.CurrentPrincipal
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With