web-dev-qa-db-fra.com

Comment utiliser ma propre base de données avec Simple Membership et Web Security? Qu'est-ce que la sécurité MVC 4?

J'ai lu tout ce que je pouvais trouver sur ce sujet, y compris des articles MSDN et des articles SO, mais je suis toujours très perdu et confus.

Des questions

Veuillez répondre aux questions suivantes (brièvement, si possible):

  1. Qu'est-ce que SimpleMembership/SimpleMembershipProvider ( WebMatrix.WebData ) et de quoi sont-ils responsables?

  2. Qu'est-ce que WebSecurity ( WebMatrix.WebData )?

  3. Qu'est-ce que la classe Membership ( System.Web.Security )?

  4. Pourquoi MVC4 crée-t-il une table serProfile et une table webpages_Membership? À quoi servent-ils et quelle est la différence? Quelle est la classe UserProfile créée par MVC4?

  5. Qu'est-ce que la classe sersContext?

  6. Comment tous ces éléments fonctionnent-ils ensemble pour effectuer l'authentification des utilisateurs?

Ma situation

Ces questions mènent ensuite au problème suivant:

Supposons que j'ai une base de données existante avec des utilisateurs (identifiants, noms d'utilisateur, mots de passe). Je crée une nouvelle application MVC4 et j'utilise l'authentification par formulaire. Les mots de passe des utilisateurs sont stockés dans la base de données sous une forme cryptée (pas bcrypt).

Que dois-je faire pour le faire fonctionner avec MVC4?

Dois-je créer un fournisseur d'adhésion personnalisé ?

Mes connaissances jusqu'à présent

Pour autant que je puisse comprendre, WebSecurity est une classe statique (Module) qui interagit avec un MembershipProvider . Un MembershipProvider est une classe qui explique comment certaines fonctions fonctionnent, telles que ValidateUser , CreateUser , ChangePassword .

Pour résoudre mon problème, je suppose que je dois créer un MembershipProvider personnalisé et dire à WebSecurity d'utiliser mon nouveau MembershipProvider.

Prime?

J'ai placé une prime sur cette question et j'ai l'intention de l'attribuer à Andy Brown pour une réponse exceptionnelle.

61
Rowan Freeman

Voir les résumés sous chaque citation pour une réponse rapide et les paragraphes pour plus de détails. Voir également la section Références à la fin pour les sources faisant autorité.

Résumés

1.Qu'est-ce que SimpleMembership/SimpleMembershipProvider (WebMatrix.WebData) et de quoi sont-ils responsables?

SimpleMembership (un terme qui couvre à la fois SimpleMembershipProvider et SimpleRoleProvider ) est chargé de fournir un moyen propre et rapide d'implémenter un 80% -Il existe un cadre d'authentification et d'autorisation plug and play avec stockage de mot de passe sécurisé, que tout le monde peut utiliser.

2.Qu'est-ce que WebSecurity (WebMatrix.WebData)?

WebSecurity est une classe d'assistance pour les tâches d'appartenance courantes qui fonctionne avec Membership et OAuthWebSecurity . Les rôles sont toujours accessibles séparément via Roles .

3.Qu'est-ce que la classe Membership (System.Web.Security)?

Membership est une classe statique de l'implémentation d'appartenance ASP.NET d'origine qui gère les paramètres et les opérations utilisateur. De nombreuses opérations utilisateur sont toujours effectuées ici plutôt que de les répéter dans WebSecurity. Ils utilisent tous les deux le même fournisseur de votre choix.

4.Pourquoi MVC4 crée-t-il une table UserProfile et une table webpages_Membership? À quoi servent-ils et quelle est la différence? Quelle est la classe UserProfile créée par MVC4?

Les deux tableaux remplissent des fonctions différentes. Le schéma webpages_Membership Est contrôlé par le framework et utilisé pour les informations d'identification, le schéma UserProfile est contrôlé par nous et utilisé pour toutes les propriétés que nous voulons stocker contre un utilisateur.

5.Qu'est-ce que la classe UsersContext?

Il s'agit d'un DbContext (partie de DbContext API ) fourni en tant que début par le modèle d'application Internet MVC. Son seul travail consiste à contenir la classe UserProfile afin que nous puissions travailler avec elle (par exemple via InitializeSimpleMembershipAttribute).

6.Comment tous ces éléments fonctionnent-ils ensemble pour effectuer l'authentification des utilisateurs?

Cela devrait maintenant être évident à partir des résumés ci-dessus et des détails ci-dessous. Utilisez: WebSecurity pour les tâches courantes; UserProfile pour les propriétés personnalisées à stocker sur un utilisateur, accessible via le UsersContext (dans le modèle "MVC Internet Application" de Visual Studio); Membership lorsque WebSecurity ou OAuthWebSecurity n'a pas la méthode; et Roles pour les rôles. Utilisez le contrôleur du modèle VS pour voir des exemples d'utilisation.

