Saya ingin mendapatkan pengguna saat ini untuk mendapatkan informasi pengguna seperti email. Tapi saya tidak bisa melakukan itu di inti asp.net. Saya sangat bingung Ini adalah kode saya.
HttpContext
hampir nol dalam konstruktor pengontrol. Tidak baik mendapatkan pengguna di setiap tindakan. Saya Ingin mendapatkan informasi pengguna sekali dan mengaturnya menjadi ViewData
;
public DashboardController()
{
var user = HttpContext.User.GetUserId();
}
c#
asp.net-core
asp.net-identity
Mehran Hafizi
sumber
sumber
Jawaban:
EDIT untuk konstruktor
Kode di bawah ini berfungsi:
Edit untuk RTM
Anda harus mendaftar
IHttpContextAccessor
:sumber
ClaimTypes.NameIdentifier
memberikan id pengguna saat ini, danClaimTypes.Name
memberikan nama pengguna.null
dalam kasus saya? Saya menggunakan.Net core 2.1 Web api
sekalipun.Cara sederhana yang berhasil dan saya periksa.
maka Anda dapat semua properti variabel ini seperti
user.Email
. Saya harap ini akan membantu seseorang.Edit :
Ini adalah hal yang tampaknya sederhana tetapi agak rumit karena berbagai jenis sistem otentikasi di ASP.NET Core. Saya memperbarui karena beberapa orang mendapatkan
null
.Untuk JWT Authentication (Diuji pada ASP.NET Core v3.0.0-preview7):
sumber
Memiliki cara lain untuk mendapatkan pengguna saat ini di Asp.NET Core - dan saya rasa saya melihatnya di suatu tempat di sini, di SO ^^
Kode itu masuk ke pengontrol bernama DemoController. Tidak akan berfungsi tanpa kedua await (tidak akan dikompilasi);)
sumber
Saya harus mengatakan saya cukup terkejut bahwa HttpContext adalah null di dalam konstruktor. Saya yakin itu untuk alasan kinerja. Telah mengkonfirmasikan bahwa menggunakan
IPrincipal
seperti yang dijelaskan di bawah ini berhasil memasukkannya ke dalam konstruktor. Ini pada dasarnya melakukan hal yang sama seperti jawaban yang diterima, tetapi dengan cara yang lebih antarmuka.Bagi siapa pun yang menemukan pertanyaan ini mencari jawaban untuk pertanyaan umum "Bagaimana cara mendapatkan pengguna saat ini?" Anda dapat
User
langsung mengaksesnya dariController.User
. Tetapi Anda hanya dapat melakukan ini di dalam metode tindakan (saya berasumsi karena pengontrol tidak hanya berjalan dengan HttpContexts dan untuk alasan kinerja).Namun - jika Anda membutuhkannya di konstruktor (seperti yang dilakukan OP) atau perlu membuat objek injeksi lain yang membutuhkan pengguna saat ini, maka di bawah ini adalah pendekatan yang lebih baik:
Masukkan IPrincipal untuk mendapatkan pengguna
Pertama bertemu
IPrincipal
danIIdentity
IPrincipal
danIIdentity
mewakili pengguna dan nama pengguna. Wikipedia akan menghibur Anda jika 'Kepala Sekolah' terdengar aneh .Penting untuk disadari bahwa baik Anda mendapatkannya dari
IHttpContextAccessor.HttpContext.User
,ControllerBase.User
atauControllerBase.HttpContext.User
Anda mendapatkan suatu objek yang dijamin menjadiClaimsPrincipal
objek yang diimplementasikanIPrincipal
.Tidak ada jenis Pengguna lain yang digunakan ASP.NET untuk
User
saat ini, (tetapi itu tidak berarti hal lain tidak dapat diterapkanIPrincipal
).Jadi jika Anda memiliki sesuatu yang memiliki ketergantungan 'nama pengguna saat ini' yang ingin Anda suntikkan, Anda harus menyuntikkan
IPrincipal
dan tentu saja tidakIHttpContextAccessor
.Penting: Jangan buang waktu untuk menyuntikkan
IPrincipal
langsung ke pengontrol Anda, atau metode tindakan - tidak ada gunanya karenaUser
sudah tersedia untuk Anda di sana.Masuk
startup.cs
:Kemudian di objek DI Anda yang membutuhkan pengguna, Anda baru saja menyuntikkan
IPrincipal
untuk mendapatkan pengguna saat ini.Hal yang paling penting di sini adalah jika Anda melakukan pengujian unit, Anda tidak perlu mengirimkannya
HttpContext
, tetapi hanya perlu mengejek sesuatu yang mewakiliIPrincipal
yang sebenarnya bisa jadiClaimsPrincipal
.Satu hal ekstra penting yang saya tidak 100% yakin. Jika Anda perlu untuk mengakses klaim yang sebenarnya dari
ClaimsPrincipal
yang Anda butuhkan untuk corIPrincipal
untukClaimsPrincipal
. Ini baik-baik saja karena kita tahu 100% bahwa pada waktu proses itu dari jenis itu (karena itulahHttpContext.User
). Saya sebenarnya suka melakukan ini di konstruktor karena saya sudah tahu pasti ada yangIPrincipal
akan menjadiClaimsPrincipal
.Jika Anda sedang mengejek, buat
ClaimsPrincipal
saja langsung dan berikan ke apa punIPrincipal
.Persisnya mengapa tidak ada antarmuka untuk
IClaimsPrincipal
Saya tidak yakin. Saya berasumsi MS memutuskanClaimsPrincipal
itu hanya 'koleksi' khusus yang tidak memerlukan antarmuka.sumber
null
suntikanIPrincipal
. Saya juga perlu menambahkan layanan sementara sebagai…GetService<IHttpContextAccessor>()?.HttpContext.User…
(dengan?
) karena akan macet jika tidak (GetService mengembalikan null).services.AddTransient(provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
karena HttpContext.User adalah ClaimsPrincipal.Tampaknya mulai sekarang (April 2017) yang berfungsi sebagai berikut:
Setidaknya selama dalam a
Controller
sumber
=>
operator menggunakan seperti ini sebelumnya, ini disebut "Definisi Tubuh Ekspresi" dan dijelaskan dalam dokumentasi ini . Kalau-kalau orang masa depan seperti saya bertanya-tanya.IIdentity
kestring
, seperti yang juga dinyatakan di komentar teratas. Hasil edit hanya memperbaikinya. Saya juga tidak yakin bagaimana Anda mencapai kesimpulan Anda (khususnya karena poin "editor" hanya diberikan kepada pengguna di bawah reputasi 2k).Mungkin saya tidak melihat jawabannya, tetapi beginilah cara saya melakukannya.
Anda harus mengubah nilai-nilai ini
Startup.cs -> ConfigureServices (...)
MVC atau Pengontrol Api Web
Metode pengontrol:
Hasilnya adalah nama pengguna misalnya = Domain \ nama pengguna
sumber
Masalah saya adalah mengakses Pengguna yang masuk sebagai objek di file cshtml. Mengingat Anda menginginkan pengguna di ViewData, pendekatan ini mungkin bisa membantu:
Di file cshtml
sumber
Selain jawaban yang ada, saya ingin menambahkan bahwa Anda juga dapat memiliki instance kelas yang tersedia di seluruh aplikasi yang menyimpan data terkait pengguna seperti
UserID
dll.Mungkin berguna untuk refactoring mis. Anda tidak ingin mengambil
UserID
setiap tindakan pengontrol dan mendeklarasikanUserID
parameter tambahan di setiap metode yang terkait dengan Lapisan Layanan.Saya telah melakukan penelitian dan inilah postingan saya .
Anda hanya perlu memperluas kelas yang Anda peroleh
DbContext
dengan menambahkanUserId
properti (atau menerapkanSession
kelas kustom yang memiliki properti ini).Pada tingkat filter, Anda dapat mengambil instance kelas Anda dan menetapkan
UserId
nilai.Setelah itu di mana pun Anda memasukkan instance - itu akan memiliki data yang diperlukan (masa hidup harus sesuai permintaan , jadi Anda mendaftarkannya menggunakan
AddScoped
metode).Contoh kerja:
Untuk informasi lebih lanjut lihat jawaban saya .
sumber
Mengambil
IdentityUser
juga akan berhasil. Ini adalah objek pengguna saat ini dan semua nilai pengguna dapat diambil.sumber
Jika Anda menggunakan Identitas scafold dan menggunakan Asp.net Core 2.2+, Anda dapat mengakses pengguna saat ini dari tampilan seperti ini:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio
sumber
Ini pertanyaan lama tetapi kasus saya menunjukkan bahwa kasus saya tidak dibahas di sini.
Saya paling suka jawaban Simon_Weaver ( https://stackoverflow.com/a/54411397/2903893 ). Ia menjelaskan secara detail bagaimana cara mendapatkan nama pengguna menggunakan IPrincipal dan IIdentity. Jawaban ini sepenuhnya benar dan saya merekomendasikan untuk menggunakan pendekatan ini. Namun, selama debugging saya mengalami masalah ketika ASP.NET TIDAK dapat mengisi prinsip layanan dengan benar . (atau dengan kata lain, IPrincipal.Identity.Name adalah null)
Jelas bahwa untuk mendapatkan kerangka kerja MVC nama pengguna harus mengambilnya dari suatu tempat. Di dunia .NET, ASP.NET atau ASP.NET Core menggunakan middleware Open ID Connect. Dalam skenario sederhana, aplikasi web mengautentikasi pengguna di browser web. Dalam skenario ini, aplikasi web mengarahkan browser pengguna untuk masuk ke Azure AD. Azure AD mengembalikan respons masuk melalui browser pengguna, yang berisi klaim tentang pengguna dalam token keamanan. Untuk membuatnya berfungsi dalam kode untuk aplikasi Anda, Anda harus memberikan otoritas kepada mana delegasi aplikasi web Anda masuk. Saat Anda menerapkan aplikasi web Anda ke Azure Service, skenario umum untuk memenuhi persyaratan ini adalah dengan mengonfigurasi aplikasi web: "Layanan Aplikasi" -> Aplikasi Anda -> "Otentikasi / Otorisasi" blade -> "Autentikasi Layanan Aplikasi" = "Aktif"https://github.com/Huachao/azure-content/blob/master/articles/app-service-api/app-service-api-authentication.md ). Saya percaya (ini adalah tebakan saya) bahwa di balik proses ini, wizard menyesuaikan konfigurasi web "induk" dari aplikasi web ini dengan menambahkan pengaturan yang sama dengan yang saya tunjukkan di paragraf berikut. Pada dasarnya, masalah mengapa pendekatan ini TIDAK berfungsi di ASP.NET Core adalah karena konfigurasi mesin "induk" diabaikan oleh webconfig. (ini belum 100% yakin, saya hanya memberikan penjelasan terbaik yang saya miliki). Jadi, untuk membuatnya bekerja, Anda perlu mengatur ini secara manual di aplikasi Anda.
Berikut adalah artikel yang menjelaskan cara banyak mengatur aplikasi Anda untuk menggunakan Azure AD. https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2
Langkah 1: Daftarkan sampel dengan penyewa Azure AD Anda. (sudah jelas, saya tidak ingin menghabiskan waktu penjelasan saya).
Langkah 2: Di file appsettings.json: ganti nilai ClientID dengan ID Aplikasi dari aplikasi yang Anda daftarkan di portal Pendaftaran Aplikasi pada Langkah 1. ganti nilai TenantId dengan common
Langkah 3: Buka file Startup.cs dan dalam metode ConfigureServices, setelah baris yang berisi .AddAzureAD masukkan kode berikut, yang memungkinkan aplikasi Anda memasukkan pengguna dengan titik akhir Azure AD v2.0, yaitu Work and School dan Akun Microsoft Personal.
Ringkasan : Saya telah menunjukkan satu lagi kemungkinan masalah yang dapat menyebabkan kesalahan sehingga topik pembuka dijelaskan. Alasan masalah ini adalah tidak adanya konfigurasi untuk Azure AD (Open ID middleware). Untuk mengatasi masalah ini saya mengusulkan pengaturan secara manual "Otentikasi / Otorisasi". Tinjauan singkat tentang cara menyiapkan ini ditambahkan.
sumber
Sebagian besar jawaban menunjukkan cara terbaik menangani
HttpContext
dari dokumentasi, yang juga saya gunakan.Saya ingin menyebutkan bahwa Anda ingin memeriksa pengaturan proyek Anda saat debugging, defaultnya adalah
Enable Anonymous Authentication = true
.sumber
Saya mendapatkan solusi saya
sumber