Rufen Sie den aktuellen Benutzer innerhalb einer ApiController-Aktion ab, ohne die Benutzer-ID als Parameter zu übergeben

97

Wie erhalten wir den aktuellen Benutzer innerhalb einer sicheren ApiController-Aktion, ohne den Benutzernamen oder die Benutzer-ID als Parameter zu übergeben?

Wir gehen davon aus, dass dies verfügbar ist, da wir uns in einer sicheren Aktion befinden. Wenn Sie sich in einer sicheren Aktion befinden, hat sich der Benutzer bereits authentifiziert und die Anfrage hat ihr Inhaber-Token. Da WebApi den Benutzer autorisiert hat, gibt es möglicherweise eine integrierte Möglichkeit, auf die Benutzer-ID zuzugreifen, ohne sie als Aktionsparameter übergeben zu müssen.

Shaun Luttin
quelle
Bitte sehen Sie diese Antwort: stackoverflow.com/a/26453782/3290276 Hinzufügen der Behauptung hat den Trick getan
Gabriela Macias

Antworten:

148

In WebApi 2 können Sie RequestContext.Principalinnerhalb einer Methode auf ApiController verwenden

Darrel Miller
quelle
1
Wir haben diese Eigenschaft anscheinend nicht. Hmm. Vielleicht verwenden wir eine alte Version von WebApi.
Shaun Luttin
2
@ShaunLuttin Ok, wenn Sie die Web-API 1 verwenden, gibt es meines Erachtens eine Prinicpal-Eigenschaft in ApiController. Dies ist nur ein ausgefallener Wrapper für den Zugriff auf die Request.Properties-Auflistung. Das Hauptobjekt wird in diesem Wörterbuch gespeichert.
Darrel Miller
6
Nur nicht vergessenusing Microsoft.AspNet.Identity;
Overlord
1
@DarrelMiller gibt es eine Möglichkeit, dasselbe (z. B. Anforderungskontext) aus anderen Teilen des Codes (nicht innerhalb des Controllers) abzurufen.
Ajay Aradhya
2
@ AjayAradhya Nur wenn Sie es dort übergeben. Frühere Bemühungen um Webframeworks haben gezeigt, dass die Verwendung statischer Eigenschaften für den Zugriff auf den Anforderungskontext alle Arten von Architekturproblemen verursacht. Es ist zunächst praktisch, aber es verursacht auf lange Sicht soooooo viel Schmerz.
Darrel Miller
35

Sie können auch über die UserEigenschaft auf auf den Principal zugreifen ApiController.

Die folgenden zwei Aussagen sind also grundsätzlich gleich:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();
Patrick
quelle
15
Ich versuche, das zu verwenden, was Sie hier geschrieben haben, aber die Funktion GetUserId () gibt immer null zurück. Der Benutzer ist autorisiert, ich übergebe ein Inhaber-Token und der ApiController hat den [Authorize] -Header
Joshua Ohana
Die Funktion GetUserId () gibt nur dann eine ID zurück, wenn der Benutzer einen NameIdentifier-Anspruch hat. Ein Beispiel für die Lösung dieses Problems finden Sie in
Oswaldos
14

Hinweis liegt in Webapi2 automatisch generierten Account Controller

Haben Sie diese Eigenschaft mit Getter definiert als

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

und um UserManager - In WebApi2 zu erhalten - tun Sie es wie Römer (gelesen als AccountController)

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

Dies sollte im IIS- und Self-Host-Modus kompatibel sein

Karan Bhandari
quelle
7

Keiner der oben genannten Vorschläge hat bei mir funktioniert. Folgendes hat getan!

HttpContext.Current.Request.LogonUserIdentity.Name

Ich denke, es gibt eine Vielzahl von Szenarien und diese hat für mich funktioniert. Mein Szenario umfasste ein AngularJS-Frontend und eine Web API 2-Backend-Anwendung, die beide unter IIS ausgeführt wurden. Ich musste beide Anwendungen so einstellen , dass sie ausschließlich unter Windows-Authentifizierung ausgeführt werden.

Keine Notwendigkeit, Benutzerinformationen weiterzugeben. Der Browser und IIS tauschen die angemeldeten Benutzeranmeldeinformationen aus, und die Web-API hat bei Bedarf Zugriff auf die Benutzeranmeldeinformationen (von IIS, nehme ich an).

Kannankeril
quelle
6

Karan Bhandaris Antwort ist gut, aber der in einem Projekt hinzugefügte AccountController ist sehr wahrscheinlich a Mvc.Controller. Um seine Antwort für die Verwendung in einem ApiController HttpContext.Current.GetOwinContext()zu konvertieren, ändern Sie diese Request.GetOwinContext()und stellen Sie sicher, dass Sie die folgenden 2 usingAnweisungen hinzugefügt haben :

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
Jeff Leach
quelle
4

Verwenden Sie User.Identity.Namein .Net Core , um den Namensanspruch des Benutzers abzurufen.

Venkatesh Muniyandi
quelle
2
User.Identity.NameRuft den Wert des Namensanspruchs ab . Es ist nicht Active Directory-spezifisch.
Nate Barbettini
@Nate Danke für Ihren Kommentar, ich habe es behoben
Venkatesh Muniyandi
3

Wenn Sie Asp.Identity UseManager verwenden, wird der Wert von automatisch festgelegt

RequestContext.Principal.Identity.GetUserId ()

basierend auf IdentityUser, den Sie beim Erstellen des IdentityDbContext verwenden .

Wenn Sie jemals eine benutzerdefinierte Benutzertabelle implementieren und eine Token-Inhaber-Authentifizierung besitzen, überprüfen Sie bitte meine Antwort.

Wie erhalte ich den Benutzerkontext während Web-API-Aufrufen?

Hoffe es hilft noch. :) :)

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

Oder verwenden Sie dies basierend auf Darrel Millers Kommentar, um zuerst den HttpContext abzurufen.

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

Siehe auch:

So greifen Sie über Ihre Web-API-Aktion auf HTTPContext zu

Shaun Luttin
quelle
5
Verwenden Sie HttpContext nicht, da dies Ihre Hosting-Optionen einschränkt und das Testen Ihres Codes erschwert.
Darrel Miller
Das HttpContext-Objekt wird nicht im Wörterbuch sein, wenn Sie Self-Host oder OwinHttpListener gehostet sind
Darrel Miller