ASP.NET Core Identity - get current user

前端 未结 7 638
灰色年华
灰色年华 2020-12-07 11:48

To get the currently logged in user in MVC5, all we had to do was:

using Microsoft.AspNet.Identity;
[Authorize]
public IHttpActionResult DoSomething() {
             


        
相关标签:
7条回答
  • 2020-12-07 12:33

    For context, I created a project using the ASP.NET Core 2 Web Application template. Then, select the Web Application (MVC) then hit the Change Authentication button and select Individual User accounts.

    There is a lot of infrastructure built up for you from this template. Find the ManageController in the Controllers folder.

    This ManageController class constructor requires this UserManager variable to populated:

    private readonly UserManager<ApplicationUser> _userManager;
    

    Then, take a look at the the [HttpPost] Index method in this class. They get the current user in this fashion:

    var user = await _userManager.GetUserAsync(User);
    

    As a bonus note, this is where you want to update any custom fields to the user Profile you've added to the AspNetUsers table. Add the fields to the view, then submit those values to the IndexViewModel which is then submitted to this Post method. I added this code after the default logic to set the email address and phone number:

    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();
    
    0 讨论(0)
  • 2020-12-07 12:37

    In .NET Core 2.0 the user already exists as part of the underlying inherited controller. Just use the User as you would normally or pass across to any repository code.

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

    This is where it inherits it from

    #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; }
    
    0 讨论(0)
  • 2020-12-07 12:39

    I have put something like this in my Controller class and it worked:

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

    where userManager is an instance of Microsoft.AspNetCore.Identity.UserManager class (with all weird setup that goes with it).

    0 讨论(0)
  • 2020-12-07 12:47
    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);
    }
    
    0 讨论(0)
  • 2020-12-07 12:49

    Just if any one is interested this worked for me. I have a custom Identity which uses int for a primary key so I overrode the GetUserAsync method

    Override GetUserAsync

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

    Get Identity User

    var user = await _userManager.GetUserAsync(User);
    

    If you are using a regular Guid primary key you don't need to override GetUserAsync. This is all assuming that you token is configured correctly.

    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;
    }
    
    0 讨论(0)
  • 2020-12-07 12:51

    Assuming your code is inside an MVC controller:

    public class MyController : Microsoft.AspNetCore.Mvc.Controller
    

    From the Controller base class, you can get the IClaimsPrincipal from the User property

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

    You can check the claims directly (without a round trip to the database):

    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. Get the user manager using dependency injection

      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;
      
    0 讨论(0)
提交回复
热议问题