Я обновляю проект с .NET 4.6 до .NET Core. Это веб-сайт ASP.NET MVC с WebAPI, который использует EntityFramework. Когда контроллер a (MVC или WebAPI) запускает DbContext, появляется код, который должен идентифицировать пользователя как ClaimsIdentity для проверки его утверждений. В предыдущем .NET это было наиболее надежно доступно в Thread.CurrentPrincipal, например так:
ClaimsIdentity identity = System.Threading.Thread.CurrentPrincipal.Identity as ClaimsIdentity;
IIRC, это был самый безопасный способ сделать это, поскольку вы могли исходить из разных контекстов - WebAPI или ASP.NET MVC.
В базовом решении .NET я пытался сделать Dependency Inject IHttpContextAccessor в конструктор, но пользователь на HttpContext не авторизован и не имеет претензий
ClaimsIdentity identity = httpContext.HttpContext.User.Identity;
// identity.IsAuthenticated == false. identity.Claims is empty.
Безопасность установлена в Startup.cs:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).
AddCookie(options =>
{
options.LoginPath = "/Login";
options.Cookie.HttpOnly = true;
}).
AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
var key = Configuration["Tokens:Key"];
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["Tokens:Issuer"],
ValidAudience = Configuration["Tokens:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key))
};
});
Пользователь входит на страницу просмотра MVC / Login, которая входит в систему с помощью файлов cookie, а также создает токен на предъявителя в другом запросе, который сохраняется на клиенте. После всего этого пользователь перенаправляется на домашнюю страницу.
Cookie Логин:
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = bIsPersistent });
Token Generation (вызывается из ajax, сохраняется в localalstorage до перенаправления)
var secretKey = Configuration["Tokens:Key"];
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey));
var creds = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256 );
var expires = DateTime.Now.AddHours(8);
var token = new JwtSecurityToken(
_config["Tokens:Issuer"],
_config["Tokens:Issuer"],
oAuthIdentity.Claims,
expires: expires,
signingCredentials: creds
);
ret = Ok(new { token = new JwtSecurityTokenHandler().WriteToken(token) });
После приземления на домашнюю страницу в WebApi выполняется вызов ajax с токеном-носителем (я вытащил токен-носитель из http-запроса и проверил подпись на jwt.io), и webapi заставляет DbContext быть экземпляр, и это где личность не действительна.
Это как если бы Идентичность не была должным образом передана в DbContext -
Как получить правильного пользователя или личность в DbContext?
Кроме того, в момент, когда мне это нужно, он находится в конструкции DbContext, которую я не могу контролировать с помощью Dependency Injection. Но мне нужно получить эту информацию в основном из конструктора по умолчанию или как-нибудь лениво загрузить ее.