Reputation: 39394
On an ASP.NET Core 2.2 controller I have the following:
var principal = this.User as ClaimsPrincipal;
var authenticated = this.User.Identity.IsAuthenticated;
var claims = this.User.Identities.FirstOrDefault().Claims;
var id = this.User.FindFirstValue(ClaimTypes.NameIdentifier);
I am able to check if the user is authenticated
and gets the claims
including id
.
How can I do the same outside of the Controller
where I do not have this.User
?
Upvotes: 10
Views: 7307
Reputation: 151594
You don't want to inject the IHttpContextAccessor
interface into a non-web service, because that gives it a dependency on ASP.NET Core, making it unusable outside the context of a web request.
Instead, resolve the user from within the controller or page you're in:
var user = await _userManager.FindByNameAsync(User.Identity!.Name);
// or by Id
var userId = User.FindFirst(Claims.UserId).Value;
var user = await _userManager.FindByIdAsync(userId);
Now you have an ApplicationUser
instance (or whatever you named your Identity user entity), which you can pass to the appropriate service:
await otherService.DoSomething(foo, bar, user);
Upvotes: 2
Reputation: 247123
Inject IHttpContextAccessor
interface into the target class. This will give access to the current User
via the HttpContext
This provides an opportunity to abstract this feature by creating a service to provide just the information you want (Which is the current logged in user)
public interface IUserService {
ClaimsPrincipal GetUser();
}
public class UserService : IUserService {
private readonly IHttpContextAccessor accessor;
public UserService(IHttpContextAccessor accessor) {
this.accessor = accessor;
}
public ClaimsPrincipal GetUser() {
return accessor?.HttpContext?.User as ClaimsPrincipal;
}
}
You need to setup IHttpContextAccessor
now in Startup.ConfigureServices
in order to be able to inject it:
services.AddHttpContextAccessor();
services.AddTransient<IUserService, UserService>();
and inject your service where needed.
It's important to note that
HttpContext
could be null. Just because you haveIHttpContextAccessor
, doesn't mean that you're going to actually be able to always get theHttpContext
. Importantly, the code where you're using this must be within the request pipeline in some way orHttpContext
will be null.
Credit @ChrisPratt via comment
Upvotes: 24