ASP.NET Core'da şu anda oturum açmış olan kullanıcı kimliğini alma


179

Bunu MVC5 kullanarak daha önce yaptım User.Identity.GetUserId()ama bu burada işe yaramıyor gibi görünüyor. User.IdentityDoesnt sahip GetUserId()yöntemi

Ben kullanıyorum Microsoft.AspNet.Identity


2
denemek ister System.Web.HttpContext.Current.User.Identity.Namemisin?
Pravin Deshmukh

Teşekkürler @PravinDeshmukh ama kullanıcının adını değil kimliğini döndürür
MRainzo

1
İşe yaramalı. Asp.net github.com/aspnet/Identity/blob/… adresindeki örneklere bakın . Kullanıcının oturum açtığından emin olun. @PravinDeshmukh, asla System.Web.HttpContext.Current kullanmayın vnext :)
user960567

1
Merhaba @ user960567, lütfen bize nedenini söyleyebilir misiniz?
Pravin Deshmukh

@PravinDeshmukh çünkü .NET çekirdeğinde çalışmaz ve System.Web bağımlılığı yoktur.
user960567

Yanıtlar:


148

ASP.NET Core Sürümünde Güncelleme> = 2.0

Denetleyicide:

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
    }
}

Başka bir sınıfta:

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

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

Sonra kayıt olmalıdır IHttpContextAccessoriçinde Startupaşağıdaki gibi sınıfta:

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

    // Or you can also register as follows

    services.AddHttpContextAccessor();
}

Daha fazla okunabilirlik için genişletme yöntemlerini aşağıdaki gibi yazın:

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);
    }
}

Sonra aşağıdaki gibi kullanın:

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
Ama Kullanıcı benim durumumda null döndürüyor? Nerede yanlış yapıyorum?
Sruthi Varghese

Bir kullanıcıyla giriş yaptığınızdan emin misiniz?
TanvirArjel

Senaryom, sistemime giriş yapan kullanıcının kullanıcı adını istiyorum gibi. Ubuntu ya da Windows olsun? Bunu pencerelerde test ederken adım altında oturum açtım. Ama geri dönüyor null.
Sruthi Varghese

O zaman kodunuzu görmek zorunda! Burada rol oynayan herhangi bir harici ajan olabilir.
TanvirArjel

2
Null sonucunuz varsa User.Identity.Name, bunun Anonim Kimlik Doğrulaması etkinleştirilmiş olabileceğini fark ettim. Elde edebildi User.Identity.Namegenişleterek alan adımı ve kullanıcı adını döndürmek için Properties > launchSettings.jsonve ayar anonymousAuthenticationiçin false, ve windowsAuthenticationiçin true.
Andrew Gray

109

ASP.NET Core 1.0 RC1'e kadar :

System.Security.Claims ad alanından User.GetUserId () .

ASP.NET Core 1.0 RC2'den beri :

Artık UserManager'ı kullanmanız gerekiyor . Geçerli kullanıcıyı almak için bir yöntem oluşturabilirsiniz:

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

Ve nesne ile kullanıcı bilgilerini alın:

var user = await GetCurrentUserAsync();

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

Not: Bunu, böyle tek satırlar yazan bir yöntem kullanmadan yapabilirsiniz string mail = (await _userManager.GetUserAsync(HttpContext.User))?.Email, ancak tek sorumluluk ilkesine uymaz. Kullanıcıyı elde etme şeklinizi izole etmek daha iyidir, çünkü bir gün kimlik yönetiminden başka bir çözüm kullanmak gibi bir gün kullanıcı yönetim sisteminizi değiştirmeye karar verirseniz, tüm kodunuzu gözden geçirmeniz gerektiğinden ağrılı olacaktır.


1
System.Security.Claims ad alanı ve Microsoft.AspNet.Identity derleme var.
scottheckel

2
Özellikle asp.net çekirdeği bağımlılık enjeksiyonunu teşvik ettiği için bu cevabın kabul edilen cevaptan daha iyi olduğunu düşünüyorum.
Phillip Davis

