Правильный способ получения текущего идентификатора пользователя в ядре Entity Framework
Существует множество разных ответов для разных RC-ов ASP.NET Core о том, как получить идентификатор текущего пользователя. Я хотел задать здесь определенный вопрос. Обратите внимание, что project.json теперь имеет "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0"
С RC1 вы можете сделать что-то вроде этого:
using Microsoft.AspNet.Identity;
using System.Security.Claims;
User.GetUserId();
Но с недавно выпущенной версией EF Core, Microsoft.AspNet.Identity не является правильной версией.
Были предложения использовать UserManager, который, похоже, очень просто, чтобы получить зарегистрированного пользователя:
private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);
var user = await GetCurrentUserAsync();
var userId = user?.Id;
Другим методом, который я нашел, был:
private readonly UserManager<ApplicationUser> _userManager;
_userManager.GetUserId(User)
Итак, с помощью RTM и Core EF Core 1 для .NET Framework 1 со следующими библиотеками в project.json, каков правильный способ получить идентификатор текущего пользователя в системе?
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
Ответы
Ответ 1
Идентификатор ядра ASP.NET вводится через DI в startup.cs - как таковой вам просто нужно вводить UserManager через конструктор
UserManager<ApplicationUser> userManager
Затем вы можете использовать следующие методы
_userManager.GetUserId(User);
То, как он используется в примере веб-приложения при создании нового проекта ASP.NET Core 1 с индивидуальной учетной записью пользователя.
Ответ 2
Если вы получаете доступ к этому при работе с контроллером, то использование UserManager для получения идентификатора пользователя довольно неэффективно, поскольку вы делаете обратную поездку в базу данных. Если вы используете ClaimsIdentity, вы можете сделать что-то вроде этого, чтобы получить идентификатор пользователя:
var claimsIdentity = (ClaimsIdentity)this.User.Identity;
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
var userId = claim.Value;
Этот метод просто считывает идентификатор пользователя, который уже присутствует в файле cookie, который, в свою очередь, автоматически десериализуется и сохраняется в экземпляре ClaimsIdentity.
Я использую этот вспомогательный класс:
public static class UserHelpers
{
public static string GetUserId(this IPrincipal principal)
{
var claimsIdentity = (ClaimsIdentity)principal.Identity;
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
return claim.Value;
}
}
Таким образом, получение идентификатора пользователя становится:
var userId = this.User.GetUserId();
Если по какой-либо причине требуемое требование отсутствует в сборке Claims, вы можете легко добавить его при создании пользователя ClaimsIdentity:
public class ApplicaionUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
userIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, this.UserId));
return userIdentity;
}
}
Ответ 3
Ниже приведена более строгая версия других ответов.
var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;
Чтобы объяснить немного дальше, я хотел использовать самую основную форму аутентификации без каких-либо таблиц в базе данных, поэтому я выбрал этот вариант -
Использование аутентификации cookie без Идентификатора основного ядра ASP.NET из документации Core.
Чтобы получить эту работу, первым шагом является добавление сервисов в Startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = new PathString("/Account/Login/");
options.LogoutPath = new PathString("/Account/Logoff/");
options.AccessDeniedPath = new PathString("/Account/AccessDenied/");
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
services.ConfigureApplicationCookie(identityOptionsCookies =>
{
// See https://andrewlock.net/automatically-validating-anti-forgery-tokens-in-asp-net-core-with-the-autovalidateantiforgerytokenattribute/
identityOptionsCookies.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
Затем в AccountController в сообщении после ввода правильного идентификатора пользователя и пароля простейшая проверка подлинности на основе требований должна просто добавить идентификатор входа в качестве претензии, например.
var требует = новый список { new Claim (ClaimTypes.NameIdentifier, loginViewModel.Guid, ClaimValueTypes.String, эмитент), };
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal,
new AuthenticationProperties
{
ExpiresUtc = DateTime.UtcNow.AddMinutes(_cookieTimeoutInMinutes),
IsPersistent = true,
AllowRefresh = false
});
После завершения входа в систему вы можете получить идентификатор пользователя, как описано в одном вкладыше выше. См. Ответ от Milos Mrdovic выше для более подробных шагов.
var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;
Для получения дополнительной информации см. Авторизация на основе претензий.