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.
Veuillez répondre aux questions suivantes (brièvement, si possible):
Qu'est-ce que SimpleMembership/SimpleMembershipProvider ( WebMatrix.WebData ) et de quoi sont-ils responsables?
Qu'est-ce que WebSecurity ( WebMatrix.WebData )?
Qu'est-ce que la classe Membership ( System.Web.Security )?
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?
Qu'est-ce que la classe sersContext?
Comment tous ces éléments fonctionnent-ils ensemble pour effectuer l'authentification des utilisateurs?
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é ?
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.
J'ai placé une prime sur cette question et j'ai l'intention de l'attribuer à Andy Brown pour une réponse exceptionnelle.
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é.
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
Pour comprendre comment tout s'enchaîne, il est utile de comprendre l'histoire.
SimpleMembershipProvider
implémente ExtendedMembershipProvider
pour étendre l'implémentation du fournisseur d'origineC'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.
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'autresCes 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.
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.
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
.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.
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.
WebSecurity
OAuthWebSecurity
SimpleMembershipProvider
ExtendedMembershipProvider
SimpleRoleProvider
Membership
Roles
DbContext
et API DbContext[~ # ~] modifier [~ # ~] Note de bas de page: les détails pour effectuer une mise à niveau par mot de passe évolutive
UserProfile
qui stocke la version du mot de passe du compte (par exemple 1 pour l'héritage, 2 pour SimpleMembership)ResetPassword
puis ChangePassword
pour utiliser la version SimpleMembership, cela mettra à jour le champ vers la nouvelle version du mot de passeUserProfile
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
.