如果您在控制器上下文中,则可以访问当前经过身份验证的用户。请参阅Get the current user, within an ApiController action, without passing the userID as a parameter等文章。
但是,如果我的控制器调用服务(同一个程序集),但在这里我没有控制器上下文。
实际获得经过身份验证的用户的最佳方式是什么?
答案 0 :(得分:9)
您可以创建一个中间服务来提供该功能
public interface IPrincipalProvider {
IPrincipal User { get; }
}
public class WebApiPrincipalProvider : IPrincipalProvider {
public IPrincipal User {
get {
return HttpContext.Current != null
? HttpContext.Current.User
: null;
}
}
}
并将其注入依赖服务上下文
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;
}
}
最后确保抽象和实现在主应用程序的组合根中注册DI容器,这样当服务注入控制器时,它也能够访问当前请求的用户。
[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);
}
}
当Identity Framework对用户进行身份验证时,将为当前上下文设置用户主体。
如果在IIS中托管,您可以使用HttpContext
来访问用户,就像之前提供的示例一样。 MVC和Web API基本上类似于填充Controller.User
和ApiController.User
。
如果自托管有其他方法可以访问它。
事实是,一旦经过身份验证,用户就可以使用。将其封装在抽象之后,您可以在控制器之外的任何地方注入。
Asp.net Core引入了类似的IHttpContextAccessor
,允许服务类访问控制器的当前HttpContext
侧
public interface IHttpContextAccessor {
HttpContext HttpContext { get; }
}