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);
}

有什么想法吗?

EDIT: Gerardo's response is on track but to get the actual "Id" of the user, this seems to work:

ClaimsPrincipal currentUser = this.User;
var currentUserID = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
222207 次浏览

如果您的代码是 在 MVC 控制器中:

public class MyController : Microsoft.AspNetCore.Mvc.Controller

Controller基类中,可以从 User属性获得 ClaimsPrincipal

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

您可以直接检查索赔(无需往返数据库) :

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

Other fields can be fetched from the database's User entity:

  1. 使用依赖注入获取用户管理器

    private UserManager<ApplicationUser> _userManager;
    
    
    //class constructor
    public MyController(UserManager<ApplicationUser> userManager)
    {
    _userManager = userManager;
    }
    
  2. And use it:

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

如果您的代码是一个服务类 ,那么您可以使用依赖注入来获得一个 IHttpContextAccessor,它允许您从 HttpContext 获得 User

    private IHttpContextAccessor _httpContextAccessor;


public MyClass(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}


private void DoSomething()
{
var user = _httpContextAccessor.Context?.User;
}

进去。NET Core 2.0用户作为底层继承控制器的一部分已经存在。只要像通常那样使用 User,或者传递给任何存储库代码。

[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; }

如果您使用的是轴承令牌授权,则上述示例不返回应用程序用户。

Instead, use this:

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

这在 apsnetcore 2.0中可以工作。没有在早期版本中尝试过。

对于上下文,我使用 ASP.NET Core 2 Web Application 模板创建了一个项目。然后,选择 Web 应用程序(MVC) ,然后点击更改身份验证按钮,并选择个人用户帐户。

这个模板为您构建了许多基础设施。在 Controller 文件夹中查找 ManageController

This ManageController class constructor requires this UserManager variable to populated:

private readonly UserManager<ApplicationUser> _userManager;

然后,查看该类中的[ HttpPost ] Index 方法。他们以这种方式获得当前用户:

var user = await _userManager.GetUserAsync(User);

作为附加说明,这是您希望将任何自定义字段更新到已添加到 AspNetUsers 表中的用户配置文件的位置。将字段添加到视图中,然后将这些值提交给 IndexViewModel,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();

我在 Controller 类中加入了类似的东西,它起作用了:

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

其中 userManager 是 Microsoft.AspNetCore.Identity. UserManager 类的一个实例(附带所有奇怪的设置)。

如果有人感兴趣的话,这招对我很管用。我有一个自定义 Identity,它使用 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;
}
private readonly UserManager<AppUser> _userManager;


public AccountsController(UserManager<AppUser> userManager)
{
_userManager = userManager;
}


[Authorize(Policy = "ApiUser")]
[HttpGet("api/accounts/GetProfile", Name = "GetProfile")]
public async Task<IActionResult> GetProfile()
{
var userId = ((ClaimsIdentity)User.Identity).FindFirst("Id").Value;
var user = await _userManager.FindByIdAsync(userId);


ProfileUpdateModel model = new ProfileUpdateModel();
model.Email = user.Email;
model.FirstName = user.FirstName;
model.LastName = user.LastName;
model.PhoneNumber = user.PhoneNumber;


return new OkObjectResult(model);
}