web-dev-qa-db-fra.com

Comment obtenir l'utilisateur actuel dans le noyau asp.net

Je veux obtenir l'utilisateur actuel pour obtenir des informations d'utilisateur telles que l'email . Mais je ne peux pas le faire dans asp.net core.Je suis tellement confus Ceci est mon code. 

HttpContext presque est null dans constructor of controller . Ce n’est pas bon d’obtenir 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();
   }
65
Mehran Hafizi
User.FindFirst(ClaimTypes.NameIdentifier).Value

EDIT pour constructeur

Le code ci-dessous fonctionne:

public Controller(IHttpContextAccessor httpContextAccessor)
{
    var userId = httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value 
}

Modifier pour RTM

Vous devriez vous enregistrer IHttpContextAccessor:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }
105
adem caglin

Manière simple qui fonctionne et j'ai vérifié.

private readonly UserManager<IdentityUser> _userManager;
public CompetitionsController(UserManager<IdentityUser> userManager)
{
    _userManager = userManager;
}

var user = await _userManager.GetUserAsync(HttpContext.User);

alors vous pouvez toutes les propriétés de cette variable comme user.Email. J'espère que cela aiderait quelqu'un.

30
Ahmad

Avoir un autre moyen d'obtenir l'utilisateur actuel dans Asp.NET Core - et je pense l'avoir vu quelque part ici, sur SO ^^ 

// Stores UserManager
private readonly UserManager<ApplicationUser> _manager; 

// Inject UserManager using dependency injection.
// Works only if you choose "Individual user accounts" during project creation.
public DemoController(UserManager<ApplicationUser> manager)  
{  
    _manager = manager;  
}

// You can also just take part after return and use it in async methods.
private async Task<ApplicationUser> GetCurrentUser()  
{  
    return await _manager.GetUserAsync(HttpContext.User);  
}  

// Generic demo method.
public async Task DemoMethod()  
{  
    var user = await GetCurrentUser(); 
    string userEmail = user.Email; // Here you gets user email 
    string userId = user.Id;
}  

Ce code est envoyé au contrôleur nommé DemoController. Ne fonctionnera pas sans attendre (ne compile pas);)

20
Hekkaryk

Il semblerait que dès maintenant (avril 2017), les travaux suivants:

public string LoggedInUser => User.Identity;

Au moins dans une Controller

11
Grandizer

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

@using Microsoft.AspNetCore.Identity
@inject UserManager<ApplicationUser> UserManager

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
    @UserManager.FindByNameAsync(UserManager.GetUserName(User)).Result.Email
    </title>
  </head>
  <body>

  </body>
</html>
3
MikeMajara

En plus des réponses existantes, j'aimerais ajouter que vous pouvez également disposer d'une instance de classe disponible dans toute l'application, qui contient des données relatives à l'utilisateur telles que UserID, etc. 

Cela peut être utile pour refactoring _ ​​par exemple, vous ne voulez pas extraire UserID dans chaque action du contrôleur et déclarer un paramètre supplémentaire UserID dans chaque méthode liée à la couche de service.

J'ai fait une recherche et voici mon post .

Vous venez d'étendre votre classe dont vous dérivez DbContext en ajoutant la propriété UserId (ou en implémentant une classe Session personnalisée comportant cette propriété).

Au niveau du filtre, vous pouvez récupérer votre instance de classe et définir la valeur UserId.

