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

MRainzo
quelle
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;
     }
}
TanvirArjel
quelle
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.

AdrienTorris
quelle
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());
        }
    }
}
Soren
quelle
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

MRainzo
quelle
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);
Oracular Man
quelle
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.

Menno Guldemond
quelle
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);
Mansur Haider
quelle
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.

Ahmad
quelle
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

jv_
quelle
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

Usman
quelle
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

Maksud
quelle
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.

HO3EiN
quelle
0

Verwendung kann verwenden

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

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

Mosta
quelle
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);
    }
sammy Akinsoju
quelle
-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.

Pravin Deshmukh
quelle
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