So erhalten Sie die aktuell angemeldete Benutzer-ID in ASP.NET Core


179

Ich habe das schon einmal mit MVC5 gemacht, User.Identity.GetUserId()aber das scheint hier nicht zu funktionieren. Das User.Identityhat die GetUserId()Methode nicht

ich benutze Microsoft.AspNet.Identity


2
versuchen Sie das System.Web.HttpContext.Current.User.Identity.Name?
Pravin Deshmukh

Vielen Dank an @PravinDeshmukh, aber das gibt den Namen des Benutzers und nicht die ID zurück
MRainzo

1
Es sollte funktionieren. Siehe die Beispiele in asp.net github.com/aspnet/Identity/blob/… . Stellen Sie einfach sicher, dass der Benutzer angemeldet ist. @PravinDeshmukh, verwenden Sie niemals System.Web.HttpContext.Current in vnext :)
user960567

1
Hallo @ user960567, kannst du uns bitte sagen warum?
Pravin Deshmukh

@PravinDeshmukh, da es auf dem .NET-Kern nicht funktioniert und keine System.Web-Abhängigkeit besteht.
user960567

Antworten:


148

Update in ASP.NET Core Version> = 2.0

In der Steuerung:

public class YourControllerNameController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;

    public YourControllerNameController(UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;
    }

    public async Task<IActionResult> YourMethodName()
    {
        var userId =  User.FindFirstValue(ClaimTypes.NameIdentifier) // will give the user's userId
        var userName =  User.FindFirstValue(ClaimTypes.Name) // will give the user's userName

        ApplicationUser applicationUser = await _userManager.GetUserAsync(User);
        string userEmail = applicationUser?.Email; // will give the user's Email
    }
}

In einer anderen Klasse:

public class OtherClass
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public OtherClass(IHttpContextAccessor httpContextAccessor)
    {
       _httpContextAccessor = httpContextAccessor;
    }

   public void YourMethodName()
   {
      var userId = _httpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
   }
}

Dann sollten Sie sich wie folgt IHttpContextAccessorin der StartupKlasse anmelden :

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

    // Or you can also register as follows

    services.AddHttpContextAccessor();
}

Für eine bessere Lesbarkeit schreiben Sie Erweiterungsmethoden wie folgt:

public static class ClaimsPrincipalExtensions
{
    public static T GetLoggedInUserId<T>(this ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));

        var loggedInUserId = principal.FindFirstValue(ClaimTypes.NameIdentifier);

        if (typeof(T) == typeof(string))
        {
            return (T)Convert.ChangeType(loggedInUserId, typeof(T));
        }
        else if (typeof(T) == typeof(int) || typeof(T) == typeof(long))
        {
            return loggedInUserId != null ? (T)Convert.ChangeType(loggedInUserId, typeof(T)) : (T)Convert.ChangeType(0, typeof(T));
        }
        else
        {
            throw new Exception("Invalid type provided");
        }
    }

    public static string GetLoggedInUserName(this ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));

        return principal.FindFirstValue(ClaimTypes.Name);
    }

    public static string GetLoggedInUserEmail(this ClaimsPrincipal principal)
    {
        if (principal == null)
            throw new ArgumentNullException(nameof(principal));

        return principal.FindFirstValue(ClaimTypes.Email);
    }
}

Dann verwenden Sie wie folgt:

public class YourControllerNameController : Controller
{
    public IActionResult YourMethodName()
    {
        var userId = User.GetLoggedInUserId<string>(); // Specify the type of your UserId;
        var userName = User.GetLoggedInUserName();
        var userEmail = User.GetLoggedInUserEmail();
    }
}

public class OtherClass
{
     private readonly IHttpContextAccessor _httpContextAccessor;
     public OtherClass(IHttpContextAccessor httpContextAccessor)
     {
         _httpContextAccessor = httpContextAccessor;
     }

     public void YourMethodName()
     {
         var userId = _httpContextAccessor.HttpContext.User.GetLoggedInUserId<string>(); // Specify the type of your UserId;
     }
}

