所以我正在开发一个 .net core 2 项目,我们希望在该项目中创建一个可用于 future 项目的基本平台。对于登录,我们使用 Identity。我们已经完成所有设置,用户可以成功登录并设置 cookie。出于某种原因,一旦我们调用 HttpContext.User,这将导致 null。我很确定它确实找到了一个身份,但这个身份是空的。我们已经检查了 cookie,它非常好,它有它的 token 。我们确实添加了 token 身份验证,但这不应该在设置 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());
}
这是 Controller 中用于获取用户的代码:
User _user = await _userManager.GetUserAsync(HttpContext.User);
以及我们用来登录用户的代码:
var result = await _signInManager.PasswordSignInAsync(model.Email,
model.Password, true, false);
最佳答案
您编写了两次 AddAuthentication
,一次用于 Cookie
,一次用于 JWT
并覆盖默认值。
只使用一次AddAuthentication
,并添加Cookie
和JWT
。
services.AddAuthentication(options =>
{
// set schema here
})
.AddCookie(config =>
{
//config cookie
})
.AddJwtBearer(config =>
{
//config jwt
});
现在您有两种身份验证方案,您必须选择要使用哪一种来验证您的请求
[授权(CookieAuthenticationDefaults.AuthenticationScheme)]
或
[授权(JwtBearerDefaults.AuthenticationScheme)]
或者两者兼而有之
[Authorize($"{CookieAuthenticationDefaults.AuthenticationScheme},{JwtBearerDefaults.AuthenticationScheme}")]
关于asp.net-core - HttpContext.User null 与经过身份验证的用户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50025679/