How to get User Information after login in ASP.NET Core3.1

Viewed 4446

I am trying to get user information after login in ASP.NET Core 3.1 (information like name, email, id, ...).

Here is my code in login action

var claims = new List<Claim>()
{
    new Claim(ClaimTypes.NameIdentifier, "NameIdentifire"),
    new Claim(ClaimTypes.Name, "Name"),
    new Claim(ClaimTypes.Email, "Email")
};

var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

var principal = new ClaimsPrincipal(identity);

HttpContext.SignInAsync(principal);

In the views I only access the name by looking at @User.Identity.Name. My question is: how to get other information user in different views?

4 Answers

You can create an helper class like this one:

internal static class ClaimsPrincipalExtensions
{
    internal static string GetEmail(this ClaimsPrincipal claimsPrincipal)
        => claimsPrincipal.FindFirstValue(ClaimTypes.Email);

    internal static string GetFirstName(this ClaimsPrincipal claimsPrincipal)
        => claimsPrincipal.FindFirstValue(ClaimTypes.Name);

    internal static string GetLastName(this ClaimsPrincipal claimsPrincipal)
        => claimsPrincipal.FindFirstValue(ClaimTypes.Surname);

    internal static string GetPhoneNumber(this ClaimsPrincipal claimsPrincipal)
        => claimsPrincipal.FindFirstValue(ClaimTypes.MobilePhone);

    internal static string GetUserId(this ClaimsPrincipal claimsPrincipal)
       => claimsPrincipal.FindFirstValue(ClaimTypes.NameIdentifier);
}

and use it like:

_profileModel.Email = user.GetEmail();
_profileModel.FirstName = user.GetFirstName();
_profileModel.LastName = user.GetLastName();
_profileModel.PhoneNumber = user.GetPhoneNumber();

This code is from a Blazor WASM application, but the code is about the same for ASP.NET Core.

claims can be fetched from User Principal

ViewBag.userName = User.Claims.FirstOrDefault(c => c.Type == "key")?.Value;

a database call can be made to fetch values and add them in claims, if you want other claims from identity provider, you will have to change configuration from identity provider end.

await userManager.FindByIdAsync(userManager.GetUserId(user))

to fetch user identity

This code is for APS.NET CORE Identity

Add Imports to your controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;

Import _userManager into your controller.

private readonly UserManager<ApplicationUser> _userManager;

public UserManagementController //this should be your controller name

(UserManager<ApplicationUser> userManager)

Write the method:

[HttpGet]
public async Task<object> GetCurrentUser()
{
     var user = await _userManager.GetUserAsync(User);
     return user;
}

Based on the previous discussion and your code, I assume you are using cookie authentication without the Asp.net core Identity, and after login, when you access the claims from the HttpContext.User, the claims are empty, right?

If that is the case, I suggest you check the configuration in the Startup.cs file, whether you have set the cookie's expires time? Please make sure the cookie is not expired. And in the Configure method, make sure you have added the following middleware (note the middleware order):

        app.UseAuthentication();
        app.UseAuthorization();

Here is a simple sample code about using cookie authentication without ASP.NET Core Identity, you can refer it:

  1. Configure the cookie authentication:
    Add AddAuthentication() method in the ConfigureServices method:

     public void ConfigureServices(IServiceCollection services)
     {
         services.AddControllersWithViews();
         //required using Microsoft.AspNetCore.Authentication.Cookies;
         services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
              .AddCookie(options =>
              {
                  options.LoginPath = "/Account/Login";  //set the login page
    
              });
     }
    

    Add the UseAuthentication() and UseAuthorization() in the Configure method:

     public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     {
         if (env.IsDevelopment())
         {
             app.UseDeveloperExceptionPage();
         }
         else
         {
             app.UseExceptionHandler("/Home/Error");
             // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
             app.UseHsts();
         }
         app.UseHttpsRedirection();
         app.UseStaticFiles();
    
         app.UseRouting();
    
         //Note the middleware order.
         app.UseAuthentication();
         app.UseAuthorization();
    
         app.UseEndpoints(endpoints =>
         {
             endpoints.MapControllerRoute(
                 name: "default",
                 pattern: "{controller=Home}/{action=Index}/{id?}");
         });
     }
    
  2. Create Account controller with the following actions:

     public class AccountController : Controller
     {
         public IActionResult Index()
         {
             return View();
         }
         public IActionResult Login()
         {
             return View();
         }
         [HttpPost]
         public async Task<IActionResult> Login(string username, string email, string password, string ReturnUrl)
         {
             if ((username == "Tom") && (password == "abc"))
             {
                 var claims = new List<Claim>
                 {
                     new Claim(ClaimTypes.NameIdentifier, "NameIdentifire"),
                     new Claim(ClaimTypes.Name, username),
                     new Claim(ClaimTypes.Email, email)
                 };
                 var claimsIdentity = new ClaimsIdentity(claims, "Login");
    
                 await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity));
                 return Redirect(ReturnUrl == null ? "/Home/Privacy" : ReturnUrl);
             }
             else
                 return View();
         }
    
         [HttpPost]
         public async Task<IActionResult> Logout()
         {
             await HttpContext.SignOutAsync();
             return RedirectToAction("Index", "Home");
         }
     }
    

    Add the Login page:

     @{
         ViewData["Title"] = "Login";
     }
    
     <h1>Login</h1>
    
     <form method="post">
         <input type="text" name="username" placeholder="Username">
         <input type="text" name="email" placeholder="User Email">
         <input type="password" name="password" placeholder="Password">
         <button>Sign in</button>
    
     </form>
    
  3. Add the secured page and access the claims.

    Add the [Authorize] attribute at the head of the Home Controller Privacy Page

     [Authorize]
     public IActionResult Privacy()
     {
         var claims = HttpContext.User.Claims;
    
         return View();
     }
    

    In the Privacy view page:

     Login User Information
     <h2>@User.Claims.FirstOrDefault(c => c.Type.Contains("name")).Value</h2>
     <h2>@User.Claims.FirstOrDefault(c => c.Type.Contains("email")).Value</h2>
    
    
     <form class="form-inline" asp-controller="Account" asp-action="Logout">
         <button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
     </form>
    

The result as below:

enter image description here

Related