HttpContext.User null与经过身份验证的用户?

时间:2018-04-25 15:07:50

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

所以我正在开发一个.net核心2项目,我们想要创建一个基本平台,我们可以将它用于未来的项目。对于登录,我们使用Identity。我们完成所有设置,用户可以成功登录并设置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);

1 个答案:

答案 0 :(得分:0)

您曾两次写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}")]