Identité 2.0 avec des tables personnalisées
je suis nouveau à ASP.NET j'essaie toujours de comprendre comment tout cela fonctionne. Malheureusement, j'ai trouvé beaucoup de tutoriels que j'ai essayé sont pour L'identité 1.0, alors que je tente de travailler avec L'identité 2.0.
le plus gros problème auquel je fais face est quelque chose que je pensais être simple, mais qui s'est avéré ne pas l'être. Ce que j'essaie de faire est d'utiliser une base de données existante avec une table d'utilisateur existante. Actuellement Tout ce que je peux sembler faire est d'obtenir L'identité pour créer ses propres tables pour stocker des données utilisateur. Je ne veux pas utiliser Entity Framework, mais j'ai eu beaucoup de difficulté à séparer Entity Framework de Identity 2.0.
alors que dans ma situation J'utilise SQL Server, j'ai pensé essayer d'implémenter le fournisseur personnalisé pour MySQL à ce lien: http://www.asp.net/identity/overview/extensibility/implementing-a-custom-mysql-aspnet-identity-storage-provider et https://github.com/raquelsa/AspNet.Identity.MySQL. Cela semble fonctionner sous Identité 1 seulement. Il semble qu'il y en ait un plus récent, cependant, qui utilise le cadre de L'entité. J'ai aussi essayé https://github.com/ILMServices/RavenDB.AspNet.Identity.
Avec tout ce que j'ai essayé, je me retrouve coincé avec la ligne suivante:
var manager = new IdentityUserManager(new UserStore<IdentityUser>(context.Get<ApplicationDbContext>()));
le problème auquel je suis confronté est que je dois supprimer la classe ApplicaitonDbContext selon les instructions pour RavenDB, cependant je ne sais pas quoi mettre dans cette ligne à la place.
Les erreurs que j'obtiens sont:
le type non générique " AspNet.Identité.MySQL.UserStore' ne peut pas être utilisé avec les arguments de type
et
le nom du type ou du namespace 'ApplicationDbContext' n'a pas pu être trouvé (vous manque-t-il une directive using ou une référence d'assemblage?)
la deuxième erreur est à prévoir, mais je ne sais pas quoi utiliser dans cette ligne de code à la place. Quelqu'un a-t-il déjà mis en œuvre une fournisseur sans utiliser le cadre de L'entité?
Merci.
mise à Jour 1:
j'ai essayé le tutoriel suivant [ http://aspnetguru.com/customize-authentication-to-your-own-set-of-tables-in-asp-net-mvc-5/ ] mais il semble incomplet, avec des erreurs de compilation ou d'exécution en suivant exactement le tutoriel. Quelques problèmes que j'ai encore...
en remplaçant toutes les instances de "ApplicationUser" par "User" ont un problème avec la ligne suivante dans IdentityConfig.cs
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<MyDbContext>()));
changer ApplicationUser en User produit l'erreur suivante
le type ' WebApplicationTest2.Modèle.User ' ne peut pas être utilisé comme paramètre de type 'TUser' dans le type générique ou la méthode 'Microsoft.AspNet.Identité.EntityFramework.UserStore". Il n'y a pas de conversion de référence implicite de 'WebApplicationTest2.Modèle.L'utilisateur' à "Microsoft.AspNet.Identité.EntityFramework.IdentityUser".
j'ai aussi de la difficulté à trouver comment utiliser le gestionnaire d'utilisateurs et bon nombre des méthodes ASync. Les lignes suivantes ne fonctionnent pas:
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, await user.GenerateUserIdentityAsync(UserManager));
Dans AccountController.cs avec les erreurs suivantes:
la meilleure correspondance de méthode surchargée pour ' Microsoft.Owin.Sécurité.IAuthenticationManager.SignIn (Microsoft.Owin.Sécurité.Propriétés d'authentification, params Système.Sécurité.Réclamation.ClaimsIdentity [] " a des arguments invalides.
'WebApplicationTest2.Modèle.User "ne contient pas de définition pour "GenerateUserIdentityAsync" et aucune méthode d'extension "GenerateUserIdentityAsync" acceptant un premier argument de type " WebApplicationTest2.Modèle.Utilisateur " peut être trouvé (manque-t-il une directive d'utilisation ou une référence d'assemblage?)
3 réponses
Dans vos exemples, vous semblez vouloir remplacer le DbContext
avec autre chose mais je crois qu'en fait, vous devez concentrer vos efforts un niveau plus élevé.
le framework a une classe UserManager
qui a la responsabilité de gérer, mais non de stocker, les utilisateurs et leurs informations connexes. Quand on veut stocker les utilisateurs (ou de leurs informations) la valeur par défaut est d'utiliser le UserStore<IdentityUser>
qui sait comment store IdentityUser
cas dans une base de données utilisant un DbContext
.
dans le cadre 2.0, les différents bits du stockage d'identité ont été décomposés en plusieurs interfaces. L'implémentation par défaut fourni, UserStore<IdentityUser>
implémente plusieurs de ces interfaces et stocke les données pour elles toutes dans la base de données en utilisant un DBContext
.
si vous regardez la définition par défaut de la directive entity provided framework based UserStore, vous pouvez voir qu'elle implémente beaucoup de ces petites interfaces:
public class UserStore<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : IUserLoginStore<TUser, TKey>,
IUserClaimStore<TUser, TKey>, IUserRoleStore<TUser, TKey>, IUserPasswordStore<TUser, TKey>,
IUserSecurityStampStore<TUser, TKey>, IQueryableUserStore<TUser, TKey>, IUserEmailStore<TUser, TKey>,
IUserPhoneNumberStore<TUser, TKey>, IUserTwoFactorStore<TUser, TKey>, IUserLockoutStore<TUser, TKey>,
IUserStore<TUser, TKey>, IDisposable
where TUser : IdentityUser<TKey, TUserLogin, TUserRole, TUserClaim>
where TRole : IdentityRole<TKey, TUserRole>
where TKey : Object, IEquatable<TKey>
where TUserLogin : new(), IdentityUserLogin<TKey>
where TUserRole : new(), IdentityUserRole<TKey>
where TUserClaim : new(), IdentityUserClaim<TKey>
Comme vous ne voulez pas pour utiliser Entity Framework, vous devez fournir vos propres implémentations de ces interfaces clés qui permet de stocker des données dans les endroits où vous voulez que les données soient stockées. L'interface principale est IUserStore<Tuser,TKey>
. cela définit le contrat pour stocker les utilisateurs qui ont une clé d'un type particulier. Si vous voulez seulement stocker des utilisateurs et aucune autre information, alors vous pouvez implémenter cette interface et passer ensuite votre implémentation à UserManager
et vous devriez être bon d' aller.
il est peu probable que cela soit suffisant bien que vous souhaitiez probablement des mots de passe, des rôles, des logins, etc. pour vos utilisateurs. Si oui, alors vous devez faire votre classe qui met en œuvre IUserStore<Tuser,TKey>
œuvre IUserPasswordStore<TUser, TKey>
,IRoleStore<TRole, TKey>
et IUserClaimStore<TUser, TKey>
.
Vous pouvez trouver une liste de toutes les interfaces sur MSDN ici
selon les bits que vous voulez utiliser, vous devez implémenter ces interfaces.
vous devrez probablement aussi définissez vos propres versions du Identity*
classes qui existent pour les Entity framework déjà hors de la boîte. Donc vous aurez besoin de votre propre IdentityUser
classe qui représente les utilisateurs que vous souhaitez stocker et IdentityUserClaim
pour les réclamations des utilisateurs. Je ne l'ai pas fait moi-même donc je ne suis pas vraiment sûr, mais mon sentiment est que vous aurez à le faire.
Scott Allen a un bon article sur les différentes parties du modèle qui pourraient être utile.
Comme pour vos problèmes avec cette ligne:
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, await user.GenerateUserIdentityAsync(UserManager));
il existe une méthode appelée GenerateUserIdentityAsync
est définie sur Applicationuser
qui s'étend IdentityUser
. Il est défini dans le projet de modèle je crois et je ressemble à quelque chose comme ceci:
public class ApplicationUser : IdentityUser
{
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
return userIdentity;
}
}
comme vous n'utilisez pas le framework entity IdentityUser
alors vous avez besoin de définir une méthode similaire ou votre propre User
classe ou de mettre en œuvre les mêmes fonctionnalités d'une autre façon (comme tout le qualifiant de await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie)
au lieu de cela)
je suis assez nouveau à L'identité moi-même. Votre entité utilisateur implémente-t-elle L'interface IUser? par exemple,
public partial class User : IUser<Guid> //Whatever your key is
{
public Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
{
return Task.FromResult(GenerateUserIdentity(manager));
}
public ClaimsIdentity GenerateUserIdentity(ApplicationUserManager manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = manager.CreateIdentity<User, Guid>(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
alors pour vous connecter vous pouvez appeler le ci-dessus:
public async Task SignInAsync(User user, bool isPersistent)
{
var userIdentity = await user.GenerateUserIdentityAsync(UserManager);
AuthenticationManager.SignIn(
new AuthenticationProperties
{
IsPersistent = isPersistent
},
userIdentity
);
}
je pense que cela a été mis à jour récemment dans ApplicationUser
:
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
// Add custom user claims here
return userIdentity;
}
il est appelé comme ceci de AccountController
-> GetExternalLogin
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);