Obtenir l'utilisateur actuel, dans une action ApiController, sans passer l'ID utilisateur en tant que paramètre

97

Comment obtenir l'utilisateur actuel, dans une action ApiController sécurisée, sans passer le userName ou userId en tant que paramètre?

Nous supposons que cela est disponible, car nous sommes dans une action sécurisée. Être dans une action sécurisée signifie que l'utilisateur s'est déjà authentifié et que la demande a son jeton de support. Étant donné que WebApi a autorisé l'utilisateur, il peut y avoir un moyen intégré d'accéder à userId, sans avoir à le passer en tant que paramètre d'action.

Shaun Luttin
la source
S'il vous plaît, voir cette réponse: stackoverflow.com/a/26453782/3290276 Ajouter la revendication a fait l'affaire
Gabriela Macias

Réponses:

149

Dans WebApi 2, vous pouvez utiliser à RequestContext.Principalpartir d'une méthode sur ApiController

Darrel Miller
la source
1
Nous n'avons pas cette propriété, semble-t-il. Hmm. Peut-être que nous utilisons une ancienne version de WebApi.
Shaun Luttin
2
@ShaunLuttin Ok, donc si vous utilisez l'API Web 1, je crois qu'il existe une propriété Prinicpal sur ApiController. Ceci est juste un wrapper sophistiqué pour accéder à la collection Request.Properties. L'objet principal est stocké dans ce dictionnaire.
Darrel Miller
6
N'oubliez pasusing Microsoft.AspNet.Identity;
Overlord
1
@DarrelMiller existe-t-il un moyen d'obtenir la même chose (disons le contexte de la demande) à partir d'autres parties du code (pas dans le contrôleur).
Ajay Aradhya
2
@AjayAradhya Seulement si vous le passez là-bas. Des efforts antérieurs sur les frameworks Web ont montré que l'utilisation de propriétés statiques pour accéder au contexte de requête provoque toutes sortes de problèmes d'architecture. C'est pratique au début, mais cela cause tellement de douleur à long terme.
Darrel Miller
36

Vous pouvez également accéder au principal en utilisant la Userpropriété sur ApiController.

Les deux déclarations suivantes sont donc fondamentalement les mêmes:

string id;
id = User.Identity.GetUserId();
id = RequestContext.Principal.Identity.GetUserId();
Patrick
la source
15
J'essaye d'utiliser ce que vous avez écrit ici mais la fonction GetUserId () renvoie toujours null. L'utilisateur est authentifié, je passe un jeton de porteur et l'ApiController a l'en-tête [Authorize]
Joshua Ohana
La fonction GetUserId () renvoie un ID uniquement si l'utilisateur a une revendication NameIdentifier. Pour un exemple de résolution de ce problème, reportez-vous à la réponse d'Oswaldo ici: stackoverflow.com/questions/19505526
jramm
14

Un indice réside dans le contrôleur de compte généré automatiquement par Webapi2

Définissez cette propriété avec getter comme

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

et pour obtenir UserManager - Dans WebApi2 - faites comme les Romains (lisez comme AccountController)

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

Cela devrait être compatible en mode IIS et auto-hôte

Karan Bhandari
la source
7

Aucune des suggestions ci-dessus n'a fonctionné pour moi. Ce qui suit a fait!

HttpContext.Current.Request.LogonUserIdentity.Name

Je suppose qu'il existe une grande variété de scénarios et celui-ci a fonctionné pour moi. Mon scénario impliquait un frontend AngularJS et une application backend Web API 2, tous deux fonctionnant sous IIS. J'ai dû configurer les deux applications pour qu'elles s'exécutent exclusivement sous l'authentification Windows.

Pas besoin de transmettre des informations utilisateur. Le navigateur et IIS échangent les informations d'identification de l'utilisateur connecté et l'API Web a accès aux informations d'identification de l'utilisateur à la demande (à partir d'IIS, je présume).

kannankeril
la source
6

La réponse de Karan Bhandari est bonne, mais le AccountController ajouté dans un projet est très probablement un Mvc.Controller. Pour convertir sa réponse pour une utilisation dans un ApiController changez HttpContext.Current.GetOwinContext()en Request.GetOwinContext()et assurez-vous d'avoir ajouté les 2 usinginstructions suivantes:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
Jeff Leach
la source
5

Dans .Net Core, utilisez User.Identity.Namepour obtenir la revendication de nom de l'utilisateur.

Venkatesh Muniyandi
la source
2
User.Identity.Nameobtient la valeur de la revendication de nom . Ce n'est pas spécifique à Active Directory.
Nate Barbettini
@Nate Merci pour votre commentaire, je l'ai corrigé
Venkatesh Muniyandi
3

Si vous utilisez Asp.Identity UseManager, il définit automatiquement la valeur de

RequestContext.Principal.Identity.GetUserId ()

basé sur IdentityUser que vous utilisez pour créer IdentityDbContext .

Si jamais vous implémentez une table utilisateur personnalisée et une authentification du porteur de jeton owin, veuillez vérifier ma réponse.

Comment obtenir le contexte utilisateur lors des appels Web Api?

J'espère que ça aide encore. :)

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

Ou sur la base du commentaire de Darrel Miller, utilisez peut-être ceci pour récupérer d'abord le HttpContext.

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

Voir également:

Comment accéder à HTTPContext depuis votre action d'API Web

Shaun Luttin
la source
5
N'utilisez pas HttpContext car cela limite vos options d'hébergement et rend votre code difficile à tester.
Darrel Miller
L'objet HttpContext ne sera pas dans le dictionnaire si vous êtes Self-host ou OwinHttpListener hébergé
Darrel Miller