2
UserManager kullanıcı hakkında bilgi almak için veritabanına talepte bulunacağı için yanlış görünüyor. Ve bu durumda userId HttpContext.User'da zaten mevcuttu
gizli

@incognito Tanımlayıcı sadece bir örnektir, ancak kullanıcının nesnesi ile ihtiyacınız olan tüm bilgileri alabilirsiniz
AdrienTorris

2
@Adrien ama soru Kullanıcı Kimliği nasıl elde edildi. Sadece sağlanan yolun en verimli olmadığını söylemek istedim. Bu durumda, Soren tarafından verilen cevabı veya yorumlarda bulunan daha kısa versiyonu tercih ederim.
gizli

91

kontrolörünüzden alabilirsiniz:

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

veya daha önce olduğu gibi bir uzantı yöntemi yazın.

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;
        }
    }
}

ve ClaimsPrincipal kullanıcısının kullanılabilir olduğu her yere gidin :

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ısa versiyon:var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
CFreitas

1
Görünüm bileşeni Kullanıcı IPrincipal ait olduğu gibi bu uzantı yöntemi yalnızca kontrolörleri içeride Kullanıcı için çalıştığını Not değil, bileşenleri görüntülemek
adam3039

@AK Convert.ToInt32(User.FindFirstValue(ClaimTypes.NameIdentifier))tamsayı almak için kullanabilirsiniz UserId
Hamza Khanzada

1
@HamzaKhanzada Evet, işe yarıyor ama çok uzun ve çirkin görünüyor.
AK

39

System.Security.Claims kullanarak dahil ve GetUserId () uzantısı yöntemine erişebilir

Not: Microsoft.AspNet.Identity kullanarak zaten vardı ama uzantısı yöntemi alamadım. Yani her ikisinin de birbirleriyle birlikte kullanılması gerekiyor

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

EDIT : Bu cevap şimdi eskimiş. Soren veya Adrien'in cevabını CORE 1.0'da bunu başarmanın tarihli bir yolu için görün


17
Bu gizli sos, ama bu kullanımları ekledikten sonra herkes lookign için ... var userId = User.GetUserId();
Samurai Ken

4
ClaimsPrincipal (Controller.User) 'dan .GetUserId () Uzantısı => UserManager.GetUserId (Kullanıcı)' ya taşındı;
Soren

1
System.Security.Claims kullanarak; var userId = this.User.FindFirst (ClaimTypes.NameIdentifier);
Anahtarı

3
Daha önce geçerli cevabı almak ve yeni "doğru" cevabı doğru bir şekilde tanımlamak için kullanılır.
pimbrouwers

26

Yalnızca .NET Core 2.0 için Bir Controllersınıfta oturum açmış kullanıcının UserID'sini getirmek için aşağıdakiler gereklidir :

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

veya

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

Örneğin

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

17

Bu yayının herhangi bir yerinde belirtildiği gibi, GetUserId () yöntemi UserManager'a taşındı.

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);
}

Boş bir proje başlattıysanız, User.anger'i startup.cs dosyasındaki hizmetlerinize eklemeniz gerekebilir. Aksi takdirde durum zaten böyle olmalıdır.


10

Microsoft.AspNetCore.Identity & System.Security.Claims'i içe aktarmanız gerekir

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

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

tüm bu anws'lardan ASP.NET CORE v 2.0 ile çalışan tek kişi sizindir. Congratz!
Just Fair

budur. .NET Core 2.0 ve üzeri herhangi biri, bu sizin cevabınız
alvinchesaro

1
Web API + JWT ayarında .NET Core 3.1 üzerinde test edilmiştir. Şu anda oturum açmış bir temel denetleyicide kullanıcı istiyorum, bu verimli değil, her istek, vb için veritabanından kullanıcı sorgulama vb Geçerli sorgu veritabanını sorgulamadan almak için herhangi bir yolu var mı?
Nexus

neden mayın çıkmıyor "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"için User.FindFirstValue(ClaimTypes.NameIdentifier);?
puerile

5

Adrien'in cevabı doğru olsa da, bunları tek bir satırda yapabilirsiniz. Ekstra işlev veya karmaşaya gerek yok.

