[英]HttpContext.User Identity information always return null
我使用 .net 核心 3.1.6。 关于这个有很多答案,我每次都尝试但都失败了。 所以我创建了新的测试 MVC 项目并添加了身份验证。
我尝试使用“CurrentUserService”class 并获取登录的用户信息。 但是,每次我得到 null 结果。
我的启动.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
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
public interface ICurrentUserService {
string UserId { get; }
bool IsAuthenticated { get; }
}
数据库上下文.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
方法不是 web 调用,因此没有HttpContext
。 当 .NET 核心为调用Configure
创建ApplicationDbContext
class 时,没有有效的上下文。
当您发送请求Home/Index
时,您可以在 controller 中获取HttpContext
:
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();
}
}
更新:
只有调用此服务,才能获取数据:
public class HomeController : Controller
{
private readonly ICurrentUserService _service;
public HomeController(ICurrentUserService service)
{
_service = service;
}
public IActionResult Index()
{
var data = _service.UserId;
return View();
}
}
如果要获取中间件中的数据,请检查:
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
实例,除非你调用它,否则它无法单独获取服务。无论如何,你总是需要在下一个业务层调用服务。
简单的方法是创建一个新方法,然后调用 ApplicationDbContext:
1.应用上下文:
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.Controller:
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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.