1
Aber der Benutzer gibt in meinem Fall null zurück? Wo mache ich falsch?
Sruthi Varghese

Sind Sie sicher, dass Sie mit einem Benutzer angemeldet sind?
TanvirArjel

In meinem Szenario möchte ich, dass der Benutzername des Benutzers in meinem System angemeldet ist. Lass es Ubuntu oder Windows sein? Und während ich dies in Windows teste, bin ich unter meinem Namen angemeldet. Aber es kehrt zurück null.
Sruthi Varghese

Dann müssen Sie Ihren Code sehen! Möglicherweise spielt hier ein externer Agent eine Rolle.
TanvirArjel

2
Ich habe festgestellt, dass wenn Sie ein Nullergebnis von haben User.Identity.Name, dies möglicherweise daran liegt, dass die anonyme Authentifizierung aktiviert ist. Ich konnte User.Identity.Namemeine Domain und meinen Benutzernamen durch Erweitern Properties > launchSettings.jsonund Einstellen anonymousAuthenticationauf falseund windowsAuthenticationauf zurückgeben true.
Andrew Gray

109

Bis ASP.NET Core 1.0 RC1 :

Es ist User.GetUserId () aus dem System.Security.Claims- Namespace.

Seit ASP.NET Core 1.0 RC2 :

Sie müssen jetzt UserManager verwenden . Sie können eine Methode erstellen, um den aktuellen Benutzer abzurufen:

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);

Und erhalten Sie Benutzerinformationen mit dem Objekt:

var user = await GetCurrentUserAsync();

var userId = user?.Id;
string mail = user?.Email;

Hinweis: Sie können dies tun, ohne eine Methode zum Schreiben einzelner Zeilen wie diese zu verwenden string mail = (await _userManager.GetUserAsync(HttpContext.User))?.Email, ohne jedoch das Prinzip der Einzelverantwortung zu berücksichtigen. Es ist besser, die Art und Weise zu isolieren, in der Sie den Benutzer erhalten, da es schmerzhaft wird, wenn Sie eines Tages Ihr Benutzerverwaltungssystem ändern und beispielsweise eine andere Lösung als Identity verwenden, da Sie Ihren gesamten Code überprüfen müssen.


1
Ich habe den System.Security.Claims-Namespace und die Microsoft.AspNet.Identity-Assembly.
Scottheckel

2
Ich denke, dass diese Antwort besser ist als die akzeptierte Antwort, zumal der asp.net-Kern die Abhängigkeitsinjektion fördert.
Phillip Davis

2
Scheint falsch, weil userManager eine Anfrage an die Datenbank stellt, um Informationen über den Benutzer abzurufen. Und in diesem Fall war die Benutzer-ID bereits in HttpContext.User
incognito

@incognito Der Bezeichner war nur ein Beispiel, aber Sie können alle Informationen erhalten, die Sie mit dem Objekt des Benutzers benötigen
AdrienTorris

2
@Adrien aber die Frage war, wie man Benutzer-ID bekommt. Ich wollte nur sagen, dass der bereitgestellte Weg nicht der effizienteste ist. Für diesen Fall würde ich eine Antwort von Soren oder die kürzere Version bevorzugen, die in den Kommentaren zu finden ist.
inkognito

91

Sie können es in Ihrem Controller erhalten:

using System.Security.Claims;
var userId = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

oder schreiben Sie eine Erweiterungsmethode wie zuvor .Core v1.0

using System;
using System.Security.Claims;

namespace Shared.Web.MvcExtensions
{
    public static class ClaimsPrincipalExtensions
    {
        public static string GetUserId(this ClaimsPrincipal principal)
        {
            if (principal == null)
                throw new ArgumentNullException(nameof(principal));

            return principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        }
    }
}

und erhalten Sie, wo immer Benutzer ClaimsPrincipal verfügbar ist :

using Microsoft.AspNetCore.Mvc;
using Shared.Web.MvcExtensions;

namespace Web.Site.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return Content(this.User.GetUserId());
        }
    }
}

16
Kürzere Version:var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
CFreitas

