2016-07-23 1 views
12

Существует множество различных ответов, которые можно найти здесь для разных RC-ов ASP.NET Core о том, как получить идентификатор текущего пользователя. Я хотел задать здесь определенный вопрос. Пожалуйста, обратите внимание, что project.json теперь имеет «Microsoft.AspNetCore.Identity.EntityFrameworkCore»: «1.0.0»Правильный способ получения текущего Идентификатора пользователя в Entity Framework Core

С RC1, вы могли бы сделать что-то вроде этого:

using Microsoft.AspNet.Identity; 
using System.Security.Claims; 

User.GetUserId(); 

Но с недавно выпущенной версии 1 из 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) 

Так с ASP. NET Core 1 RTM и EF Core 1 со следующими библиотеками в project.json, каков правильный способ получить идентификатор текущего пользователя?

"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0", 
"Microsoft.AspNetCore.Mvc": "1.0.0", 
+0

Пожалуйста, не ставьте теги под вопрос! http://stackoverflow.com/help/tagging – Tseng

ответ

11

ASP.NET Ядро Идентичность впрыскивается через DI в startup.cs - как таковой вы просто должны вводить UserManager

UserManager<ApplicationUser> userManager 

Вы можете использовать следующие в методах с помощью конструктора

_userManager.GetUserId(User); 

Так он используется в примере веб-приложения при создании нового проекта ASP.NET Core 1 с индивидуальной учетной записью пользователя.

16

Если вы обращаетесь к этим из жгутов контроллера, а затем с помощью UserManager, чтобы получить идентификатор пользователя довольно неэффективно, как вы делаете путешествие туда и обратно в базу данных. Если вы используете ClaimsIdentity, вы можете сделать что-то вроде этого, чтобы получить идентификатор пользователя:

var claimsIdentity = (ClaimsIdentity)this.User.Identity; 
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier); 
var userId = claim.Value; 

Этот метод просто считывает идентификатор пользователя, который уже присутствует в куки, который, в свою очередь, автоматически десериализованное и хранится в примере 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(); 

Если по какой-то причине требуется требование не присутствует в Претензии colleciton, вы можете легко добавить его при создании пользователя 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; 
    } 
} 
+0

im удивлен, что нет встроенного способа получить текущий идентификатор пользователя. Этот метод отличается от того, как работают или ведут себя старые Users.Identity.GetUserId()? – Reza

+0

Этот метод использует ту же основную логику, что и старый GetUserId. Разница заключается в том, что вы можете вызвать его непосредственно в объекте User вместо объекта User.Idenity. Проверьте этот ответ для сравнения http://stackoverflow.com/a/28520274/1396972. Я считаю, что причина, по которой они их удалили, связана с тем, что она была подана в ClaimsIdentity, что является нарушением LSP. –

+0

Используется для основного приложения asp.net в фреймворке 4.5.2. Добавление пакета nuget Microsoft.AspNet.Identity вызвало неоднозначность и конфликты с существующими ссылками на структуру. –

2

Ниже приведена более лаконичная версия других ответов выше.

var user = User.FindFirst(ClaimTypes.NameIdentifier).Value; 

Чтобы объяснить немного дальше, я хотел бы использовать самую основную форму аутентификации без каких-либо таблиц в базе данных, поэтому я выбрал этот - Using Cookie Authentication without ASP.NET Core Identity из документации 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 на пост обратно вступив действительный идентификатор пользователя и пароль, аутентификация простейшими Иски на основе заключается в том, чтобы просто добавить идентификатор входа в качестве претензии, например

вар претензии = новый список { новое требование (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; 

Дополнительную информацию см. Claims-Based Authorization.

+0

Done @PetterFriberg :). –

Смежные вопросы