Принципал пользователя в Entity Framework Core DbContext - PullRequest
0 голосов
/ 01 ноября 2018

Я обновляю проект с .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. Но мне нужно получить эту информацию в основном из конструктора по умолчанию или как-нибудь лениво загрузить ее.

1 Ответ

0 голосов
/ 02 ноября 2018

С вашей настройкой у вас есть две настройки аутентификации. Итак, в вашей функции ConfigureServices в классе запуска вам нужно использовать что-то вроде следующего:

services.AddAuthentication().AddCookie().AddJwtBearer();

Не забудьте указать аутентификацию по умолчанию. Например, если вы хотите, чтобы аутентификация была куки-файлами по умолчанию, вы можете использовать это:

services.AddAuthentication("Cookies").AddCookie().AddJwtBearer();

Или чтобы код был безопаснее,

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie().AddJwtBearer();

В вашем классе запуска, в функции Configure, не забудьте добавить

app.UseAuthentication();

При аутентификации в контроллере вам нужно будет использовать имя схемы вместе с [Authorize], если вы не используете схему по умолчанию.

[Authorize(AuthenticationSchemes = "")]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...