【问题标题】:HttpContext.User null with authenticated user?HttpContext.User null 与经过身份验证的用户?
【发布时间】:2018-04-26 14:06:22
【问题描述】:

所以我正在开发一个 .net core 2 项目,我们希望在该项目中创建一个可用于未来项目的基本平台。对于登录,我们使用身份。我们已经完成了所有设置,用户可以成功登录并设置 cookie。出于某种原因,一旦我们调用 HttpContext.User 这将导致 null。我很确定它确实找到了一个身份,但这个身份是空的。我们检查了 cookie,它非常好,它有它的令牌。我们确实添加了令牌身份验证,但这不应该在设置 cookie 时干扰 cookie 系统。

下面是 Startup.cs

public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<MyIdentityDbContext>(options => options
        .UseSqlServer("Data Source=PATH;Initial Catalog=DB;Persist Security Info=True;User ID=ID;Password=*******"));

        services.AddSingleton<IJwtFactory, JwtFactory>();

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        }).AddCookie();

        services.AddIdentity<User, IdentityRole>(options =>
        {
            options.SignIn.RequireConfirmedEmail = true;
            options.User.RequireUniqueEmail = false;
            options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
        })
    .AddEntityFrameworkStores<MyIdentityDbContext>()
    .AddDefaultTokenProviders();

        services.Configure<IISOptions>(options =>
        {
            options.ForwardClientCertificate = false;
        });

        var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));

        services.Configure<JwtIssuerOptions>(options =>
        {
            options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
            options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
            options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
        });

        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],

            ValidateAudience = true,
            ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],

            ValidateIssuerSigningKey = true,
            IssuerSigningKey = _signingKey,

            RequireExpirationTime = false,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.Zero
        };

        services
           .AddAuthentication(options =>
           {
               options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
               options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

           })
       .AddJwtBearer(cfg =>
       {
           cfg.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
           cfg.TokenValidationParameters = tokenValidationParameters;
           cfg.SaveToken = true;
       });

        services.Configure<IdentityOptions>(options =>
        {
            // Password settings
            options.Password.RequireDigit = true;
            options.Password.RequiredLength = 8;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireUppercase = true;
            options.Password.RequireLowercase = true;
            options.Password.RequiredUniqueChars = 6;

            // Lockout settings
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
            options.Lockout.MaxFailedAccessAttempts = 5;
            options.Lockout.AllowedForNewUsers = true;

            // User settings
            options.User.RequireUniqueEmail = true;
        });

        services.ConfigureApplicationCookie(options =>
        {
            // Cookie settings
            options.LoginPath = "/Account/Login"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
            options.LogoutPath = "/Account/Logout"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
            options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
            options.SlidingExpiration = true;
            options.Cookie = new CookieBuilder
            {
                HttpOnly = true,
                Name = "MyAuthToken",
                Path = "/",
                SameSite = SameSiteMode.Lax,
                SecurePolicy = CookieSecurePolicy.SameAsRequest
            };
        });


        services.AddAuthorization(options =>
        {
            options.AddPolicy("EmployeeOnly", policy => policy.RequireClaim("Employee"));
            options.AddPolicy("OwnerOnly", policy => policy.RequireClaim("Owner"));
            options.AddPolicy("AdminOnly", policy => policy.RequireClaim("Admin"));
            options.AddPolicy("ModeratorOnly", policy => policy.RequireClaim("Moderator"));
        });

        services.AddTransient<IEmailSender, EmailSender>();
        services.Configure<AuthMessageSenderOptions>(Configuration);

        services.AddMvc().AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
    }

这是控制器中用于获取用户的代码:

 User _user = await _userManager.GetUserAsync(HttpContext.User);

以及我们用来登录用户的代码:

var result = await _signInManager.PasswordSignInAsync(model.Email,
                    model.Password, true, false);

【问题讨论】:

    标签: asp.net-core asp.net-identity


    【解决方案1】:

    您写了两次AddAuthentication,一次是Cookie,一次是JWT,并覆盖默认值。

    只使用一次AddAuthentication 并添加CookieJWT

    services.AddAuthentication(options =>
    {
        // set schema here
    })
    .AddCookie(config =>
    {
        //config cookie
    })
    .AddJwtBearer(config =>
    {
        //config jwt
    });
    

    现在您有两种身份验证方案,您必须选择要使用哪一种来验证您的请求

    [Authorize(CookieAuthenticationDefaults.AuthenticationScheme)]

    [Authorize(JwtBearerDefaults.AuthenticationScheme)]

    甚至两者都有

    [Authorize($"{CookieAuthenticationDefaults.AuthenticationScheme},{JwtBearerDefaults.AuthenticationScheme}")]

    【讨论】:

    • 我可能已经快速将其标记为答案。所以这适用于 [Authorize] 身份验证。但是我的 HttpContext.User 仍然返回 null。我已将默认方案设置为 cookie 身份验证。它确实找到了一个身份,但它的属性都是空的..
    猜你喜欢
    • 2021-08-12
    • 1970-01-01
    • 2020-11-15
    • 2016-01-17
    • 1970-01-01
    • 2017-09-11
    • 2018-01-07
    • 2016-11-30
    • 1970-01-01
    相关资源
    最近更新 更多