How get current user in asp.net core

2019-01-06 12:28发布

问题:

I want to get current user for getting information of user such as email. But i cant do that in asp.net core.I'm so confused This is my code.

HttpContext almost is null in constructor of controller. It's not good get user in each action.I Wanna get information of user once and set them into ViewData;

    public DashboardController()
    {
        var user = HttpContext.User.GetUserId();
   }

回答1:

User.FindFirst(ClaimTypes.NameIdentifier).Value

EDIT for constructor

Below code works:

public Controller(IHttpContextAccessor httpContextAccessor)
{
    var userId = httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value 
}

Edit for RTM

You should register IHttpContextAccessor:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }


回答2:

Simple way that works and I checked.

var user = await _userManager.GetUserAsync(HttpContext.User);

then you can all the properties of this variables like user.Email. I hope this would help someone.



回答3:

Have another way of getting current user in Asp.NET Core - and I think I saw it somewhere here, on SO ^^

// Stores UserManager
private readonly UserManager<ApplicationUser> _manager; 

// Inject UserManager using dependency injection.
// Works only if you choose "Individual user accounts" during project creation.
public DemoController(UserManager<ApplicationUser> manager)  
{  
    _manager = manager;  
}

// You can also just take part after return and use it in async methods.
private async Task<ApplicationUser> GetCurrentUser()  
{  
    return await _manager.GetUserAsync(HttpContext.User);  
}  

// Generic demo method.
public async Task DemoMethod()  
{  
    var user = await GetCurrentUser(); 
    string userEmail = user.Email; // Here you gets user email 
    string userId = user.Id;
}  

That code goes to controller named DemoController. Won't work without both await (won't compile) ;)



回答4:

It would appear that as of now (April of 2017) that the following works:

public string LoggedInUser => User.Identity;

At least while within a Controller



回答5:

My problem was to access the logged in User as an object in the cshtml file. Considering you wanted the user in ViewData, this approach might be helpful:

In the cshtml file

@using Microsoft.AspNetCore.Identity
@inject UserManager<ApplicationUser> UserManager

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
    @UserManager.FindByNameAsync(UserManager.GetUserName(User)).Result.Email
    </title>
  </head>
  <body>

  </body>
</html>


回答6:

In addition to existing answers I'd like to add that you can also have a class instance available app-wide which holds user-related data like UserID etc.

It may be useful for refactoring e.g. you don't want to fetch UserID in every controller action and declare an extra UserID parameter in every method related to Service Layer.

I've done a research and here's my post.

You just extend your class which you derive from DbContext by adding UserId property (or implement a custom Session class which has this property).

At filter level you can fetch your class instance and set UserId value.

After that wherever you inject your instance - it will have the necessary data (lifetime must be per request, so you register it using AddScoped method).

Working example:

public class AppInitializationFilter : IAsyncActionFilter
{
    private DBContextWithUserAuditing _dbContext;

    public AppInitializationFilter(
        DBContextWithUserAuditing dbContext
        )
    {
        _dbContext = dbContext;
    }

    public async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next
        )
    {
        string userId = null;
        int? tenantId = null;

        var claimsIdentity = (ClaimsIdentity)context.HttpContext.User.Identity;

        var userIdClaim = claimsIdentity.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
        if (userIdClaim != null)
        {
            userId = userIdClaim.Value;
        }

        var tenantIdClaim = claimsIdentity.Claims.SingleOrDefault(c => c.Type == CustomClaims.TenantId);
        if (tenantIdClaim != null)
        {
            tenantId = !string.IsNullOrEmpty(tenantIdClaim.Value) ? int.Parse(tenantIdClaim.Value) : (int?)null;
        }

        _dbContext.UserId = userId;
        _dbContext.TenantId = tenantId;

        var resultContext = await next();
    }
}

For more information see my answer.



回答7:

I got my solution

var claim = HttpContext.User.CurrentUserID();

public static class XYZ
{
    public static int CurrentUserID(this ClaimsPrincipal claim)
    {
        var userID = claimsPrincipal.Claims.ToList().Find(r => r.Type == 
         "UserID").Value;
        return Convert.ToInt32(userID);
    }
    public static string CurrentUserRole(this ClaimsPrincipal claim)
    {
        var role = claimsPrincipal.Claims.ToList().Find(r => r.Type == 
        "Role").Value;
        return role;
    }
}