ASP.NET Core 1.0'da kontrol ettim

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

sonra değişkenin diğer özelliklerini alabilirsiniz user.Email. Umarım bu birine yardımcı olur.


3
Bir yöntem kullanmamın nedeni, tek sorumluluk ilkesine saygı duymaktır. Kullanıcıyı elde etme şeklinizi izole etmezseniz, bir gün kimlik yönetiminden başka bir çözüm kullanmak gibi kullanıcı yönetim sisteminizi değiştirmeye karar verirseniz, bu acı verici olacaktır.
AdrienTorris

5

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

Olarak IddeğiştirildiUser.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,
        });
    }

Tepki:

resim açıklamasını buraya girin


Testime dayanarak this.User.Identity.Name, kullanıcı adı olma eğilimindedir. Testimde, kullanıcı adı bir e-postadır, kullanıcı kayıttan giriş yapar veya harici girişten giriş yapar (ör. Facebook, Google). Aşağıdaki kod userId değerini döndürür. Kimlik kullanıcı tablom, dolayısıyla int.Parse için otomatik olarak artırılmış bir birincil anahtar kullanıyorum. int userId = int.Parse(this.User.FindFirstValue(ClaimTypes.NameIdentifier));
Michael Buen

1
FindByIdAsynckullanıcı adı sağladığınız için çalışmıyor. Değiştirdiğinizde çalışır FindByNameAsync.
Jasper

4

içinde APiController

User.FindFirst(ClaimTypes.NameIdentifier).Value

Böyle bir şey iddiaları alacak


1

User.Identity.GetUserId ();

asp.net kimlik çekirdeği 2.0'da mevcut değildir. bu bakımdan farklı bir şekilde başardım. ben kullanıcı bilgi alma nedeniyle, tüm uygulama kullanımı için ortak bir sınıf yarattık.

ortak sınıf oluşturma PCommon ve arayüz IPCommon ekleme referansıusing 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();        
    }    
}

Burada ortak sınıfın uygulanması

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));
        }



    }
}

insert eyleminde userId ve name olsun

_iPCommon.GetUserId();

Teşekkürler Maksud


1
IHttpContextAccessor'ı Startup.cs dosyasına kaydettirmeniz gerekiyor mu?
REMESQ

1
Hayır REMESQ, ben başlangıçta bu enjekte etmedi, ama benim uygulama çalışma
Maksud

1

Jilet görünümlerinde geçerli kullanıcı kimliğini almak için, UserManager'ı görünüme şu şekilde enjekte edebiliriz:

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

Umarım faydalı bulursunuz.


0

kullanmak kullanabilir

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

herhangi bir nedenle NameIdentifier şimdi kullanıcı adını alır (.net core 2.2)


0

Diğer kişilerin profili üzerinde çalışan bir yönetici olarak ve üzerinde çalıştığınız profilin Kimliğini almanız gerekir, kimliğini yakalamak için bir ViewBag kullanabilirsiniz, örneğin ViewBag.UserId = userId; userId, üzerinde çalıştığınız yöntemin Parametre dizesidir.

    [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

Bunu ASP.NET MVC Denetleyicisi'nde istiyorsanız, şunu kullanın:

using Microsoft.AspNet.Identity;

User.Identity.GetUserId();

İfade eklemeniz gerekir usingçünkü GetUserId()onsuz orada olmaz.


2
Evet, ben "Microsoft.AspNet.Identity kullanarak" sahip soruya dahil.
Yazıdaki cevabımla

1
FWIW (şimdi) User.GetUserId()ve değilUser.Identity.GetUserId()
lc.

18
Soru, Microsoft.AspNetCore.Identity ad alanına sahip asp.net CORE oldu ve oldu; ve Microsoft.AspNet.Identity DEĞİL; Ve bu yeni ad alanını kullanarak NO GetUserId () uzantısı yöntemi vardır. BU CEVAP YANLIŞ!
Pascal

4
TÜM CAPS'ta kolay. Ve SO'da iyi olmayı öğrenin. stackoverflow.blog/2018/04/26/…
smoore4
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.