HttpContext.User 身份信息总是返回 null [英] HttpContext.User Identity information always return null

查看:35
本文介绍了HttpContext.User 身份信息总是返回 null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 .net 核心 3.1.6.关于这个有很多答案,我尝试了所有但每次都失败了.所以我创建了新的测试 MVC 项目并添加了身份验证.

I use .net core 3.1.6. There are lots of answer about this and I try all but failed each time. So I create new test MVC project and add authentication.

我尝试使用CurrentUserService"类并获取登录的用户信息.但是,每次我都得到空结果.

I try to use a "CurrentUserService" class and get logged user information. However, every each time I get null result.

我的startup.cs

My startup.cs

public void ConfigureServices(IServiceCollection services) {
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    services.AddHttpContextAccessor();
    services.AddScoped<ICurrentUserService, CurrentUserService>();

    services.AddControllersWithViews();
    services.AddRazorPages();


}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
    if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints => {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        endpoints.MapRazorPages();
    });
}

还有我的 CurrentUserService.cs

And my CurrentUserService.cs

public class CurrentUserService : ICurrentUserService {
    private IHttpContextAccessor _httpContextAccessor;
    public CurrentUserService(IHttpContextAccessor httpContextAccessor) {
        _httpContextAccessor = httpContextAccessor;
    //I add x for test purpose and there is no user information here.
        var x = _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
    }

    public string UserId {
        get {
            var userIdClaim = _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
            return userIdClaim;
        }
    }

    public bool IsAuthenticated => UserId != null;
}

ICurrentUser.cs

ICurrentUser.cs

public interface ICurrentUserService {
        string UserId { get; }
        bool IsAuthenticated { get; }
}

DbContext.cs

DbContext.cs

public class ApplicationDbContext : IdentityDbContext {
        private readonly ICurrentUserService _currentUserService;

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options) {
        }

        public ApplicationDbContext(
            DbContextOptions<ApplicationDbContext> options,
            ICurrentUserService currentUserService)
            : base(options) {
            _currentUserService = currentUserService;
        }
    }

调试屏幕截图:

推荐答案

HttpContext 仅在请求期间有效.Startup 中的 Configure 方法不是网络调用,而是,因此,没有 HttpContext.当 .NET Core 为对 Configure 的调用创建 ApplicationDbContext 类时,没有有效的上下文.

HttpContext is only valid during a request.The Configure method in Startup is not a web call and, as such, does not have a HttpContext. When .NET Core creates an ApplicationDbContext class for the call to Configure there is no valid context.

当您发送请求Home/Index时,您可以在控制器中获取HttpContext:

You could get the HttpContext in the controller when you send request Home/Index:

public class HomeController : Controller
{
    private IHttpContextAccessor _httpContextAccessor;

    public HomeController(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
        var x = _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); //get in the constructor
    }

    public IActionResult Index()
    {
        // you could also get in your method
        var x = _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
        return View();
    }
}

结果:

更新:

只有调用这个服务,才能得到数据:

Only if you call this service,then you could get the data:

public class HomeController : Controller
{
    private readonly ICurrentUserService _service;
    public HomeController(ICurrentUserService service)
    {
        _service = service;
    }

    public IActionResult Index()
    {
        var data = _service.UserId;
        return View();
    }
}

如果要获取中间件中的数据,请检查:

If you want to get the data in the middleware,please check:

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();
app.Use(async (context, next) =>
{
    await next.Invoke();
    var data = context.User.FindFirstValue(ClaimTypes.NameIdentifier);
});

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
    endpoints.MapRazorPages();
});

更新 2:

无论你用哪种方式创建ApplicationDbContext实例,除非你调用它,否则它无法单独获取服务.无论如何,你总是需要在下一个业务层调用服务.

No matter which way you create the ApplicationDbContext instance,it could not separately get the service unless you call it.Anyway,you always need to call the service in the next business layer.

简单的方法是创建一个新方法然后调用ApplicationDbContext:

The simple way is to create a new method then you call ApplicationDbContext:

1.ApplicationContext:

1.ApplicationContext:

public class ApplicationDbContext : IdentityDbContext
{
    private readonly ICurrentUserService _currentUserService;
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    public ApplicationDbContext(
        DbContextOptions<ApplicationDbContext> options,
        ICurrentUserService currentUserService)
        : base(options)
    {
        _currentUserService = currentUserService;

    }
    public string GetId()
    {
        var data = _currentUserService.UserId;
        return data;
    }
}

2.控制器:

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly ApplicationDbContext _context;
    public HomeController(ILogger<HomeController> logger, ApplicationDbContext context)
    {
        _context = context;
        _logger = logger;
    }

    public IActionResult Index()
    {
        var data = _context.GetId();
        return View();
    }
}

这篇关于HttpContext.User 身份信息总是返回 null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