J'ai étendu le schéma d'identité ASP NET en ajoutant quelques champs dans la classe ApplicationUser
qui est dérivée de IdentityUser
. L'un des champs que j'ai ajouté est FullName
.
Maintenant, quand j'écris User.Identity.Name
, il me donne le nom d'utilisateur, je cherche quelque chose comme User.Identity.FullName
qui devrait renvoyer le nom complet que j'ai ajouté.
Je ne suis pas sûr de savoir comment cela peut être réalisé, toute orientation sera grandement appréciée.
Merci.
Vous pouvez l'ajouter aux revendications de l'utilisateur lorsque vous créez l'utilisateur, puis le récupérer en tant que revendication auprès de l'utilisateur.
await userManager.AddClaimAsync(user.Id, new Claim("FullName", user.FullName));
Récupérez-le:
((ClaimsIdentity)User.Identity).FindFirst("FullName")
Ou vous pouvez simplement récupérer l'utilisateur et y accéder directement depuis l'utilisateur.
var user = await userManager.FindById(User.Identity.GetUserId())
return user.FullName
Dans la classe ApplicationUser, vous remarquerez un commentaire (si vous utilisez le modèle MVC5 standard) qui dit "Ajouter des revendications utilisateur personnalisées ici".
Cela étant, voici à quoi ressemblerait l'ajout de FullName:
public class ApplicationUser : IdentityUser
{
public string FullName { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> 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("FullName", this.FullName));
return userIdentity;
}
}
En utilisant cela, lorsque quelqu'un se connecte, la revendication FullName sera placée dans le cookie. Vous pouvez créer un assistant pour y accéder comme ceci:
public static string GetFullName(this System.Security.Principal.IPrincipal usr)
{
var fullNameClaim = ((ClaimsIdentity)usr.Identity).FindFirst("FullName");
if (fullNameClaim != null)
return fullNameClaim.Value;
return "";
}
Et utilisez l'aide comme ceci:
@using HelperNamespace
...
@Html.ActionLink("Hello " + User.GetFullName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
Notez que les revendications utilisateur personnalisées sont stockées dans le cookie, ce qui est préférable à l'obtention des informations utilisateur à partir de la base de données ... enregistre un hit de base de données pour les données couramment consultées.
J'ai trouvé que cela fonctionne plutôt bien
AccountController:
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
identity.AddClaim(new Claim("FullName", user.FullName));
identity.AddClaim(new Claim("Email", user.Email));
identity.AddClaim(new Claim("DateCreated", user.DateCreated.ToString("MM/dd/yyyy")));
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
Méthode d'extension sur l'identité:
public static class GenericPrincipalExtensions
{
public static string FullName(this IPrincipal user)
{
if (user.Identity.IsAuthenticated)
{
ClaimsIdentity claimsIdentity = user.Identity as ClaimsIdentity;
foreach (var claim in claimsIdentity.Claims)
{
if (claim.Type == "FullName")
return claim.Value;
}
return "";
}
else
return "";
}
}
À votre avis:
@Html.ActionLink("Hello " + User.FullName() + "!", "Manage", "Account", routeValues: null, htmlAttributes: new { title = "Manage" })
Vous pouvez consulter le fil ici: Lien
C'est possible en définissant votre propre IIdentity
(et éventuellement IPrincipal
aussi) et en le construisant lors de la création du IPrincipal
pour la requête HTTP (lorsque PostAuthenticateRequest est levée).
Comment implémenter vos propres IIDentity
et IPrincipal
: Comment puis-je implémenter un principal et une identité personnalisés dans ASP.NET MVC?
J'ai résolu le problème en procédant comme suit:
1 - Créer mon propre CustomPrincipal en étendant IPrincipal
2 - Chargez le CustomPrincipal après l'authentification de chaque demande.
Créer mon propre CustomPrincipal
interface ICustomPrincipal : IPrincipal
{
string UserId { get; set; }
string FirstName { get; set; }
string LastName { get; set; }
int CustomerId { get; set; }
}
public partial class CustomPrincipal : ClaimsPrincipal, ICustomPrincipal
{
#region IPrincipal Members
public new ClaimsIdentity Identity { get; private set; }
public new bool IsInRole(string role)
{
IdentityManager manager = new IdentityManager();
return manager.IsInRole(role, this.UserId);
}
#endregion
public CustomPrincipal(ApplicationUser user, IIdentity identity)
:base(identity)
{
this.Identity = new ClaimsIdentity(identity);
this.UserId = user.Id;
this.FirstName = user.FirstName;
this.LastName = user.LastName;
this.CustomerId = user.CustomerId;
this.DateCreated = user.DateCreated;
}
#region ICustomPrinicpal Members
public string UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int CustomerId { get; set; }
public DateTime DateCreated { get; set; }
#endregion
public string GetFullName()
{
return this.FirstName + " " + this.LastName;
}
}
Chargez le CustomPrincipal après que chaque demande a été authentifiée
Dans Global.asax.cs ...
protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
//At this point we need to get the user from the database based on the username.
ApplicationUser AppUser = ApplicationUserDB.GetByUserName(User.Identity.Name);
CustomPrincipal UserPrincipal = new CustomPrincipal(AppUser, User.Identity);
HttpContext.Current.User = UserPrincipal;
}
}
Comme vous pouvez le voir dans mon code ci-dessus, je récupère un ApplicationUser
et le passe dans le constructeur du CustomPrincipal
. J'affecte ensuite le nouveau CustomPrincipal
au contexte actuel.
Stockez la valeur des revendications et lisez-la.
Valeur magasin
public class ApplicationUser : IdentityUser
{
public string FullName { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
userIdentity.AddClaim(new Claim("FullName", this.FullName));
return userIdentity;
}
}
Lire la valeur
var FullName = "";
if (User != null)
{
var identity = (System.Security.Claims.ClaimsIdentity)Context.User.Identity;
var claim1 = identity.Claims.FirstOrDefault(c => c.Type == "FullName");
if (claim1 != null)
{
FullName = claim1.Value;
}
}
Cela devrait faire l'affaire:
User.Claims.Single(x => x.Type== "name").Value
J'ai essayé ça et ça marche!
IdentityModels.cs/ApplicationUser, classe
// Add custom user claims here
userIdentity.AddClaim(new Claim("FullName", this.FullName));
_LoginPartialView
<li>
@Html.ActionLink("Hello " + (((ClaimsIdentity)User.Identity).FindFirst("FullName").Value) + " !", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
</li>