问题引入:
通过【ASP.NET Core[源码分析篇] - 认证】这篇文章中,我们知道当请求通过认证模块时,会给当前的HttpContext赋予当前用户身份标识,我们在需要授权的控制器中打上[Authorize]授权标签,就可以在ControllerBase的User属性获取到基于声明的权限标识(ClaimsPrincipal)。
遗憾的是这只是针对Controller层面,很多场景下我们是需要在Service层乃至数据层获直接使用用户信息,这种情况我们就使用不了User了。
解决方案:
在Asp.net 4.x时代,我们通常的做法是通过HttpContext.Current获取当前请求的上下文进而获取到当前的User属性,所以问题的切入点在于我们如何获取当前的HttpContext上下文。
在我们的Aspnet Core应用中,系统是通过注入HttpContext的访问器对象IHttpContextAccessor来获取当前的HttpContext。
实现
首先我们需要在Startup的ConfigureServices方法中注册IHttpContextAccessor的实例
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); .... }
有了这个注册,我们封装一个方法从IHttpContextAccessor 的HttpContext中获取对应的ClaimsPrincipal,如下(这里面的原理在后面的认证授权文章将会讲解到,大概的原理是认证通过后,User是具有当前用户的身份标志的ClaimsPrincipal):
public class PrincipalAccessor : IPrincipalAccessor {
//没有通过认证的,User会为空 public ClaimsPrincipal Principal => _httpContextAccessor.HttpContext?.User; private readonly IHttpContextAccessor _httpContextAccessor; public PrincipalAccessor(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } } public interface IPrincipalAccessor { ClaimsPrincipal Principal { get; } }
在Startup的ConfigureServices方法中,我们一样把这个类也加入注册中
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IHttpContextAccessor, HttpContextAccessor&g