Modifier . Au cas où quelqu'un arriverait si loin

Supposons que j'ai une base de données existante ...

Si vous avez une base de données existante et que votre seule raison d'écrire un fournisseur d'adhésion personnalisé est de gérer votre méthode de stockage de mot de passe héritée, vous pouvez utiliser une solution de contournement. Cela ne fonctionnera que si vous pouvez quitter votre ancien stockage de mot de passe pour l'algorithme SimpleMembership (qui utilise la classe Rfc2898DeriveBytes ). Voir la note de bas de page pour plus de détails.

Si vous ne pouvez pas vous éloigner, alors oui, vous devrez créer votre propre fournisseur pour utiliser votre algorithme de mot de passe spécifique, ce que vous pouvez faire en dérivant de SimpleMembershipProvider .

REMARQUE: SimpleMembershipProvider va HACHER vos mots de passe pas les CHIFFREZ . Si vous ne connaissez pas la différence et pourquoi c'est important, réfléchissez-y à deux fois avant de créer votre propre fournisseur avec une sécurité personnalisée


Détail

1.Qu'est-ce que SimpleMembership/SimpleMembershipProvider

Pour comprendre comment tout s'enchaîne, il est utile de comprendre l'histoire.

  • ASP.NET en 2005 a introduit le système d'adhésion ASP.NET
  • Ce système a utilisé des fournisseurs pour extraire les détails de mise en œuvre des interfaces courantes utilisées pour gérer les comptes et les rôles, etc.
  • Cela nous a également donné une capacité de "profil utilisateur" de base (stockée dans un champ xml à une seule colonne que les gens avaient donc tendance à éviter)
  • SimpleMembership a été lancé dans le monde en 2010 en tant que fournisseur qui se connecte au système d'adhésion ASP.NET, mais permet également l'authentification OAuth et le stockage de profil utilisateur de propriété par colonne (à la place du stockage à colonne unique utilisé dans l'implémentation d'origine).
  • SimpleMembershipProvider implémente ExtendedMembershipProvider pour étendre l'implémentation du fournisseur d'origine

C'est Open Source sur codeplex (miroir sur github ). En ce qui concerne la sécurité, vous pouvez donc évaluer le code vous-même, le cloner, le changer, etc. Vous devriez prendre votre propre opinion sur le avantages et inconvénients de sécurité open source , et préparez-le avec une pincée de NIH . ( Vue personnelle: je l'utilise parfois, je ne l'utilise pas d'autres fois)

ExtendedMembershipProvider ajoute en lui-même des commandes comme GeneratePasswordResetToken à l'ancienne API du fournisseur d'appartenance.

2.Qu'est-ce que WebSecurity (WebMatrix.WebData)?

WebSecurity est simplement une façade ou une classe d'assistance, pour fournir un accès simple à SimpleMembershipProvider et rendre les tâches courantes faciles et accessibles en un seul endroit. Il est là à la fois pour vous aider et parce que l'extension du cadre d'origine via ExtendedMembershipProvider signifie que certaines des classes originales comme Membership ne suffisent pas maintenant. Exemples:

  • WebSecurity.CurrentUserName - obtient le nom de l'utilisateur actuellement connecté
  • WebSecurity.CreateUserAndAccount . Créez simultanément un utilisateur et définissez les propriétés du profil utilisateur (par exemple WebSecurity.CreateUserAndAccount(userName, pw, new { Email = model.Email });
  • WebSecurity.InitializeDatabaseConnection - Configurez rapidement une base de données nouvelle/existante à utiliser avec l'appartenance, choisissez votre colonne d'ID utilisateur et l'identifiant de clé naturelle de l'utilisateur, etc.
  • ResetPassword pour réinitialiser un mot de passe utilisateur, GeneratePasswordResetToken et bien d'autres

Ces méthodes reportent généralement au fournisseur que vous utilisez, elles ne dépendent pas seulement de SimpleMembership, et elles lient des objets comme votre fournisseur et Membership pour fournir un point commun à faire des fonctions d'adhésion.

Notez qu'il y a aussi OAuthWebSecurity qui est l'équivalent de WebSecurity pour l'authentification OAuth.

3.Qu'est-ce que la classe Membership (System.Web.Security)?

Membership provient de l'implémentation d'origine; il gère les paramètres utilisateur et effectue des opérations liées à l'utilisateur à l'aide de l'implémentation de base MembershipProvider que ExtendedMembershipProvider étend désormais. Il s'agit d'une classe statique, elle est donc disponible partout où vous déclarez l'espace de noms et est donc un moyen facile, par exemple, de récupérer l'utilisateur actuel: Membership.GetUser

Il y a une confusion causée par le fait que WebSecurity fait certaines choses et pas d'autres, et que Membership fait certaines choses et pas d'autres. Si vous voyez WebSecurity comme une boîte à outils pour les opérations de niveau supérieur et Membership comme une boîte à outils pour faire des choses à un utilisateur, tout ira bien; ils travaillent ensemble sur votre fournisseur.

4.Pourquoi MVC4 crée-t-il une table UserProfile et une table webpages_Membership? À quoi servent-ils et quelle est la différence? Quelle est la classe UserProfile créée par MVC4?

  • webpages_Membership Est une table avec un schéma fixe que nous laissons seul, et permet au fournisseur d'effectuer les opérations de base du compte, principalement en stockant les informations d'identification.
  • UserProfile est un tableau que nous personnalisons pour stocker des informations sur un compte d'utilisateur et que nous mettons à disposition dans un format fortement typé via la classe UserProfile.
  • Il existe une table supplémentaire appelée webpages_OAuthMembership Qui fait le même travail que webpages_Membership, Mais pour OAuth fournisseurs de connexion avec lesquels vous souhaitez vous intégrer.

La magie de cette configuration est qu'un seul utilisateur peut avoir une connexion d'adhésion sur votre propre site et un nombre illimité de connexions OAuth avec différents fournisseurs comme google, facebook, et ils partagent tous un profil commun stocké dans UserProfile

Généralement, si une table commence par webpages_, Cela signifie qu'il existe une API pour y accéder. La table UserProfile est représentée par la classe UserProfile dans votre UsersContext (si vous utilisez le modèle d'application Internet MVC par défaut). Par conséquent, nous y accédons par les méthodes habituelles que nous utiliserions avec n'importe quelle classe contenue dans un DbContext.

