web-dev-qa-db-fra.com

SimpleMembership avec schéma de base de données personnalisé dans ASP.NET MVC 4

Je souhaite permettre à l'API SimpleMembership d'ASP.NET MVC 4 de s'intégrer à mon propre schéma de base de données. J'ai un tableau simple et clair dans ma base de données appelé Users avec ces champs:

  • Id
  • Prénom
  • Mot de passe
  • Email
  • Est supprimé

J'ai déjà configuré l'API SimpleMembership pour utiliser ma base de données:

WebSecurity.InitializeDatabaseConnection("MyStuff", "Users", "Id", "Name", autoCreateTables: true);

Et je peux aussi insérer un utilisateur:

WebSecurity.CreateUserAndAccount(model.UserName, model.Password, 
                                 new 
                                 { 
                                        IsDeleted = false, 
                                        Email = "[email protected]"                
                                 });

Cependant, le champ Mot de passe (ou son hachage) n'est pas inséré dans la table Utilisateurs (bien sûr), mais dans une autre table appelée webpages_Membership qui est créée avec l'appel InitializeDatabaseConnection et contient beaucoup d'informations inutiles dont je n'ai pas besoin.

De plus, j'ai d'autres tables créées automatiquement, appelées webpages_OAuthMembership, webpages_Roles et webpages_UsersInRoles dont je n'ai pas besoin.

J'ai déjà essayé de définir la génération de table sur false:

WebSecurity.InitializeDatabaseConnection("MyStuff", "Users", "Id", "Name", autoCreateTables: false);

Mais dans ce cas, l'appel CreateUserAndAccount lève une exception car il ne trouvera pas la table webpages_Membership.

Il semble que ces tables soient nécessaires lorsque je veux utiliser l'API SimpleMembership. 

Ma question est la suivante: que dois-je faire dans un scénario comme celui-ci lorsque je ne souhaite qu'une simple table Users et rien de plus?

Dois-je écrire moi-même le traitement complet de l'adhésion et la logique d'authentification (génération de code de hachage, etc.)?

37
Zsolt

J'ai posé la même question à l'équipe produit.

L’objectif de la conception de l’adhésion à SIMPLE était de fonctionner aussi simple que possible.

Donc, en réalité, aucune personnalisation n'est possible en ce qui concerne les tables ..___ La solution de contournement recommandée consiste à continuer à utiliser l’adhésion ASP.NET (SqlMembershipProvider).

11
Max

La personnalisation est possible.

Vous pouvez obtenir le code source de SimpleMembershipProvider from le projet aspnetwebstack sur CodePlex , étant donné que c'est là que le mappage a lieu entre le schéma de base de données et l'environnement d'exécution. , etc. pour répondre à vos besoins (sans trop de maux de tête, IMO.)

10
Shaun Wilson

1 - Vous devez activer les migrations, de préférence avec EntityFramework 5. Utilisez Enable-Migrations dans le gestionnaire de paquets NuGet.

2 - Déplacez votre 

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 

à votre méthode Seed dans votre classe YourMvcApp/Migrations/Configuration.cs

    protected override void Seed(UsersContext context)
    {
        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

        if (!Roles.RoleExists("Administrator"))
            Roles.CreateRole("Administrator");

        if (!WebSecurity.UserExists("lelong37"))
            WebSecurity.CreateUserAndAccount(
                "lelong37",
                "password",
                new {Mobile = "+19725000000", IsSmsVerified = false});

        if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
    }

Désormais, EF5 sera chargé de créer votre table UserProfile. Après cela, vous appellerez WebSecurity.InitializeDatabaseConnection pour n’enregistrer que SimpleMembershipProvider avec la table UserProfile déjà créée, indiquant également à SimpleMembershipProvider quelle colonne est UserId et UserName. Je montre également un exemple de la manière dont vous pouvez ajouter des utilisateurs, des rôles et associer les deux dans votre méthode Seed à des propriétés/champs personnalisés UserProfile, par exemple. le numéro de téléphone portable d'un utilisateur.

3 - Désormais, lorsque vous exécuterez update-database à partir de la console Package Manager, EF5 configurera votre table avec toutes vos propriétés personnalisées.

Pour plus de références, veuillez vous référer à cet article avec le code source: http://blog.longle.io/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider- ef5-codefirst-and-custom-user-properties/

3
LeLong37

Cela peut ne pas fonctionner pour votre cas d'utilisation, mais vous pouvez bien sûr ajouter très facilement vos attributs d'utilisateur à la table UserProfile de Simplemembership au lieu de créer une autre table d'utilisateurs.

Je recommanderais d'utiliser la table d'appartenance existante pour conserver le mot de passe haché et ignorer simplement les champs dont vous n'avez pas besoin. De cette façon, la compatibilité avec SimpleMembership est préservée sans difficulté.

SQLMembership est très facile à utiliser. J'ai réalisé de nombreuses extensions personnalisées de SQLMembership sur quelques projets, ce qui n'était pas si difficile - mais avec le recul, j'aurais aimé ne pas l'avoir fait. C'est une sorte de problème d'entretien,

2
Rohit

Vous pouvez créer votre propre fournisseur d'adhésion en étendant MemberProvider. Voir Custom MembershipProvider dans .NET 4.0 pour plus de détails. En utilisant cette approche, il vous suffirait d'implémenter les méthodes dont vous avez besoin. Cela devrait aider à garder les choses plus simples et ne vous obligerait pas à ajouter des tables inutiles.

Les étapes de base (tirées de la réponse SO liée) sont les suivantes:

  1. Créez un nouveau fichier de classe (si vous n'utilisez pas de système multicouche, dans le dossier Modèles de votre projet), appelons-le MyMembershipProvider.cs.
  2. Hériter de cette classe de System.Web.Security.MembershipProvider
  3. Créer automatiquement les méthodes nécessaires (période + espace dans la classe héritée)
2
oalbrecht

Vous pouvez utiliser OAUth avec les fournisseurs universels ASP.NET. Les fournisseurs universels sont la nouvelle version des fournisseurs sqlmember. ceux-ci sont basés sur EF CodeFirst et génèrent également un schéma plus propre de votre base de données Consultez mon post suivant pour plus de détails http://blogs.msdn.com/b/pranav_rastogi/archive/2012/ 09/12/integr-openauth-openid-avec-votre-application-existante-asp-net-using-universal-providers.aspx

2
pranav rastogi

Vous pouvez utiliser à la fois votre table Utilisateurs personnalisée et les tables SimpleMembership. Cette méthode a très bien fonctionné pour moi par le passé. 

Par exemple, dans votre méthode Register dans AccountController, vous enregistreriez un nouvel utilisateur en l'ajoutant à votre propre table Utilisateurs. Ajoutez ensuite cet utilisateur à la table SimpleMembership UserProfile en utilisant l'ID de l'utilisateur que vous avez ajouté à la table Utilisateurs. 

using (var context = new MyDatabaseEntities())
{
    User newUser = new User(){
      Name = model.Name,
      Email = model.Email,
      IsDeleted = false
    }

    // Add the user to your custom Users table
    context.Users.Add(newUser);
    context.SaveChanges();

    // Add this user to the SimpleMembership table using the same Id as the custom Users table
    WebSecurity.CreateUserAndAccount(newUser.Id.ToString(), model.Password);

    // Log the user in
    WebSecurity.Login(newUser.Id.ToString(), model.Password);
}
0
oalbrecht