IHttpContextAccessor.HttpContext.User.Identity显示CurrentUserService服务中的所有空属性 [英] IHttpContextAccessor.HttpContext.User.Identity shows all null properties in CurrentUserService service

查看:173
本文介绍了IHttpContextAccessor.HttpContext.User.Identity显示CurrentUserService服务中的所有空属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Jason Taylor的Clean Architecture模板,该模板使用NSwag自动创建一个TypeScript客户端(Angular),但是我不需要创建TS客户端,因此我的主要目标是将其替换为Razor Pages.我已经能够达到较高的要求,但是 CurrentUserService 遇到问题,每当实例化它时,都应该在此行中设置UserId:

I am trying to use Jason Taylor's Clean Architecture Template, this template uses NSwag to automatically create a TypeScript Client (Angular), but I don't need to create a TS client, so my main goal is to replace it with Razor Pages. I've been able to achieve this to a high grade, but I'm having trouble with the CurrentUserService whenever it gets instantiated it is supposed to set the UserId in this line:

UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);

这是完整的 CurrentUserService :

using CleanREC0.Application.Common.Interfaces;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;

namespace CleanREC0.WebUI.Services
{
    public class CurrentUserService : ICurrentUserService
    {
        public CurrentUserService(IHttpContextAccessor httpContextAccessor)
        {
            UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
        }

        public string UserId { get; }
    }
}

即使是HttpContext,第一次也为 null ,这很好,因为一切都已初始化,但是随后的调用始终在所有 httpContextAccessor.HttpContext上返回 null ..User.Identity 属性,用户可以显示 Identity ,但是其所有属性和声明均为 null 无结果,即使用户正确登录也是如此.

The first time even the HttpContext is null and that's fine, since everything is initializing, but the subsequent calls always return null on all of httpContextAccessor.HttpContext.User.Identity properties, The User Shows an Identity alright but all of it's properties and claims are null or Yield no results, even with a user properly logged on.

以下是我对模板所做的操作的列表:

Here is a list of things I've done to the template:

  • 摆脱了 NSwag 以及与 TypeScript 相关的所有内容
  • 摆脱了 IdentityServer
  • ApiAuthorizationDbContext 替换为 IdentityDbContext
  • Got rid of NSwag and everything TypeScript Related
  • Got rid of IdentityServer
  • Replaced ApiAuthorizationDbContext for IdentityDbContext

这是我的StartUp课:

This is my StartUp class:

public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment environment)
        {
            Configuration = configuration;
            Environment = environment;
        }

        public IConfiguration Configuration { get; }
        public IWebHostEnvironment Environment { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplication();
            services.AddInfrastructure(Configuration, Environment);    

            services.AddScoped<ICurrentUserService, CurrentUserService>();

            services.AddHttpContextAccessor();
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>(); //I have added this line on as suggested on other post, but made no difference.


            services.AddHealthChecks()
                .AddDbContextCheck<ApplicationDbContext>();

            services.AddRazorPages()
                .AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<IApplicationDbContext>());
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseCustomExceptionHandler();
            app.UseHealthChecks("/health");
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

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

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }

这是从 ConfigureServices 调用的 AddApplication :

public static IServiceCollection AddApplication(this IServiceCollection services)
        {
            services.AddAutoMapper(Assembly.GetExecutingAssembly());
            services.AddMediatR(Assembly.GetExecutingAssembly());
            services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPerformanceBehaviour<,>));
            services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestValidationBehavior<,>));

            return services;
        }

还有在那里被调用的 AddInfrastructure :

public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration, IWebHostEnvironment environment)
        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    configuration.GetConnectionString("DefaultConnection"), 
                    b => b.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName)));

            services.AddScoped<IApplicationDbContext>(provider => provider.GetService<ApplicationDbContext>());

            services.AddDefaultIdentity<ApplicationUser>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            if (environment.IsEnvironment("Test"))
            {

            }
            else
            {
                services.AddTransient<IDateTime, DateTimeService>();
                services.AddTransient<IIdentityService, IdentityService>();
                services.AddTransient<ICsvFileBuilder, CsvFileBuilder>();
            }

            services.AddAuthentication();

            return services;
        }

其他一切似乎都正常.在 Razor Page 级别, User 变量及其 Identity 包含所有预期的信息和声明.

Everything else seems to be working fine. At Razor Page level the User variable and it's Identity contain all expected information and claims.

我确定我缺少了什么,有人可以指出正确的方向吗?

I'm sure I'm missing something, can someone please point me in the right direction?

推荐答案

LinkedListT在评论中的链接使我朝着正确的方向前进.

LinkedListT's link in the comments got me in the right direction.

链接指向解释此问题的答案:

The link points to an answer which explains this:

在ASP.NET MVC框架下的HttpContext(因此控制器类为时未设置HttpContext.Session)可以按您预期的方式进行构造,但稍后它会设置(注入")ControllerBuilder类.

under the ASP.NET MVC framework, the HttpContext (and therefore HttpContext.Session) is not set when the controller class is contructed as you might expect, but it set ("injected") later by the ControllerBuilder class.

我正在使用的模板随附的 CurrentUserService 类尝试读取构造函数中的用户声明,因此我将代码移至该属性的getter,该属性执行到该属性的getter为止.实际使用时,所有的声明和属性都将被填充.

The CurrentUserService class that comes with the template I'm using tries to read the user claims in the constructor, so I moved the code to the property's getter, which executes until latter when the property is actually used, by then all claims and properties are well populated.

我的新 CurrentUserService 如下:

using CleanREC0.Application.Common.Interfaces;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;

namespace CleanREC0.WebUI.Services
{
    public class CurrentUserService : ICurrentUserService
    {
        private IHttpContextAccessor _httpContextAccessor;

        public CurrentUserService(IHttpContextAccessor httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

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

这篇关于IHttpContextAccessor.HttpContext.User.Identity显示CurrentUserService服务中的所有空属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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