1
Beachten Sie, dass diese Erweiterungsmethode nur für Benutzer in Controllern funktioniert, nicht für Ansichtskomponenten, da die Ansichtskomponente Benutzer von IPrincipal ist
adam3039

@AK können Sie verwenden Convert.ToInt32(User.FindFirstValue(ClaimTypes.NameIdentifier)), um Ganzzahl UserId
Hamza Khanzada

1
@ HamzaKhanzada Ja, es funktioniert, sieht aber so lang und hässlich aus.
AK

39

Ich habe die Verwendung von System.Security.Claims eingeschlossen und konnte auf die Erweiterungsmethode GetUserId () zugreifen

NB: Ich hatte bereits Microsoft.AspNet.Identity verwendet, konnte aber die Erweiterungsmethode nicht erhalten. Ich denke also, dass beide zusammen verwendet werden müssen

using Microsoft.AspNet.Identity;
using System.Security.Claims;

EDIT : Diese Antwort ist jetzt veraltet. Schauen Sie sich Sorens oder Adriens Antwort an, um zu erfahren, wie dies in CORE 1.0 erreicht werden kann


17
Dies war die geheime Sauce, aber für jeden, der nach dem Hinzufügen dieser Verwendungen sucht, ist es ...var userId = User.GetUserId();
Samurai Ken

4
Die Erweiterung .GetUserId () von ClaimsPrincipal (Controller.User) wurde nach => UserManager.GetUserId (User) verschoben.
Soren

1
using System.Security.Claims; var userId = this.User.FindFirst (ClaimTypes.NameIdentifier);
Schalter

3
Daumen hoch für die zuvor gültige Antwort und die korrekte Identifizierung der neuen "richtigen" Antwort.
Pimbrouwers

26

Nur für .NET Core 2.0 Zum Abrufen der Benutzer-ID des angemeldeten Benutzers in einer ControllerKlasse ist Folgendes erforderlich :

var userId = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

oder

var userId = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);

z.B

contact.OwnerID = this.User.FindFirstValue(ClaimTypes.NameIdentifier);

17

Wie irgendwo in diesem Beitrag angegeben, wurde die GetUserId () -Methode in den UserManager verschoben.

private readonly UserManager<ApplicationUser> _userManager;

public YourController(UserManager<ApplicationUser> userManager)
{
    _userManager = userManager;
}

public IActionResult MyAction()
{
    var userId = _userManager.GetUserId(HttpContext.User);

    var model = GetSomeModelByUserId(userId);

    return View(model);
}

Wenn Sie ein leeres Projekt gestartet haben, müssen Sie möglicherweise den UserManger zu Ihren Diensten in startup.cs hinzufügen. Andernfalls sollte dies bereits der Fall sein.


10

Sie müssen Microsoft.AspNetCore.Identity & System.Security.Claims importieren

// to get current user ID
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);

// to get current user info
var user = await _userManager.FindByIdAsync(userId);

Von all diesen Antworten ist Ihre die einzige, die mit ASP.NET CORE v 2.0 funktioniert. Herzlichen Glückwunsch!
Nur fair

Das ist es. Jeder von .NET Core 2.0 und höher, das ist Ihre Antwort
Alvinchesaro

1
Getestet unter .NET Core 3.1 in einer Web-API + JWT-Einstellung. Ich möchte den aktuell angemeldeten Benutzer in einem Basis-Controller. Dies ist nicht effizient. Es wird der Benutzer für jede Anforderung usw. aus der Datenbank abgefragt. Gibt es eine Möglichkeit, den aktuellen Benutzer abzurufen, ohne die Datenbank abzufragen?
Nexus

warum meine Rückkehr "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"für User.FindFirstValue(ClaimTypes.NameIdentifier);?
kindisch

5

Obwohl Adriens Antwort richtig ist, können Sie dies alles in einer einzigen Zeile tun. Keine Notwendigkeit für zusätzliche Funktion oder Chaos.

Es funktioniert Ich habe es in ASP.NET Core 1.0 überprüft

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

dann können Sie andere Eigenschaften der Variablen wie erhalten user.Email. Ich hoffe das hilft jemandem.


