Comment étendre les propriétés disponibles de User.Identity

J’utilise MVC5 Identity 2.0 pour que les utilisateurs se connectent à mon site Web, où les détails d’authentification sont stockés dans une firebase database SQL. Asp.net Identity a été implémenté de manière standard, comme on peut le trouver dans de nombreux didacticiels en ligne.

La classe ApplicationUser dans IdentityModels a été étendue pour inclure certaines propriétés personnalisées, telles qu’un entier OrganizationId. L’idée est que de nombreux utilisateurs peuvent être créés et affectés à une organisation commune à des fins de relation de firebase database.

public class ApplicationUser : IdentityUser { public async Task GenerateUserIdentityAsync(UserManager manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here return userIdentity; } //Extended Properties public DateTime? BirthDate { get; set; } public long? OrganizationId { get; set; } //Key Mappings [ForeignKey("OrganizationId")] public virtual Organization Organization { get; set; } } 

Comment puis-je récupérer la propriété OrganizationId de l’utilisateur actuellement connecté depuis un contrôleur? Est-ce disponible via une méthode une fois qu’un utilisateur est connecté ou est-ce que je récupère toujours l’OrganisationId de la firebase database, basé sur UserId, chaque fois qu’une méthode de contrôleur s’exécute?

En lisant sur le Web, j’ai vu que je devais utiliser les éléments suivants pour obtenir le UserId connecté, etc.

 using Microsoft.AspNet.Identity; ... User.Identity.GetUserId(); 

Toutefois, OrganizationId n’est pas une propriété disponible dans User.Identity. Dois-je étendre User.Identity pour inclure la propriété OrganizationId? Si oui, comment vais-je faire ça?

La raison pour laquelle j’ai besoin de OrganizationId est que de nombreuses requêtes de table dépendent de OrganizationId pour récupérer des données pertinentes pour l’organisation associée à l’utilisateur connecté.

Chaque fois que vous souhaitez étendre les propriétés de User.Identity avec des propriétés supplémentaires telles que la question ci-dessus, ajoutez d’abord ces propriétés à la classe ApplicationUser comme suit:

 public class ApplicationUser : IdentityUser { public async Task GenerateUserIdentityAsync(UserManager manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here return userIdentity; } // Your Extended Properties public long? OrganizationId { get; set; } } 

Ensuite, il vous faut créer une méthode d’extension comme celle-ci (je crée la mienne dans un nouveau dossier Extensions):

 namespace App.Extensions { public static class IdentityExtensions { public static ssortingng GetOrganizationId(this IIdentity identity) { var claim = ((ClaimsIdentity)identity).FindFirst("OrganizationId"); // Test for null to avoid issues during local testing return (claim != null) ? claim.Value : ssortingng.Empty; } } } 

Lorsque vous créez l’identité dans la classe ApplicationUser, ajoutez simplement Claim -> OrganizationId comme suit:

  public async Task GenerateUserIdentityAsync(UserManager manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here => this.OrganizationId is a value stored in database against the user userIdentity.AddClaim(new Claim("OrganizationId", this.OrganizationId.ToSsortingng())); return userIdentity; } 

Une fois que vous avez ajouté la revendication et que votre méthode d’extension est en place, pour la rendre disponible en tant que propriété sur votre User.Identity, ajoutez une instruction using sur la page / le fichier auquel vous souhaitez accéder :

dans mon cas: using App.Extensions; dans un contrôleur et @using. App.Extensions @using. App.Extensions un fichier View .cshtml.

MODIFIER:

Ce que vous pouvez également faire pour éviter d’append une instruction using dans chaque vue, c’est aller dans le dossier Views et localiser le fichier Web.config. Recherchez maintenant la et ajoutez-y votre espace de noms d’extension comme suit:

  

Enregistrez votre fichier et vous avez terminé. Maintenant, chaque vue connaîtra vos extensions.

Vous pouvez accéder à la méthode d’extension:

 var orgId = User.Identity.GetOrganizationId(); 

J’espère que ça aide quelqu’un 🙂

Je cherchais la même solution et Pawel m’a donné 99% de la réponse. La seule chose qui manquait à ce que j’avais besoin pour que l’extension soit affichée était l’ajout du code de razor suivant dans la page cshtml (vue):

@using programname.Models.Extensions

Je cherchais le prénom, à afficher en haut à droite de ma barre de navigation après que l’utilisateur s’est connecté.

Je pensais que je posterais cela si cela aide quelqu’un d’autre, alors voici mon code:

J’ai créé un nouveau dossier appelé Extensions (sous mon dossier Models) et créé la nouvelle classe Pawel spécifiée ci-dessus: IdentityExtensions.cs

