Utilisation d'un Stefan Cebulak et un excellent article du blog de Ben Foster. L'identité ASP.NET mise à nue J'ai trouvé la solution ci-dessous, que j'ai appliquée à l'identité ASP.NET. 2.0 avec une générée par Visual Studio 2013 AccountController
.
La solution utilise un nombre entier comme clé primaire pour les utilisateurs et permet également d'obtenir l'ID de l'utilisateur actuellement connecté sans avoir à se rendre dans la base de données.
Voici les étapes que vous devez suivre :
1. Créer des classes personnalisées liées à l'utilisateur
Par défaut, le AccountController
utilise des classes, qui utilisent string
comme type de clé primaire. Nous devons créer les classes ci-dessous, qui utiliseront une clé primaire. int
à la place. J'ai défini toutes les classes ci-dessous dans un seul fichier : AppUser.cs
public class AppUser :
IdentityUser<int, AppUserLogin, AppUserRole, AppUserClaim>,
IUser<int>
{
}
public class AppUserLogin : IdentityUserLogin<int> { }
public class AppUserRole : IdentityUserRole<int> { }
public class AppUserClaim : IdentityUserClaim<int> { }
public class AppRole : IdentityRole<int, AppUserRole> { }
Il sera également utile d'avoir un ClaimsPrincipal personnalisé, qui exposera facilement l'ID de l'utilisateur.
public class AppClaimsPrincipal : ClaimsPrincipal
{
public AppClaimsPrincipal( ClaimsPrincipal principal ) : base( principal )
{ }
public int UserId
{
get { return int.Parse(this.FindFirst( ClaimTypes.Sid ).Value); }
}
}
2. Créez un IdentityDbContext
Le contexte de la base de données de notre application s'étendra IdentityDbContext
qui implémente par défaut tous les DbSets liés à l'authentification. Même si DbContext.OnModelCreating
est une méthode vide, je ne suis pas certain de l'utilité de l'option IdentityDbContext.OnModelCreating
Par conséquent, lorsque vous remplacez une fonction, n'oubliez pas d'appeler la fonction base.OnModelCreating( modelBuilder )
AppDbContext.cs
public class AppDbContext :
IdentityDbContext<AppUser, AppRole, int, AppUserLogin, AppUserRole, AppUserClaim>
{
public AppDbContext() : base("DefaultConnection")
{
// Here use initializer of your choice
Database.SetInitializer( new CreateDatabaseIfNotExists<AppDbContext>() );
}
// Here you define your own DbSet's
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
base.OnModelCreating( modelBuilder );
// Here you can put FluentAPI code or add configuration map's
}
}
3. Créez des UserStore
y UserManager
qui utilisera la méthode ci-dessus
AppUserStore.cs
public interface IAppUserStore : IUserStore<AppUser, int>
{
}
public class AppUserStore :
UserStore<AppUser, AppRole, int, AppUserLogin, AppUserRole, AppUserClaim>,
IAppUserStore
{
public AppUserStore() : base( new AppDbContext() )
{
}
public AppUserStore(AppDbContext context) : base(context)
{
}
}
AppUserManager.cs
public class AppUserManager : UserManager<AppUser, int>
{
public AppUserManager( IAppUserStore store ) : base( store )
{
}
}
4. Modifier AccountController
pour utiliser vos classes personnalisées
Changez tout UserManager
a AppUserManager
, UserStore
a AppUserStore
etc. Prenons un exemple de ces constructeurs :
public AccountController()
: this( new AppUserManager( new AppUserStore( new AppDbContext() ) ) )
{
}
public AccountController(AppUserManager userManager)
{
UserManager = userManager;
}
5. Ajouter l'ID de l'utilisateur en tant que réclamation à ClaimIdentity
stocké dans un cookie
A l'étape 1, nous avons créé AppClaimsPrincipal
qui expose le UserId extrait de ClaimType.Sid
. Cependant, pour que cette demande soit disponible, nous devons l'ajouter lors de la connexion de l'utilisateur. Dans AccountController
a SingInAsync
est responsable de l'ouverture de session. Nous devons ajouter une ligne à cette méthode, pour ajouter la réclamation.
private async Task SignInAsync(AppUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
// Extend identity claims
identity.AddClaim( new Claim( ClaimTypes.Sid, user.Id.ToString() ) );
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
6. Créez un BaseController
avec un CurrentUser
propriété
Pour avoir un accès facile à l'ID d'un utilisateur actuellement connecté dans vos contrôleurs, créez une abstraction BaseController
dont découleront vos contrôleurs. Dans le BaseController
créer un CurrentUser
comme suit :
public abstract class BaseController : Controller
{
public AppClaimsPrincipal CurrentUser
{
get { return new AppClaimsPrincipal( ( ClaimsPrincipal )this.User ); }
}
public BaseController()
{
}
}
7. Héritez de vos contrôleurs de BaseController
et profiter
À partir de maintenant, vous pouvez utiliser CurrentUser.UserId
dans vos contrôleurs afin d'accéder à l'ID d'un utilisateur actuellement connecté sans passer par la base de données. Vous pouvez l'utiliser pour interroger uniquement les objets qui appartiennent à l'utilisateur.
Vous n'avez pas à vous occuper de la génération automatique des clés primaires des utilisateurs - sans surprise, Entity Framework utilise par défaut Identity pour les clés primaires des entiers, lors de la création des tables.
Attention ! Gardez à l'esprit, que si vous l'implémentez dans un projet déjà publié, pour les utilisateurs déjà connectés ClaimsType.Sid
n'existera pas et FindFirst
retournera null dans AppClaimsPrincipal
. Vous devez soit forcer la déconnexion de tous les utilisateurs, soit gérer ce scénario dans le cadre de l'application de la méthode de gestion de la sécurité. AppClaimsPrincipal
0 votes
J'ai mis à jour ma réponse avec un exemple de code permettant de changer le type dans la dernière version nocturne 1.1-alpha1.
6 votes
Note aux futurs lecteurs de cette question : La version 2.0.0 de ASP.NET Identity (publiée le 20 mars 2014) intègre désormais la possibilité de modifier/étendre le type de l'identifiant/clé primaire. Voir blogs.msdn.com/b/webdev/archive/2014/03/20/
2 votes
Et pour les futurs lecteurs, il y a un exemple de solution avec User.ID comme entier : aspnet.codeplex.com/SourceControl/latest#Samples/Identity/
0 votes
Il existe un article officiel ASP.NET très bien expliqué sur le sujet : Modifier la clé primaire des utilisateurs dans ASP.NET Identity
0 votes
Vos préoccupations en matière d'interface utilisateur ne devraient pas intéresser une équipe chargée de la mise en œuvre de la sécurité !