3
Der Grund, warum ich eine Methode verwende, besteht darin, das Prinzip der Einzelverantwortung zu respektieren. Wenn Sie die Art und Weise, wie Sie den Benutzer erhalten, nicht isolieren, ist es schmerzhaft, wenn Sie sich eines Tages dazu entschließen, Ihr Benutzerverwaltungssystem zu ändern, z. B. eine andere Lösung als Identity zu verwenden.
AdrienTorris

5

Für ASP.NET Core 2.0, Entity Framework Core 2.0, AspNetCore.Identity 2.0-API ( https://github.com/kkagill/ContosoUniversity-Backend ):

Das Idwurde geändert inUser.Identity.Name

    [Authorize, HttpGet("Profile")]
    public async Task<IActionResult> GetProfile()
    {
        var user = await _userManager.FindByIdAsync(User.Identity.Name);

        return Json(new
        {
            IsAuthenticated = User.Identity.IsAuthenticated,
            Id = User.Identity.Name,
            Name = $"{user.FirstName} {user.LastName}",
            Type = User.Identity.AuthenticationType,
        });
    }

Antwort:

Geben Sie hier die Bildbeschreibung ein


Basierend auf meinem Test ist dies jedoch this.User.Identity.Namein der Regel der Benutzername. Bei meinem Test ist der Benutzername eine E-Mail, sei es der Benutzer, der sich von der Registrierung aus anmeldet oder sich von einem externen Login anmeldet (z. B. Facebook, Google). Der folgende Code gibt die Benutzer-ID zurück. Ich verwende einen automatisch inkrementierten Primärschlüssel für meine Identitätsbenutzertabelle, daher int.Parse. int userId = int.Parse(this.User.FindFirstValue(ClaimTypes.NameIdentifier));
Michael Buen

1
FindByIdAsyncfunktioniert nicht, da Sie einen Benutzernamen angeben. Es funktioniert, wenn Sie es durch ersetzen FindByNameAsync.
Jasper

4

in dem APiController

User.FindFirst(ClaimTypes.NameIdentifier).Value

So etwas bekommen Sie die Ansprüche


1

User.Identity.GetUserId ();

existiert nicht in asp.net Identity Core 2.0. In dieser Hinsicht habe ich es anders geschafft. Ich habe eine gemeinsame Klasse für die Verwendung der gesamten Anwendung erstellt, da Benutzerinformationen abgerufen werden.

Erstellen Sie eine gemeinsame Klasse PCommon & Schnittstelle IPCommon und fügen Sie eine Referenz hinzuusing System.Security.Claims

using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace Common.Web.Helper
{
    public class PCommon: IPCommon
    {
        private readonly IHttpContextAccessor _context;
        public PayraCommon(IHttpContextAccessor context)
        {
            _context = context;
        }
        public int GetUserId()
        {
            return Convert.ToInt16(_context.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier));
        }
        public string GetUserName()
        {
            return _context.HttpContext.User.Identity.Name;
        }

    }
    public interface IPCommon
    {
        int GetUserId();
        string GetUserName();        
    }    
}

