Подтвердить что ты не робот

Идентификатор ядра ASP.NET - получить текущий пользователь

Чтобы получить вошедшего в систему пользователя в MVC5, нам нужно было всего лишь:

using Microsoft.AspNet.Identity;
[Authorize]
public IHttpActionResult DoSomething() {
    string currentUserId = User.Identity.GetUserId();
}

Теперь с ASP.NET Core я думал, что это должно работать, но выдает ошибку.

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Http;

private readonly UserManager<ApplicationUser> _userManager;
[HttpPost]
[Authorize]
public async Task<IActionResult> StartSession() {
    var curUser = await _userManager.GetUserAsync(HttpContext.User);
}

Есть идеи?

РЕДАКТИРОВАТЬ: ответ Gerardo находится на пути, но чтобы получить фактический "Id" пользователя, это похоже на работу:

ClaimsPrincipal currentUser = this.User;
var currentUserID = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
4b9b3361

Ответ 1

Предполагая, что ваш код находится внутри контроллера MVC:

public class MyController : Microsoft.AspNetCore.Mvc.Controller

В базовом классе Controller вы можете получить IClaimsPrincipal из свойства User

System.Security.Claims.ClaimsPrincipal currentUser = this.User;

Вы можете проверить претензии напрямую (без обратной поездки в базу данных):

bool IsAdmin = currentUser.IsInRole("Admin");
var id = _userManager.GetUserId(User); // Get user id:

Другие поля могут быть извлечены из базы данных Пользовательский объект:

  • Получить менеджеру пользователя с использованием инъекции зависимостей

    private UserManager<ApplicationUser> _userManager;
    
    //class constructor
    public MyController(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }
    
  • И используйте его:

    var user = await _userManager.GetUserAsync(User);
    var email = user.Email;
    

Ответ 2

Если вы используете Bearing Token Auth, приведенные выше примеры не возвращают пользователя приложения.

Вместо этого используйте это:

ClaimsPrincipal currentUser = this.User;
var currentUserName = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
ApplicationUser user = await _userManager.FindByNameAsync(currentUserName);

Это работает в apsnetcore 2.0. Не пробовал в более ранних версиях.

Ответ 3

В .NET Core 2.0 пользователь уже существует как часть базового унаследованного контроллера. Просто используйте пользователя как обычно или переходите к любому коду репозитория.

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme, Policy = "TENANT")]
[HttpGet("issue-type-selection"), Produces("application/json")]
public async Task<IActionResult> IssueTypeSelection()
{
    try
    {
        return new ObjectResult(await _item.IssueTypeSelection(User));
    }
    catch (ExceptionNotFound)
    {
        Response.StatusCode = (int)HttpStatusCode.BadRequest;
        return Json(new
        {
            error = "invalid_grant",
            error_description = "Item Not Found"
        });
    }
}

Вот откуда он наследует

#region Assembly Microsoft.AspNetCore.Mvc.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// C:\Users\BhailDa\.nuget\packages\microsoft.aspnetcore.mvc.core\2.0.0\lib\netstandard2.0\Microsoft.AspNetCore.Mvc.Core.dll
#endregion

using System;
using System.IO;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Routing;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNetCore.Mvc
{
    //
    // Summary:
    //     A base class for an MVC controller without view support.
    [Controller]
    public abstract class ControllerBase
    {
        protected ControllerBase();

        //
        // Summary:
        //     Gets the System.Security.Claims.ClaimsPrincipal for user associated with the
        //     executing action.
        public ClaimsPrincipal User { get; }

Ответ 4

Для контекста я создал проект, используя шаблон веб-приложения ASP.NET Core 2. Затем выберите веб-приложение (MVC), нажмите кнопку "Изменить аутентификацию" и выберите "Учетные записи отдельных пользователей".

Из этого шаблона для вас создано множество инфраструктур. Найдите ManageController в папке "Контроллеры".

Этот ManageController класса ManageController требует заполнения переменной UserManager:

private readonly UserManager<ApplicationUser> _userManager;

Затем взгляните на метод индекса [HttpPost] в этом классе. Они получают текущего пользователя таким образом:

var user = await _userManager.GetUserAsync(User);

В качестве бонуса, здесь вы хотите обновить любые настраиваемые поля для профиля пользователя, который вы добавили в таблицу AspNetUsers. Добавьте поля в представление, затем отправьте эти значения в IndexViewModel, который затем отправляется в этот метод Post. Я добавил этот код после логики по умолчанию, чтобы установить адрес электронной почты и номер телефона:

user.FirstName = model.FirstName;
user.LastName = model.LastName;
user.Address1 = model.Address1;
user.Address2 = model.Address2;
user.City = model.City;
user.State = model.State;
user.Zip = model.Zip;
user.Company = model.Company;
user.Country = model.Country;
user.SetDisplayName();
user.SetProfileID();

_dbContext.Attach(user).State = EntityState.Modified;
_dbContext.SaveChanges();

Ответ 5

Я поместил что-то вроде этого в моем классе контроллера, и это сработало:

IdentityUser user = await userManager.FindByNameAsync(HttpContext.User.Identity.Name);

где userManager - это экземпляр класса Microsoft.AspNetCore.Identity.UserManager (со всеми странными настройками, которые идут с ним).

Ответ 6

Просто, если кто-то заинтересован, это сработало для меня. У меня есть собственный идентификатор, который использует int для первичного ключа, поэтому я переопределил метод GetUserAsync

Переопределить GetUserAsync

public override Task<User> GetUserAsync(ClaimsPrincipal principal)
{
    var userId = GetUserId(principal);
    return FindByNameAsync(userId);
}

Получить личность пользователя

var user = await _userManager.GetUserAsync(User);

Если вы используете обычный первичный ключ Guid, вам не нужно переопределять GetUserAsync. Все это при условии, что ваш токен настроен правильно.

public async Task<string> GenerateTokenAsync(string email)
{
    var user = await _userManager.FindByEmailAsync(email);
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(_tokenProviderOptions.SecretKey);

    var userRoles = await _userManager.GetRolesAsync(user);
    var roles = userRoles.Select(o => new Claim(ClaimTypes.Role, o));

    var claims = new[]
    {
        new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
        new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString(CultureInfo.CurrentCulture)),
        new Claim(JwtRegisteredClaimNames.GivenName, user.FirstName),
        new Claim(JwtRegisteredClaimNames.FamilyName, user.LastName),
        new Claim(JwtRegisteredClaimNames.Email, user.Email),
    }
    .Union(roles);

    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(claims),
        Expires = DateTime.UtcNow.AddHours(_tokenProviderOptions.Expires),
        SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
    };

    var token = tokenHandler.CreateToken(tokenDescriptor);

    return Task.FromResult(new JwtSecurityTokenHandler().WriteToken(token)).Result;
}