ASP.NET Core Identity - get current user
If your code is inside an MVC controller:
public class MyController : Microsoft.AspNetCore.Mvc.Controller
From the Controller
base class, you can get the ClaimsPrincipal
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:
Get the user manager using dependency injection
private UserManager<ApplicationUser> _userManager;
//class constructor
public MyController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}And use it:
var user = await _userManager.GetUserAsync(User);
var email = user.Email;
If your code is a service class, you can use dependency injection to get an IHttpContextAccessor
that lets you get the User
from the HttpContext.
private IHttpContextAccessor _httpContextAccessor;
public MyClass(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
private void DoSomething()
{
var user = _httpContextAccessor.Context?.User;
}
How to get the current logged in user ID in ASP.NET Core?
I included using System.Security.Claims and I could access the GetUserId() extension method
NB: I had the using Microsoft.AspNet.Identity already but couldn't get the extension method. So I guess both of them have to be used in conjunction with one another
using Microsoft.AspNet.Identity;
using System.Security.Claims;
EDIT:
This answer is now outdated. Look at Soren's or Adrien's answer for a dated way of achieving this in CORE 1.0
Getting Current User in Controller
You can get the current user id in your controller using the UserManager such as:
ASP.NET CORE >= 2.0
var currentUserId = User.FindFirstValue(ClaimTypes.NameIdentifier);
or Name
using:
var currentUserId = User.FindFirstValue(ClaimTypes.Name);
If you want to get the current user in some other class, you can use the IHttpContextAccessor
, passing it into the class's constructor and using the HttpContext
to access the User
How to get current user in asp.net core
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.AddHttpContextAccessor();
}
How to get current user id, if i inherits from IdentityUser?
In ASP.Net Core ,if your Controller inherits the Microsoft.AspNetCore.Mvc.Controller
, you could get the IClaimsPrincipal
from the User property and get the actual "Id" of the user,
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
ClaimsPrincipal currentUser = this.User;
var currentUserID = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
You can also get the data of all fields(include Id) from the database's User entity:
1.DI UserManager
private readonly UserManager<ApplicationUser> _userManager;
public HomeController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
2.Use it like below:
var id = userManager.GetUserId(User); // get user Id
var user = await userManager.GetUserAsync(User); // get user's all data
What is the way in ASP.NET Core 3.0 to get current authenticated User username?
For this issue, it is caused by that the IdentityServer4
did not add the JwtClaimTypes.Name
to the access_token. If you check the access_token from web brower, you will find it miss "name": "Tom",
node.
For a workaround, you could implement your own ITokenService
like
public class CustomTokenService : DefaultTokenService
{
public CustomTokenService(IClaimsService claimsProvider
, IReferenceTokenStore referenceTokenStore
, ITokenCreationService creationService
, IHttpContextAccessor contextAccessor
, ISystemClock clock
, IKeyMaterialService keyMaterialService
, ILogger<DefaultTokenService> logger)
: base(claimsProvider, referenceTokenStore, creationService, contextAccessor, clock, keyMaterialService, logger)
{
}
public override async Task<Token> CreateAccessTokenAsync(TokenCreationRequest request)
{
Logger.LogTrace("Creating access token");
request.Validate();
var claims = new List<Claim>();
claims.AddRange(await ClaimsProvider.GetAccessTokenClaimsAsync(
request.Subject,
request.Resources,
request.ValidatedRequest));
if (request.ValidatedRequest.Client.IncludeJwtId)
{
claims.Add(new Claim(JwtClaimTypes.JwtId, CryptoRandom.CreateUniqueId(16)));
}
claims.Add(new Claim(JwtClaimTypes.Name, request.Subject.GetDisplayName()));
var issuer = Context.HttpContext.GetIdentityServerIssuerUri();
var token = new Token(OidcConstants.TokenTypes.AccessToken)
{
CreationTime = Clock.UtcNow.UtcDateTime,
Issuer = issuer,
Lifetime = request.ValidatedRequest.AccessTokenLifetime,
Claims = claims.Distinct(new ClaimComparer()).ToList(),
ClientId = request.ValidatedRequest.Client.ClientId,
AccessTokenType = request.ValidatedRequest.AccessTokenType
};
foreach (var api in request.Resources.ApiResources)
{
if (!string.IsNullOrWhiteSpace(api.Name))
{
token.Audiences.Add(api.Name);
}
}
return token;
}
}
And then register CustomTokenService
before Identity Configuration
public void ConfigureServices(IServiceCollection services)
{
services.TryAddTransient<ITokenService, CustomTokenService>();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
}
For a simple way, you could try to override DefaultClaimsService.GetStandardSubjectClaims
like
public class CustomClaimsService : DefaultClaimsService
{
public CustomClaimsService(IProfileService profile
, ILogger<DefaultClaimsService> logger) : base(profile, logger)
{
}
protected override IEnumerable<Claim> GetStandardSubjectClaims(ClaimsPrincipal subject)
{
var claims = base.GetStandardSubjectClaims(subject);
var newClaims = new List<Claim>(claims)
{
new Claim(JwtClaimTypes.Name, subject.Identity.Name)
};
return newClaims;
}
}
And register like
public void ConfigureServices(IServiceCollection services)
{
services.TryAddTransient<IClaimsService, CustomClaimsService>();
//services.TryAddTransient<ITokenService, CustomTokenService>();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<ApplicationUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
}
How to get current logged in user id in ASP NET CORE 3.0?
To solve this issue, you should create a MyUser and set properties for this newly created object like this :
var user = await _userManager.GetUserAsync(HttpContext.User);
if (ModelState.IsValid)
{
var newUserInfo = new ToDoList.Models.MyUser{
//set related properties from user to this object
//for example
UserName = user.UserName
//and add other properties
};
toDo.User = newUserInfo ;
_context.Todoes.Add(toDo);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
Get current user id in startup (asp.net core 5)
I need to send user Id when inject some service. or it is not possible ?
HttpContext
is only valid during a request. The ConfigureServices
method in Startup is not a web call and, as such, does not have a HttpContext
. So the User information also cannot be got. You need register the IHttpContextAccessor
and DI it by constructor in your services. Then you could get HttpContext.User
infomation successfully.
Register the IHttpContextAccessor:
services.AddScoped<IHttpContextAccessor,HttpContextAccessor>();
DI in the service:
public interface IService
{
string GetUserId();
}
public class Service : IService
{
private readonly IHttpContextAccessor _httpContextAccessor;
public Service(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public string GetUserId()
{
var id = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
return id;
}
}
Register the service:
services.AddScoped<IHttpContextAccessor,HttpContextAccessor>();
services.AddScoped<IService, Service>(); //add this...
More explanations you could refer to here.
Related Topics
How to Make Form1 Label.Text Change When Checkbox on Form2 Is Checked
Error Message "Cs5001 Program Does Not Contain a Static 'Main' Method Suitable for an Entry Point"
How to Define Properties in Partial Classes, Then Mark Them with Attributes in Another Partial Class
Removing the Delay After Keydown Event
The Difference Between Virtual, Override, New and Sealed Override
Overriding Fields or Properties in Subclasses
C# - How to Make Two Forms Reference Each Other
Xaml Gridview Itemtemplate Not Binding to Control
Open a Folder Using Process.Start
Blocking Access to Private Member Variables? Force Use of Public Properties
How to Interact with Windows Media Player in C#
Asmx Web Service How to Return JSON and Not Xml
How to Debug into My Nuget Package Deployed from Teamcity
How to Implement a Singleton in C#
Ms Chart Rectangular Annotation Width in Percent and Not Pixel