Dapatkan pengguna saat ini, dalam tindakan ApiController, tanpa meneruskan userID sebagai parameter

97

Bagaimana kita mendapatkan pengguna saat ini, dalam tindakan ApiController yang aman, tanpa meneruskan userName atau userId sebagai parameter?

Kami berasumsi bahwa ini tersedia, karena kami berada dalam tindakan yang aman. Berada dalam tindakan aman berarti pengguna telah mengautentikasi dan permintaan memiliki token pembawa-nya. Mengingat bahwa WebApi telah mengotorisasi pengguna, mungkin ada cara bawaan untuk mengakses userId, tanpa harus meneruskannya sebagai parameter tindakan.

Shaun Luttin
sumber
Silakan, lihat Jawaban ini: stackoverflow.com/a/26453782/3290276 Tambahkan klaim melakukan trik
Gabriela Macias

Jawaban:

149

Di WebApi 2 Anda bisa menggunakan RequestContext.Principaldari dalam metode di ApiController

Darrel Miller
sumber
1
Sepertinya kami tidak memiliki properti itu. Hmm. Mungkin kami menggunakan WebApi versi lama.
Shaun Luttin
2
@ShaunLuttin Ok, jadi jika Anda menggunakan API Web 1 maka Anda saya yakin ada properti Prinicpal di ApiController. Ini hanyalah pembungkus mewah untuk mengakses koleksi Request.Properties. Objek utama disimpan dalam kamus itu.
Darrel Miller
6
Jangan lupausing Microsoft.AspNet.Identity;
Overlord
1
@Darreliller apakah ada cara untuk mendapatkan hal yang sama (katakanlah konteks permintaan) dari bagian lain dari kode (bukan dalam pengontrol).
Ajay Aradhya
2
@AjayAradhya Hanya jika Anda lulus di sana. Upaya sebelumnya pada kerangka web telah menunjukkan bahwa menggunakan properti statis untuk mengakses konteks permintaan menyebabkan semua jenis masalah arsitektur. Ini nyaman pada awalnya tapi itu menyebabkan rasa sakit yang sangat besar dalam jangka panjang.
Darrel Miller
36

Anda juga dapat mengakses kepala sekolah menggunakan Userproperti di ApiController.

Jadi dua pernyataan berikut pada dasarnya sama:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();
Patrick
sumber
15
Saya mencoba menggunakan apa yang Anda tulis di sini tetapi fungsi GetUserId () selalu mengembalikan null. Pengguna diautentikasi, saya meneruskan token pembawa, dan ApiController memiliki header [Otorisasi]
Joshua Ohana
Fungsi GetUserId () mengembalikan ID hanya jika pengguna memiliki klaim NameIdentifier. Untuk contoh bagaimana menyelesaikan ini, lihat jawaban Oswaldo di sini: stackoverflow.com/questions/19505526
jramm
14

Petunjuk terletak pada pengontrol akun yang dibuat otomatis Webapi2

Tetapkan properti ini dengan getter sebagai

public string UserIdentity
        {
            get
            {
                var user = UserManager.FindByName(User.Identity.Name);
                return user;//user.Email
            }
        }

dan untuk mendapatkan UserManager - Dalam WebApi2-lakukan seperti yang dilakukan Roma (baca sebagai AccountController)

public ApplicationUserManager UserManager
        {
            get { return HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
        }

Ini harus kompatibel dalam IIS dan mode self host

Karan Bhandari
sumber
7

Tidak ada saran di atas yang berhasil untuk saya. Berikut ini lakukan!

HttpContext.Current.Request.LogonUserIdentity.Name

Saya kira ada banyak variasi skenario dan yang satu ini berhasil untuk saya. Skenario saya melibatkan frontend AngularJS dan aplikasi backend Web API 2, keduanya berjalan di bawah IIS. Saya harus mengatur kedua aplikasi untuk berjalan secara eksklusif di bawah Otentikasi Windows.

Tidak perlu memberikan informasi pengguna apa pun. Browser dan IIS pertukaran kredensial pengguna logon dan API Web memiliki akses ke kredensial pengguna sesuai permintaan (dari IIS saya kira).

kannankeril.dll
sumber
6

Jawaban Karan Bhandari bagus, tetapi AccountController yang ditambahkan dalam sebuah proyek sangat mungkin a Mvc.Controller. Untuk mengkonversi jawabannya untuk digunakan dalam perubahan ApiController HttpContext.Current.GetOwinContext()untuk Request.GetOwinContext()dan pastikan Anda telah menambahkan 2 berikut usingpernyataan:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
Jeff Leach
sumber
5

Dalam .Net Core digunakan User.Identity.Nameuntuk mendapatkan klaim Nama pengguna.

Venkatesh Muniyandi
sumber
2
User.Identity.Namemendapatkan nilai dari klaim nama . Ini bukan khusus Active Directory.
Nate Barbettini
@Nate Terima kasih atas komentar Anda, saya telah memperbaikinya
Venkatesh Muniyandi
3

Jika Anda menggunakan Asp.Identity UseManager, ini otomatis menetapkan nilai

RequestContext.Principal.Identity.GetUserId ()

berdasarkan IdentityUser yang Anda gunakan dalam membuat IdentityDbContext .

Jika pernah Anda menerapkan tabel pengguna khusus dan otentikasi pembawa token owin, silakan periksa jawaban saya.

Bagaimana cara mendapatkan konteks pengguna selama panggilan Api Web?

Semoga masih membantu. :)

pampi
sumber
1
string userName;
string userId;
if (HttpContext.Current != null && HttpContext.Current.User != null 
        && HttpContext.Current.User.Identity.Name != null)
{
    userName = HttpContext.Current.User.Identity.Name;
    userId = HttpContext.Current.User.Identity.GetUserId();
}

Atau berdasarkan komentar Darrel Miller, mungkin gunakan ini untuk mengambil HttpContext terlebih dahulu.

// get httpContext
object httpContext;
actionContext.Request.Properties.TryGetValue("MS_HttpContext", out httpContext);    

Lihat juga:

Cara mengakses HTTPContext dari dalam tindakan API Web Anda

Shaun Luttin
sumber
5
Jangan gunakan HttpContext karena membatasi opsi hosting Anda dan membuat kode Anda sulit diuji.
Darrel Miller
Objek HttpContext tidak akan ada dalam kamus jika Anda adalah Self-host, atau OwinHttpListener dihosting
Darrel Miller