Ich möchte einen aktuellen Benutzer zum Abrufen von Informationen eines Benutzers wie z. B. einer E-Mail erhalten. Aber das kann ich im asp.net-Kern nicht. Ich bin so verwirrt. Dies ist mein Code.
HttpContext
Im Konstruktor des Controllers ist fast null . Es ist nicht gut, einen Benutzer für jede Aktion zu gewinnen. Ich möchte einmal Informationen über den Benutzer erhalten und sie einstellen ViewData
.
public DashboardController()
{
var user = HttpContext.User.GetUserId();
}
c#
asp.net-core
asp.net-identity
Mehran Hafizi
quelle
quelle
Antworten:
EDIT für Konstruktor
Der folgende Code funktioniert:
Für RTM bearbeiten
Sie sollten sich registrieren
IHttpContextAccessor
:quelle
ClaimTypes.NameIdentifier
gibt die aktuelle Benutzer-ID undClaimTypes.Name
den Benutzernamen an.null
in meinem Fall zurück? Ich benutze.Net core 2.1 Web api
aber.Einfache Art und Weise, die funktioniert und ich habe überprüft.
dann können Sie alle Eigenschaften dieser Variablen wie
user.Email
. Ich hoffe das würde jemandem helfen.Bearbeiten :
Es ist eine scheinbar einfache, aber etwas komplizierte Ursache für verschiedene Arten von Authentifizierungssystemen in ASP.NET Core. Ich aktualisiere, weil einige Leute bekommen
null
.Für die JWT-Authentifizierung (getestet unter ASP.NET Core v3.0.0-Vorschau7):
quelle
Haben Sie eine andere Möglichkeit, den aktuellen Benutzer in Asp.NET Core zu finden - und ich glaube, ich habe es hier irgendwo auf SO ^^ gesehen
Dieser Code geht an den Controller namens DemoController. Funktioniert nicht ohne beide zu warten (wird nicht kompiliert);)
quelle
Ich muss sagen, dass ich ziemlich überrascht war, dass HttpContext im Konstruktor null ist. Ich bin sicher, es ist aus Leistungsgründen. Habe bestätigt, dass die Verwendung
IPrincipal
wie unten beschrieben in den Konstruktor injiziert wird. Es macht im Wesentlichen das Gleiche wie die akzeptierte Antwort, aber auf eine andere Art und Weise.Für alle, die diese Frage finden und nach einer Antwort auf das allgemeine "Wie bekomme ich den aktuellen Benutzer?" Suchen. Sie können einfach
User
direkt von zugreifenController.User
. Sie können dies jedoch nur innerhalb von Aktionsmethoden tun (ich gehe davon aus, dass Controller nicht nur mit HttpContexts und aus Leistungsgründen ausgeführt werden).Wenn Sie es jedoch im Konstruktor benötigen (wie es OP getan hat) oder andere injizierbare Objekte erstellen müssen, die den aktuellen Benutzer benötigen, ist das Folgende ein besserer Ansatz:
Injizieren Sie IPrincipal, um den Benutzer zu erhalten
Erstes Treffen
IPrincipal
undIIdentity
IPrincipal
undIIdentity
repräsentiert den Benutzer und den Benutzernamen. Wikipedia wird Sie trösten, wenn "Principal" seltsam klingt .Wichtig zu erkennen , dass , ob Sie es aus
IHttpContextAccessor.HttpContext.User
,ControllerBase.User
oderControllerBase.HttpContext.User
Sie bekommen ein Objekt , das eine sein , garantiertClaimsPrincipal
Objekt , das implementiertIPrincipal
.Es gibt derzeit keinen anderen Benutzertyp, den ASP.NET verwendet
User
(aber das heißt nicht, dass etwas anderes nicht implementiert werden kannIPrincipal
).Wenn Sie also etwas haben, das von 'dem aktuellen Benutzernamen' abhängt, den Sie injizieren möchten, sollten Sie injizieren
IPrincipal
und definitiv nichtIHttpContextAccessor
.Wichtig: Verschwenden Sie keine Zeit damit,
IPrincipal
direkt in Ihren Controller oder Ihre Aktionsmethode zu injizieren - dies ist sinnlos, daUser
es Ihnen dort bereits zur Verfügung steht.In
startup.cs
:Dann in Ihr DI-Objekt, das den Benutzer benötigt, injizieren Sie einfach,
IPrincipal
um den aktuellen Benutzer zu erhalten.Das Wichtigste dabei ist, wenn Sie Unit-Tests durchführen, müssen Sie keine senden
HttpContext
, sondern nur etwas verspotten, das darstellt,IPrincipal
was einfach sein kannClaimsPrincipal
.Eine besonders wichtige Sache, bei der ich mir nicht 100% sicher bin. Wenn Sie die tatsächlichen Ansprüche zugreifen müssen aus
ClaimsPrincipal
müssen Sie GussIPrincipal
zuClaimsPrincipal
. Dies ist in Ordnung, da wir zu 100% wissen, dass es zur Laufzeit von diesem Typ ist (da dies der FallHttpContext.User
ist). Eigentlich mache ich das einfach gerne im Konstruktor, da ich sicher schon weiß, dassIPrincipal
es eine sein wirdClaimsPrincipal
.Wenn Sie sich lustig machen, erstellen
ClaimsPrincipal
Sie einfach ein direktes und übergeben Sie es an alles, was Sie brauchenIPrincipal
.Warum es keine Schnittstelle gibt, weiß
IClaimsPrincipal
ich nicht genau . Ich gehe davon aus, dass MS entschieden hat, dassClaimsPrincipal
es sich nur um eine spezialisierte „Sammlung“ handelt, für die keine Schnittstelle erforderlich ist.quelle
null
für die injiziertIPrincipal
. Ich musste den vorübergehenden Dienst auch als…GetService<IHttpContextAccessor>()?.HttpContext.User…
(mit dem?
) hinzufügen, da er sonst abstürzen würde (GetService gab null zurück).services.AddTransient(provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
HttpContext.User ist ein ClaimsPrincipal.Es scheint, dass ab sofort (April 2017) Folgendes funktioniert:
Zumindest während eines
Controller
quelle
=>
verwendeten Operator noch nicht gesehen hat , wird er als "Ausdruckskörperdefinition" bezeichnet und in dieser Dokumentation beschrieben . Nur für den Fall, dass sich zukünftige Leute wie ich fragen.IIdentity
nach erfolgtstring
, wie auch im oberen Kommentar angegeben. Die Bearbeitung hat das einfach behoben. Ich bin mir auch nicht sicher, wie Sie zu Ihrer Schlussfolgerung gekommen sind (insbesondere, weil "Editor" -Punkte nur Benutzern mit einem Ruf von weniger als 2.000 Punkten gegeben werden).Vielleicht habe ich die Antwort nicht gesehen, aber so mache ich es.
Sie müssen diese Werte ändern
Startup.cs -> ConfigureServices (...)
MVC oder Web Api Controller
Controller-Methode:
Ergebnis ist Benutzername, zB = Domain \ Benutzername
quelle
Mein Problem bestand darin, auf den angemeldeten Benutzer als Objekt in der cshtml-Datei zuzugreifen. In Anbetracht der Tatsache, dass Sie den Benutzer in ViewData haben möchten, kann dieser Ansatz hilfreich sein:
In der cshtml-Datei
quelle
Zusätzlich zu den vorhandenen Antworten möchte ich hinzufügen, dass Sie auch eine Klasseninstanz für die gesamte App verfügbar haben können, die benutzerbezogene Daten wie
UserID
usw. enthält.Es kann nützlich sein , Refactoring z.B. Sie möchten nicht
UserID
jede Controller-Aktion abrufen undUserID
in jeder Methode, die sich auf Service Layer bezieht , einen zusätzlichen Parameter deklarieren .Ich habe recherchiert und hier ist mein Beitrag .
Sie erweitern einfach Ihre Klasse, von der Sie abgeleitet sind,
DbContext
indem Sie eineUserId
Eigenschaft hinzufügen (oder eine benutzerdefinierteSession
Klasse implementieren, die diese Eigenschaft hat).Auf Filterebene können Sie Ihre Klasseninstanz abrufen und den
UserId
Wert festlegen .Danach, wo immer Sie Ihre Instanz injizieren - sie hat die erforderlichen Daten (die Lebensdauer muss pro Anforderung sein , also registrieren Sie sie mit der
AddScoped
Methode).Arbeitsbeispiel:
Weitere Informationen finden Sie in meiner Antwort .
quelle
Nehmen
IdentityUser
würde auch funktionieren. Dies ist ein aktuelles Benutzerobjekt, und alle Benutzerwerte können abgerufen werden.quelle
Wenn Sie die gerüstete Identität verwenden und Asp.net Core 2.2+ verwenden, können Sie über eine Ansicht wie folgt auf den aktuellen Benutzer zugreifen:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio
quelle
Dies ist eine alte Frage, aber mein Fall zeigt, dass mein Fall hier nicht besprochen wurde.
Die Antwort von Simon_Weaver ( https://stackoverflow.com/a/54411397/2903893 ) gefällt mir am besten . Er erklärt ausführlich, wie man mit IPrincipal und IIdentity einen Benutzernamen erhält. Diese Antwort ist absolut richtig und ich empfehle diesen Ansatz. Während des Debuggens trat jedoch das Problem auf, dass ASP.NET das Dienstprinzip NICHT ordnungsgemäß ausfüllen kann . (oder mit anderen Worten, IPrincipal.Identity.Name ist null)
Es ist offensichtlich, dass MVC Framework, um den Benutzernamen zu erhalten, es von irgendwoher nehmen sollte. In der .NET-Welt verwendet ASP.NET oder ASP.NET Core die Open ID Connect-Middleware. Im einfachen Szenario authentifizieren Web-Apps einen Benutzer in einem Webbrowser. In diesem Szenario weist die Webanwendung den Browser des Benutzers an, sich bei Azure AD anzumelden. Azure AD gibt über den Browser des Benutzers eine Anmeldeantwort zurück, die Angaben zum Benutzer in einem Sicherheitstoken enthält. Damit es im Code für Ihre Anwendung funktioniert, müssen Sie die Berechtigung angeben, an die sich Ihre Web-App-Delegierten anmelden. Wenn Sie Ihre Webanwendung für Azure Service bereitstellen, besteht das übliche Szenario zur Erfüllung dieser Anforderungen darin, die Webanwendung zu konfigurieren: "App Services" -> YourApp -> Blade "Authentifizierung / Autorisierung" -> "App Service Authenticatio" = "On"https://github.com/Huachao/azure-content/blob/master/articles/app-service-api/app-service-api-authentication.md ). Ich glaube (dies ist meine Vermutung), dass der Assistent unter der Haube dieses Prozesses die "übergeordnete" Webkonfiguration dieser Web-App anpasst, indem er dieselben Einstellungen hinzufügt, die ich in den folgenden Absätzen zeige. Grundsätzlich besteht das Problem, warum dieser Ansatz in ASP.NET Core NICHT funktioniert, darin, dass die "übergeordnete" Computerkonfiguration von webconfig ignoriert wird. (Dies ist nicht 100% sicher, ich gebe nur die beste Erklärung, die ich habe). Damit es funktioniert, müssen Sie dies manuell in Ihrer App einrichten.
In diesem Artikel wird erläutert, wie Sie Ihre App für die Verwendung von Azure AD mehrfach einrichten. https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2
Schritt 1: Registrieren Sie das Beispiel bei Ihrem Azure AD-Mandanten. (Es ist offensichtlich, ich möchte meine Zeit nicht mit Erklärungen verbringen).
Schritt 2: Ersetzen Sie in der Datei appsettings.json den ClientID-Wert durch die Anwendungs-ID der Anwendung, die Sie in Schritt 1 im Anwendungsregistrierungsportal registriert haben. Ersetzen Sie den TenantId-Wert durch common
Schritt 3: Öffnen Sie die Datei Startup.cs und fügen Sie in der ConfigureServices-Methode nach der Zeile mit .AddAzureAD den folgenden Code ein, mit dem Ihre Anwendung Benutzer mit dem Azure AD v2.0-Endpunkt anmelden kann, dh sowohl Work als auch School und Microsoft Personal-Konten.
Zusammenfassung : Ich habe ein weiteres mögliches Problem aufgezeigt, das zu einem Fehler führen könnte, bei dem der Themenstarter erklärt wird. Der Grund für dieses Problem sind fehlende Konfigurationen für Azure AD (Open ID Middleware). Um dieses Problem zu lösen, schlage ich vor, "Authentifizierung / Autorisierung" manuell einzurichten. Die kurze Übersicht über die Einrichtung wird hinzugefügt.
quelle
Die meisten Antworten zeigen, wie man am besten mit
HttpContext
der Dokumentation umgeht, und das habe ich auch getan.Ich wollte erwähnen, dass Sie Ihre Projekteinstellungen beim Debuggen überprüfen möchten. Die Standardeinstellung ist
Enable Anonymous Authentication = true
.quelle
Ich habe meine Lösung
quelle