 using System.Security.Claims; using System.Security.Principal; namespace ProgramName.Models.Extensions { public static class IdentityExtensions { public static ssortingng GetUserFirstname(this IIdentity identity) { var claim = ((ClaimsIdentity)identity).FindFirst("FirstName"); // Test for null to avoid issues during local testing return (claim != null) ? claim.Value : ssortingng.Empty; } } } 

IdentityModels.cs :

 public class ApplicationUser : IdentityUser { //Extended Properties public ssortingng FirstName { get; internal set; } public ssortingng Surname { get; internal set; } public bool isAuthorized { get; set; } public bool isActive { get; set; } public async Task GenerateUserIdentityAsync(UserManager manager) { // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); // Add custom user claims here userIdentity.AddClaim(new Claim("FirstName", this.FirstName)); return userIdentity; } } 

Ensuite, dans mon _LoginPartial.cshtml (Sous Views/Shared Dossiers Views/Shared ), j’ai ajouté @using.ProgramName.Models.Extensions

J’ai ensuite ajouté le changement à la ligne de code suivante qui allait utiliser le prénom des utilisateurs après la connexion:

@Html.ActionLink("Hello " + User.Identity.GetUserFirstname() + "!", "Index", "Manage", routeValues: null, htmlAtsortingbutes: new { title = "Manage" })

Peut-être que cela aide quelqu’un d’autre.

Jetez un œil à cet excellent article de blog de John Atten: ASP.NET Identity 2.0: personnalisation des utilisateurs et des rôles

Il contient des informations détaillées sur l’ensemble du processus. Allez le lire:)

Voici quelques bases.

Étendez la classe ApplicationUser par défaut en ajoutant de nouvelles propriétés (par exemple, adresse, ville, état, etc.):

 public class ApplicationUser : IdentityUser { public async Task GenerateUserIdentityAsync(UserManager manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } public ssortingng Address { get; set; } public ssortingng City { get; set; } public ssortingng State { get; set; } // Use a sensible display name for views: [Display(Name = "Postal Code")] public ssortingng PostalCode { get; set; } // Concatenate the address info for display in tables and such: public ssortingng DisplayAddress { get { ssortingng dspAddress = ssortingng.IsNullOrWhiteSpace(this.Address) ? "" : this.Address; ssortingng dspCity = ssortingng.IsNullOrWhiteSpace(this.City) ? "" : this.City; ssortingng dspState = ssortingng.IsNullOrWhiteSpace(this.State) ? "" : this.State; ssortingng dspPostalCode = ssortingng.IsNullOrWhiteSpace(this.PostalCode) ? "" : this.PostalCode; return ssortingng.Format("{0} {1} {2} {3}", dspAddress, dspCity, dspState, dspPostalCode); } } 

Ensuite, vous ajoutez vos nouvelles propriétés à votre RegisterViewModel.

  // Add the new address properties: public ssortingng Address { get; set; } public ssortingng City { get; set; } public ssortingng State { get; set; } 

Ensuite, mettez à jour la vue de registre pour inclure les nouvelles propriétés.

  
@Html.LabelFor(m => m.Address, new { @class = "col-md-2 control-label" })
@Html.TextBoxFor(m => m.Address, new { @class = "form-control" })

Ensuite, mettez à jour la méthode Register () sur AccountController avec les nouvelles propriétés.

  // Add the Address properties: user.Address = model.Address; user.City = model.City; user.State = model.State; user.PostalCode = model.PostalCode; 

Dhaust donne un bon moyen d’append la propriété à la classe ApplicationUser. En regardant le code OP, il semble qu’ils aient pu le faire ou étaient sur le sharepoint le faire. La question demande

Comment puis-je récupérer la propriété OrganizationId de l’utilisateur actuellement connecté depuis un contrôleur? Toutefois, OrganizationId n’est pas une propriété disponible dans User.Identity. Dois-je étendre User.Identity pour inclure la propriété OrganizationId?

Pawel permet d’append une méthode d’extension qui nécessite l’utilisation d’instructions ou l’ajout de l’espace de noms au fichier web.config.

Cependant, la question vous demande si vous “devez” étendre User.Identity pour inclure la nouvelle propriété. Il existe un autre moyen d’accéder à la propriété sans étendre User.Identity. Si vous avez suivi la méthode Dhaust, vous pouvez utiliser le code suivant dans votre contrôleur pour accéder à la nouvelle propriété.

 ApplicationDbContext db = new ApplicationDbContext(); var manager = new UserManager(new UserStore(db)); var currentUser = manager.FindById(User.Identity.GetUserId()); var myNewProperty = currentUser.OrganizationId; 

J’avais également ajouté ou étendu des colonnes supplémentaires dans ma table AspNetUsers. Quand je voulais simplement voir ces données, j’ai trouvé de nombreux exemples comme le code ci-dessus avec “Extensions” etc … Cela m’a vraiment étonné de devoir écrire toutes ces lignes de code pour obtenir quelques valeurs des utilisateurs actuels.

Il se trouve que vous pouvez interroger la table AspNetUsers comme toute autre table:

  ApplicationDbContext db = new ApplicationDbContext(); var user = db.Users.Where(x => x.UserName == User.Identity.Name).FirstOrDefault(); 

Pour quiconque trouve cette question en cherchant comment accéder aux propriétés personnalisées dans ASP.NET Core 2.1 – c’est beaucoup plus facile: vous aurez un UserManager, par exemple dans _LoginPartial.cshtml, et vous pourrez le faire simplement (en supposant que “ScreenName” est un propriété que vous avez ajoutée à votre propre AppUser qui hérite de IdentityUser):

 @using Microsoft.AspNetCore.Identity @using  @inject SignInManager SignInManager @inject UserManager UserManager @if (SignInManager.IsSignedIn(User)) { 
} else { }