Je souhaite obtenir un utilisateur actuel pour obtenir des informations sur un utilisateur, comme un e-mail. Mais je ne peux pas faire cela dans le noyau asp.net. Je suis tellement confus C'est mon code.
HttpContext
presque est nul dans le constructeur du contrôleur. Il n'est pas bon d'avoir un utilisateur dans chaque action. Je veux obtenir des informations sur l'utilisateur une fois et les définir dans ViewData
;
public DashboardController()
{
var user = HttpContext.User.GetUserId();
}
c#
asp.net-core
asp.net-identity
Mehran Hafizi
la source
la source
Réponses:
EDIT pour le constructeur
Le code ci-dessous fonctionne:
Modifier pour RTM
Vous devez vous inscrire
IHttpContextAccessor
:la source
ClaimTypes.NameIdentifier
donne l'ID utilisateur actuel etClaimTypes.Name
donne le nom d'utilisateur.null
dans mon cas? J'utilise.Net core 2.1 Web api
cependant.Manière simple qui fonctionne et j'ai vérifié.
alors vous pouvez toutes les propriétés de ces variables comme
user.Email
. J'espère que cela aiderait quelqu'un.Modifier :
C'est une chose apparemment simple mais un peu compliquée à cause des différents types de systèmes d'authentification dans ASP.NET Core. Je mets à jour parce que certaines personnes obtiennent
null
.Pour l'authentification JWT (testée sur ASP.NET Core v3.0.0-preview7):
la source
J'ai un autre moyen d'obtenir l'utilisateur actuel dans Asp.NET Core - et je pense que je l'ai vu quelque part ici, sur SO ^^
Ce code va au contrôleur nommé DemoController. Ne fonctionnera pas sans attendre les deux (ne compilera pas);)
la source
Je dois dire que j'ai été assez surpris que HttpContext soit nul à l'intérieur du constructeur. Je suis sûr que c'est pour des raisons de performance. Avoir confirmé que l'utilisation
IPrincipal
comme décrit ci-dessous l'injecte dans le constructeur. Il fait essentiellement la même chose que la réponse acceptée, mais d'une manière plus interface.Pour tous ceux qui trouvent cette question à la recherche d'une réponse au générique "Comment obtenir l'utilisateur actuel?" vous pouvez simplement accéder
User
directement à partir deController.User
. Mais vous ne pouvez le faire qu'à l'intérieur des méthodes d'action (je suppose que les contrôleurs ne fonctionnent pas uniquement avec HttpContexts et pour des raisons de performances).Cependant - si vous en avez besoin dans le constructeur (comme OP l'a fait) ou si vous devez créer d'autres objets injectables qui ont besoin de l'utilisateur actuel, alors la solution ci-dessous est une meilleure approche:
Injectez IPrincipal pour obtenir l'utilisateur
Première rencontre
IPrincipal
etIIdentity
IPrincipal
etIIdentity
représente l'utilisateur et le nom d'utilisateur. Wikipedia vous réconfortera si «Principal» semble étrange .Il est important de se rendre compte que si vous l' obtenez à partir
IHttpContextAccessor.HttpContext.User
,ControllerBase.User
ouControllerBase.HttpContext.User
vous faire un objet qui est garanti d'être unClaimsPrincipal
objet qui met en œuvreIPrincipal
.Il n'y a aucun autre type d'utilisateur utilisé par ASP.NET pour
User
le moment (mais cela ne veut pas dire que quelque chose d'autre ne pourrait pas être implémentéIPrincipal
).Donc, si vous avez quelque chose qui a une dépendance du «nom d'utilisateur actuel» que vous voulez injecter, vous devriez l'injecter
IPrincipal
et certainement pasIHttpContextAccessor
.Important: ne perdez pas de temps à injecter
IPrincipal
directement dans votre manette ou votre méthode d'action - c'est inutile carUser
vous y êtes déjà disponible.Dans
startup.cs
:Ensuite, dans votre objet DI qui a besoin de l'utilisateur que vous venez d'injecter
IPrincipal
pour obtenir l'utilisateur actuel.La chose la plus importante ici est que si vous faites des tests unitaires, vous n'avez pas besoin d'envoyer un
HttpContext
, mais seulement de vous moquer de quelque chose qui représenteIPrincipal
ce qui peut simplement êtreClaimsPrincipal
.Une chose supplémentaire importante dont je ne suis pas sûr à 100%. Si vous avez besoin d'accéder aux demandes d' indemnités de
ClaimsPrincipal
vous devez convertirIPrincipal
àClaimsPrincipal
. C'est très bien car nous savons à 100% qu'au moment de l'exécution, c'est de ce type (puisque c'est ce quiHttpContext.User
est). En fait, j'aime faire cela dans le constructeur car je sais déjà avec certitude que toutIPrincipal
sera un fichierClaimsPrincipal
.Si vous vous moquez, créez
ClaimsPrincipal
simplement un directement et transmettez-le à tout ce qui prendIPrincipal
.Exactement pourquoi il n'y a pas d'interface pour
IClaimsPrincipal
je ne suis pas sûr. Je suppose que MS a décidé que ceClaimsPrincipal
n'était qu'une «collection» spécialisée qui ne justifiait pas une interface.la source
null
pour l'injectionIPrincipal
. J'avais également besoin d'ajouter le service transitoire en tant que…GetService<IHttpContextAccessor>()?.HttpContext.User…
(avec le?
) car il planterait sinon (GetService retournait null).services.AddTransient(provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
comme HttpContext.User est un ClaimsPrincipal.Il semblerait qu'à partir de maintenant (avril 2017), ce qui suit fonctionne:
Au moins dans un
Controller
la source
=>
opérateur utilisé comme ça auparavant, cela s'appelle une "Définition du corps d'expression" et est décrit dans cette documentation . Juste au cas où de futurs gens comme moi se demanderaient.IIdentity
enstring
, comme indiqué également dans le commentaire supérieur. La modification a simplement corrigé cela. Je ne sais pas non plus comment vous êtes parvenu à votre conclusion (d'autant plus que les points "éditeur" ne sont attribués qu'aux utilisateurs ayant une réputation inférieure à 2k).Peut-être que je n'ai pas vu la réponse, mais c'est ainsi que je le fais.
Vous devez avoir changé ces valeurs
Startup.cs -> Configurer les services (...)
Contrôleur MVC ou Web Api
Méthode de contrôleur:
Le résultat est userName, par exemple = Domaine \ nom d'utilisateur
la source
Mon problème était d'accéder à l'utilisateur connecté en tant qu'objet dans le fichier cshtml. Considérant que vous vouliez l'utilisateur dans ViewData, cette approche peut être utile:
Dans le fichier cshtml
la source
En plus des réponses existantes, j'aimerais ajouter que vous pouvez également disposer d'une instance de classe disponible à l'échelle de l'application qui contient des données relatives à l'utilisateur, telles que
UserID
etc.Cela peut être utile pour refactoriser par ex. vous ne voulez pas récupérer
UserID
dans chaque action du contrôleur et déclarer unUserID
paramètre supplémentaire dans chaque méthode liée à la couche de service.J'ai fait une recherche et voici mon message .
Vous étendez simplement votre classe dont vous dérivez
DbContext
en ajoutant uneUserId
propriété (ou en implémentez uneSession
classe personnalisée qui a cette propriété).Au niveau du filtre, vous pouvez récupérer votre instance de classe et définir la
UserId
valeur.Après cela, partout où vous injectez votre instance - elle aura les données nécessaires (la durée de vie doit être par requête , vous l'enregistrez donc à l'aide de
AddScoped
method).Exemple de travail:
Pour plus d'informations, consultez ma réponse .
la source
Prendre
IdentityUser
fonctionnerait également. Il s'agit d'un objet utilisateur actuel et toutes les valeurs de l'utilisateur peuvent être récupérées.la source
Si vous utilisez l' identité scafolded et que vous utilisez Asp.net Core 2.2+, vous pouvez accéder à l'utilisateur actuel à partir d'une vue comme celle-ci:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio
la source
C'est une vieille question mais mon cas montre que mon cas n'a pas été discuté ici.
J'aime le plus la réponse de Simon_Weaver ( https://stackoverflow.com/a/54411397/2903893 ). Il explique en détail comment obtenir le nom d'utilisateur en utilisant IPrincipal et IIdentity. Cette réponse est absolument correcte et je recommande d'utiliser cette approche. Cependant, pendant le débogage, j'ai rencontré le problème lorsque ASP.NET ne peut PAS remplir correctement le principe de service . (ou en d'autres termes, IPrincipal.Identity.Name est nul)
Il est évident que pour obtenir le nom d'utilisateur, le framework MVC doit le prendre quelque part. Dans le monde .NET, ASP.NET ou ASP.NET Core utilise le middleware Open ID Connect. Dans le scénario simple, les applications Web authentifient un utilisateur dans un navigateur Web. Dans ce scénario, l'application Web demande au navigateur de l'utilisateur de se connecter à Azure AD. Azure AD renvoie une réponse de connexion via le navigateur de l'utilisateur, qui contient des revendications sur l'utilisateur dans un jeton de sécurité. Pour que cela fonctionne dans le code de votre application, vous devez fournir l'autorité à laquelle vous déléguez la connexion de l'application Web. Lorsque vous déployez votre application Web sur Azure Service, le scénario courant pour répondre à ces exigences consiste à configurer l'application Web: "App Services" -> YourApp -> Blade "Authentication / Authorization" -> "App Service Authenticatio" = "On"https://github.com/Huachao/azure-content/blob/master/articles/app-service-api/app-service-api-authentication.md ). Je crois (c'est ma supposition éclairée) que sous le capot de ce processus, l'assistant ajuste la configuration Web "parent" de cette application Web en ajoutant les mêmes paramètres que ceux que je montre dans les paragraphes suivants. Fondamentalement, le problème pour lequel cette approche ne fonctionne PAS dans ASP.NET Core est que la configuration de la machine "parente" est ignorée par webconfig. (ce n'est pas sûr à 100%, je donne juste la meilleure explication que j'ai). Donc, pour que cela fonctionne, vous devez le configurer manuellement dans votre application.
Voici un article qui explique comment configurer plusieurs fois votre application pour utiliser Azure AD. https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2
Étape 1: inscrivez l'exemple auprès de votre locataire Azure AD. (c'est évident, je ne veux pas passer mon temps aux explications).
Étape 2: Dans le fichier appsettings.json: remplacez la valeur ClientID par l'ID d'application de l'application que vous avez enregistrée dans le portail d'inscription des applications à l'étape 1. remplacez la valeur TenantId par common
Étape 3: ouvrez le fichier Startup.cs et dans la méthode ConfigureServices, après la ligne contenant .AddAzureAD, insérez le code suivant, qui permet à votre application de connecter des utilisateurs avec le point de terminaison Azure AD v2.0, qui est à la fois professionnel et scolaire et Comptes personnels Microsoft.
Résumé : J'ai montré un autre problème possible qui pourrait entraîner une erreur expliquant le début du sujet. La raison de ce problème est l'absence de configurations pour Azure AD (middleware Open ID). Afin de résoudre ce problème, je propose de configurer manuellement "Authentification / Autorisation". Le bref aperçu de la façon de configurer ceci est ajouté.
la source
La plupart des réponses montrent comment gérer au mieux
HttpContext
la documentation, ce que j'ai également choisi.Je voulais mentionner que vous voudrez vérifier les paramètres de votre projet lors du débogage, la valeur par défaut est
Enable Anonymous Authentication = true
.la source
J'ai ma solution
la source