Hier die Implementierung der gemeinsamen Klasse

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Logging;
using Pay.DataManager.Concreate;
using Pay.DataManager.Helper;
using Pay.DataManager.Models;
using Pay.Web.Helper;
using Pay.Web.Models.GeneralViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Pay.Controllers
{

    [Authorize]
    public class BankController : Controller
    {

        private readonly IUnitOfWork _unitOfWork;
        private readonly ILogger _logger;
        private readonly IPCommon _iPCommon;


        public BankController(IUnitOfWork unitOfWork, IPCommon IPCommon, ILogger logger = null)
        {
            _unitOfWork = unitOfWork;
            _iPCommon = IPCommon;
            if (logger != null) { _logger = logger; }
        }


        public ActionResult Create()
        {
            BankViewModel _bank = new BankViewModel();
            CountryLoad(_bank);
            return View();
        }

        [HttpPost, ActionName("Create")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Insert(BankViewModel bankVM)
        {

            if (!ModelState.IsValid)
            {
                CountryLoad(bankVM);
                //TempData["show-message"] = Notification.Show(CommonMessage.RequiredFieldError("bank"), "Warning", type: ToastType.Warning);
                return View(bankVM);
            }


            try
            {
                bankVM.EntryBy = _iPCommon.GetUserId();
                var userName = _iPCommon.GetUserName()();
                //_unitOfWork.BankRepo.Add(ModelAdapter.ModelMap(new Bank(), bankVM));
                //_unitOfWork.Save();
               // TempData["show-message"] = Notification.Show(CommonMessage.SaveMessage(), "Success", type: ToastType.Success);
            }
            catch (Exception ex)
            {
               // TempData["show-message"] = Notification.Show(CommonMessage.SaveErrorMessage("bank"), "Error", type: ToastType.Error);
            }
            return RedirectToAction(nameof(Index));
        }



    }
}

Holen Sie sich die Benutzer-ID und den Namen in die Einfügeaktion

_iPCommon.GetUserId();

Danke, Maksud


1
Müssen Sie IHttpContextAccessor in Startup.cs registrieren?
REMESQ

1
Kein REMESQ, ich habe dies nicht in den Start injiziert, sondern in meiner Anwendung gearbeitet
Maksud

1

Um die aktuelle Benutzer-ID in Rasiereransichten abzurufen, können Sie UserManager wie folgt in die Ansicht einfügen:

@inject Microsoft.AspNetCore.Identity.UserManager<ApplicationUser> _userManager
@{ string userId = _userManager.GetUserId(User); }

Ich hoffe, Sie finden es nützlich.


0

Verwendung kann verwenden

string userid = User.FindFirst("id").Value;

Aus irgendeinem Grund ruft NameIdentifier jetzt den Benutzernamen ab (.net Core 2.2).


0

Als Administrator, der am Profil anderer Personen arbeitet und die ID des Profils abrufen muss, an dem Sie arbeiten, können Sie die ID mit einem ViewBag erfassen, z. B. ViewBag.UserId = userId; während userId der String-Parameter der Methode ist, an der Sie arbeiten.

    [HttpGet]

    public async Task<IActionResult> ManageUserRoles(string userId)
    {

          ViewBag.UserId = userId;


        var user = await userManager.FindByIdAsync(userId);

        if (user == null)
        {
            ViewBag.ErrorMessage = $"User with Id = {userId} cannot be found";
            return View("NotFound");
        }

        var model = new List<UserRolesViewModel>();

        foreach (var role in roleManager.Roles)
        {
            var userRolesViewModel = new UserRolesViewModel
            {
                RoleId = role.Id,
                RoleName = role.Name
            };

            if (await userManager.IsInRoleAsync(user, role.Name))
            {
                userRolesViewModel.IsSelected = true;
            }
            else
            {
                userRolesViewModel.IsSelected = false;
            }

            model.Add(userRolesViewModel);
        }
        return View(model);
    }

-11

Wenn Sie dies in ASP.NET MVC Controller möchten, verwenden Sie

using Microsoft.AspNet.Identity;

User.Identity.GetUserId();

Sie müssen eine usingAnweisung hinzufügen , da GetUserId()diese ohne diese Anweisung nicht verfügbar ist.


2
Ja, ich habe in die Frage aufgenommen, dass ich die "using Microsoft.AspNet.Identity" habe. Ich fand heraus, wie ich es lösen konnte, aber mit meiner Antwort auf den Beitrag
MRainzo

1
FWIW es ist (jetzt) User.GetUserId()und nichtUser.Identity.GetUserId()
lc.

18
Die Frage war und ist über asp.net CORE, das den Namespace Microsoft.AspNetCore.Identity hat; und NICHT Microsoft.AspNet.Identity; Und unter Verwendung dieses neuen Namespace gibt es KEINE Erweiterungsmethode GetUserId (). Diese Antwort ist falsch!
Pascal

4
Schont die ALL CAPS. Und lerne, wie man auf SO nett ist. stackoverflow.blog/2018/04/26/…
smoore4
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.