If you are in a controller context, you can access the current authenticated User. Take an article such as Get the current user, within an ApiController action, without passing the userID as a parameter .
However, if my controller calls a service (same assembly), but here I don't have the controller context.
What is the best way to actually get the authenticated user?
ASP.NET Core apps access HttpContext through the IHttpContextAccessor interface and its default implementation HttpContextAccessor. It's only necessary to use IHttpContextAccessor when you need access to the HttpContext inside a service.
Web API assumes that authentication happens in the host. For web-hosting, the host is IIS, which uses HTTP modules for authentication. You can configure your project to use any of the authentication modules built in to IIS or ASP.NET, or write your own HTTP module to perform custom authentication.
The authentication and authorization mechanism in such a site is simple. After the user logs into the website, a single database holding user information verifies their identity. A session is created on the server, and all subsequent requests use the session to identify the user without another login required.
The HttpContext encapsulates all the HTTP-specific information about a single HTTP request. When an HTTP request arrives at the server, the server processes the request and builds an HttpContext object. This object represents the request which your application code can use to create the response.
You can create an intermediate service to provide that functionality
public interface IPrincipalProvider {
IPrincipal User { get; }
}
public class WebApiPrincipalProvider : IPrincipalProvider {
public IPrincipal User {
get {
return HttpContext.Current != null
? HttpContext.Current.User
: null;
}
}
}
and inject it into the dependent service context
public class MyService : IService {
private readonly IPrincipalProvider provider;
public MyService(IPrincipalProvider provider) {
this.provider = provider;
}
public MyModel MyServiceMethod() {
var currentUser = provider.User;
var name = currentUser.Identity.Name;
//...use user....
return model;
}
}
Finally make sure abstraction and implementation are registered with DI container in composition root of main application so that when service is injected into controller it would also be able to access current request's user.
[Authorize]
public class MyController : ApiController {
public readonly IService service;
public MyController (IService service) {
this.service = service;
}
[HttpGet]
public IHttpActionResult MyGetActiom() {
var model = service.MyServiceMethod();
return Ok(model);
}
}
When Identity framework authenticates a user the user principal is then set for the current context.
If hosted in IIS you can tap into HttpContext
to access the user like in the example provided earlier. MVC and Web API basically do something similar to populate Controller.User
and ApiController.User
.
If self hosting there are other ways to access it.
That fact is that once authenticated, the user is available. Encapsulate it behind an abstraction and you can injected where ever it is needed outside of a controller.
Asp.net Core introduced something similar IHttpContextAccessor
which allowed service classes to access the current HttpContext
out side of controllers
public interface IHttpContextAccessor {
HttpContext HttpContext { get; }
}
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