UserProfile est très convivial pour le code: vous pouvez ajouter des colonnes (comme l'adresse Email de l'utilisateur), puis configurer une migration pour inclure cette colonne dans votre base de données sur votre prochaine version (si vous comme utiliser les migrations). En fait, la table UserProfile ne doit pas être appelée ainsi - vous pouvez changer cela en utilisant l'appel WebSecurity.InitializeDatabaseConnection, [Table("UserProfile")] public class UserProfile, et vos propres migrations.

5.Qu'est-ce que la classe UsersContext?

Il s'agit du modèle d'application Internet MVC fourni dans Visual Studio New Project. La première chose que je fais est de m'assurer qu'elle partage une chaîne de connexion commune avec mon propre contexte de base de données (en supposant que les tables d'appartenance se trouvent dans la même base de données). Vous pouvez changer cela et les découpler plus tard si vous le souhaitez.

Vous n'avez pas besoin de les séparer de votre propre contexte - cela n'est nécessaire que si vous souhaitez stocker les informations d'appartenance dans une autre base de données maintenant ou à l'avenir. Si vous vous en débarrassez, vous pouvez simplement changer les références à UsersContext à votre propre contexte, en ajustant Database.SetInitializer.

Références:

tilisation de SimpleMembership avec des pages Web ASP.NET - Matthew Osborn - Il s'agit de la référence d'origine sur SimpleMembership et ce que c'est, pourquoi c'est et ce qu'il fait:

MSDN - Introduction to Membership - L'adhésion est toujours au cœur de SimpleMembership, donc cela aide à en comprendre un peu plus.


[~ # ~] modifier [~ # ~] Note de bas de page: les détails pour effectuer une mise à niveau par mot de passe évolutive

  • Ajoutez une propriété à UserProfile qui stocke la version du mot de passe du compte (par exemple 1 pour l'héritage, 2 pour SimpleMembership)
  • Dans l'action "Connexion", écrivez le code de sorte que:
    • S'ils sont sur votre version de mot de passe SimpleMembership, vous vous connectez normalement
    • S'ils sont sur la version héritée du mot de passe, vous:
      • vérifiez-le en utilisant votre ancienne méthode
      • s'il est correct, vous le réinitialisez en utilisant ResetPassword puis ChangePassword pour utiliser la version SimpleMembership, cela mettra à jour le champ vers la nouvelle version du mot de passe
      • et enfin mettre à jour la version du mot de passe sur le UserProfile
  • Mettez à jour toutes les autres méthodes de AccountsController qui utilisent le mot de passe de la même manière.
  • Vivez avec la solution de contournement hacky et le couplage à la table webpages_Membership Que nous ne sommes pas censés toucher car vous n'avez pas eu à écrire un nouveau fournisseur personnalisé.

Il est possible de rendre tout cela transactionnel avec TransactionScope . La seule chose désagréable qui se passe est le code supplémentaire dans le contrôleur et le couplage à webpages_Membership.

184
Andy Brown