Après cela, peu importe où vous injectez votre instance - elle aura les données nécessaires (la durée de vie doit être de par requête, donc vous l'enregistrez en utilisant la méthode AddScoped).

Exemple de travail:

public class AppInitializationFilter : IAsyncActionFilter
{
    private DBContextWithUserAuditing _dbContext;

    public AppInitializationFilter(
        DBContextWithUserAuditing dbContext
        )
    {
        _dbContext = dbContext;
    }

    public async Task OnActionExecutionAsync(
        ActionExecutingContext context,
        ActionExecutionDelegate next
        )
    {
        string userId = null;
        int? tenantId = null;

        var claimsIdentity = (ClaimsIdentity)context.HttpContext.User.Identity;

        var userIdClaim = claimsIdentity.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
        if (userIdClaim != null)
        {
            userId = userIdClaim.Value;
        }

        var tenantIdClaim = claimsIdentity.Claims.SingleOrDefault(c => c.Type == CustomClaims.TenantId);
        if (tenantIdClaim != null)
        {
            tenantId = !string.IsNullOrEmpty(tenantIdClaim.Value) ? int.Parse(tenantIdClaim.Value) : (int?)null;
        }

        _dbContext.UserId = userId;
        _dbContext.TenantId = tenantId;

        var resultContext = await next();
    }
}

Pour plus d'informations, voir ma réponse .

1
Alex Herman

Si vous utilisez l'identité scafold et utilisez Asp.net Core 2.2+, vous pouvez accéder à l'utilisateur actuel à partir d'une vue comme celle-ci:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

 @if (SignInManager.IsSignedIn(User))
    {
        <p>Hello @User.Identity.Name!</p>
    }
    else
    {
        <p>You're not signed in!</p>
    }

https://docs.Microsoft.com/en-us/aspnet/core/security/authentication/identity?view=aspnetcore-2.2&tabs=visual-studio

0
Andrew

Prendre IdentityUser fonctionnerait également. Il s'agit d'un objet utilisateur actuel et toutes les valeurs d'utilisateur peuvent être récupérées.

private readonly UserManager<IdentityUser> _userManager;
public yourController(UserManager<IdentityUser> userManager)
{
    _userManager = userManager;
}

var user = await _userManager.GetUserAsync(HttpContext.User);
0
zzdhxu

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/290389 ). Il explique en détail comment obtenir un nom d'utilisateur en utilisant IPrincipal et IIdentity. Cette réponse est absolument correcte et je recommande d'utiliser cette approche. Cependant, lors du débogage, j'ai rencontré le problème lorsque ASP.NET ne peut PAS renseigner le principe de service correctement . (ou en d'autres termes, IPrincipal.Identity.Name est null)

Il est évident que pour obtenir le nom d'utilisateur, MVC Framework 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 les revendications relatives à 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 vous connectez. Lorsque vous déployez votre application Web sur Azure Service, le scénario habituel pour répondre à cette configuration consiste à configurer l'application Web: "App Services" -> VotreApp -> Lame "Authentification/Autorisation" -> "App Service Authenticatio" = "Activé", etc. sur ( 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, le magicien ajuste la configuration Web "parent" de cette application Web en ajoutant les mêmes paramètres que ceux indiqués dans les paragraphes suivants. Fondamentalement, la raison pour laquelle cette approche ne fonctionne PAS dans ASP.NET Core est parce que la configuration de la machine "mère" est ignorée par webconfig. (ce n'est pas sûr à 100%, je viens de donner la meilleure explication que j'ai). Donc, pour que cela fonctionne, vous devez configurer cela manuellement dans votre application.

Voici un article qui explique comment configurer de manière multiple votre application pour utiliser Azure AD. https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/aspnetcore2-2

Étape 1: enregistrez l'échantillon auprès de votre locataire Azure AD. (c'est évident, je ne veux pas passer mon temps d'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 d'application à 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 les utilisateurs avec le point de terminaison Azure AD v2.0, à la fois en mode travail et travail et en mode travail. Comptes Microsoft Personal.

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
    options.Authority = options.Authority + "/v2.0/";
    options.TokenValidationParameters.ValidateIssuer = false;
});

Résumé : J'ai déjà montré un problème supplémentaire qui pourrait expliquer le fait que le sujet commence est expliqué. 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". La brève présentation de la configuration est ajoutée.

0
Roman Oira-Oira

Peut-être que je n'ai pas vu la réponse, mais c'est comme ça que je le fais.

  1. . Net Core -> Propriétés -> launchSettings.json

Vous devez avoir changer ces valeurs

"windowsAuthentication": true, // needs to be true
"anonymousAuthentication": false,  // needs to be false 

Startup.cs -> ConfigureServices (...)

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

Contrôleur Api MVC ou Web

private readonly IHttpContextAccessor _httpContextAccessor;
//constructor then
_httpContextAccessor = httpContextAccessor;

Méthode du contrôleur:

string userName = _httpContextAccessor.HttpContext.User.Identity.Name;

Le résultat est userName, par exemple. = Domaine\nom d'utilisateur

0
Tom Stickel