English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Celui qui connaît bien le système d'authentification MS Identity doit savoir que le rôle de UserManager est le coordonnateur de l'ensemble du système, il définit un ensemble de comportements d'utilisateur pour nous aider à gérer les informations utilisateur, les informations de rôle, et à traiter les mots de passe. Son implémentation se trouve dans UserStore, nous pouvons l'implémenter pour définir ce que nous voulons, par exemple IUserStore, IUserPasswordStore, IRoleStore, etc. Nous pouvons nous baser sur un ensemble de comportements utilisateur pour personnaliser nos informations utilisateur, notre structure de données et notre stockage de données. Alors, concernant le Hasher de mot de passe, MS nous fournit toujours une définition complète du comportement, et il est coordonné par UserManager. Par exemple
UserManager.PasswordHasher.HashPassword(password)
PasswordHasher est ainsi défini dans l'interface UserManager :
Je n'étais pas intéressé par son implémentation par défaut, dans le but d'indépendance de l'authentification de connexion de plusieurs applications, donc j'ai besoin d'un projet d'authentification d'utilisateur indépendant en tant que service d'authentification, qui ne produit que des jetons, après l'authentification réussie, l'Header d'Authorization de l'HTTP Request du utilisateur contient le jeton pour accéder aux ressources de diverses applications sur le serveur d'application.
C'est précisément pour cette raison que sur plusieurs applications, une telle question est apparue dans l'authentification des mots de passe :
Par exemple, l'application A utilise l'implémentation IPasswordHasher pour personnalisier la méthode de cryptage - MD5+La forme de sel, tandis que l'application B utilise PasswordHasher par défaut de Identity pour la mise en œuvre, obtenue par désassemblage du code suivant :
Afin de garantir la compatibilité avec différentes méthodes de cryptage utilisées par diverses applications, je dois décompiler le code source par défaut, obtenir la méthode de cryptage par défaut, déterminer par le nom de l'application différente si le mot de passe doit être crypté ou déchiffré, ou directement comparer le mot de passe entré par l'utilisateur avec la base de données via un certain mode.
// Decompiled with JetBrains decompiler // Type: Microsoft.AspNet.Identity.Crypto // Assembly: Microsoft.AspNet.Identity.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 // MVID: E3A10FFD-023A-4BC3-AD53-32D145ABF1C9 // Assembly location: C:\Sport\NewProject\V2.0\Api\Fantasy.Sport\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll using System; using System.Runtime.CompilerServices; using System.Security.Cryptography; namespace Microsoft.AspNet.Identity { internal static class Crypto { private const int PBKDF2IterCount = 1000; private const int PBKDF2SubkeyLength = 32; private const int SaltSize = 16; public static string HashPassword(string password) { if (password == null) throw new ArgumentNullException("password"); byte[] salt; byte[] bytes; using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, 16, 1000)) { salt = rfc2898DeriveBytes.Salt; bytes = rfc2898DeriveBytes.GetBytes(32); } byte[] inArray = new byte[49]; Buffer.BlockCopy((Array) salt, 0, (Array) inArray, 1, 16); Buffer.BlockCopy((Array) bytes, 0, (Array) inArray, 17, 32); return Convert.ToBase64String(inArray); } public static bool VerifyHashedPassword(string hashedPassword, string password) { if (hashedPassword == null) return false; if (password == null) throw new ArgumentNullException("password"); byte[] numArray = Convert.FromBase64String(hashedPassword); if (numArray.Length != 49 || (int) numArray[0] != 0) return false; byte[] salt = new byte[16]; Buffer.BlockCopy((Array) numArray, 1, (Array) salt, 0, 16); byte[] a = new byte[32]; Buffer.BlockCopy((Array) numArray, 17, (Array) a, 0, 32); byte[] bytes; using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, 1000)) bytes = rfc2898DeriveBytes.GetBytes(32); return Crypto.ByteArraysEqual(a, bytes); } [MethodImpl(MethodImplOptions.NoOptimization)] private static bool ByteArraysEqual(byte[] a, byte[] b) { if (object.ReferenceEquals((object) a, (object) b)) return true; if (a == null || b == null || a.Length != b.Length) return false; bool flag = true; for (int index = 0; index < a.Length; ++index) flag &= (int) a[index] == (int) b[index]; return flag; } } }
Quelqu'un pourrait demander, comment appliquer ces codes sources obtenus. Voici une brève explication de cette question.
Au début, je pensais naïvement que c'était juste un cryptage, pas besoin de le regarder en détail, on peut l'utiliser directement ?
Lors de l'enregistrement des utilisateurs et de la modification des mots de passe, ils sont tous cryptés par le HashPassword ci-dessus. Alors, dans le nouveau PasswordHasher personnalisé, pour comparer le mot de passe de connexion utilisateur avec l'application B, ne serait-ce pas mieux de crypter directement l'entrée utilisateur par HashPassword ? Donc, ma méthode VerifyHashedPassword (Verify traduit par vérification) compare si le Pwd dans la base de données et le résultat traité par hasher sont égaux. Mais le résultat est que chaque chaîne de caractères identique produit un résultat de cryptage différent, et avant de jouer md5+Le sel est différent. Alors je me suis rappelé de la méthode par défaut implementée VerifyHashedPassword.
Donc, en dernier lieu, vous pouvez utiliser directement le mode de cryptage de Microsoft Identity (le Hasher ci-dessus) et utiliser la méthode VerifyHashedPassword () pour comparer l'entrée utilisateur et le résultat de stockage hashé dans la base de données. Même sans authentification Identity, vous pouvez utiliser cet algorithme de cryptage
Voici la fin de cet article, j'espère que le contenu de cet article peut vous apporter un certain aide à l'apprentissage ou au travail, et j'espère aussi que vous pouvez soutenir le tutoriel d'alarme !
Déclaration : le contenu de cet article est tiré d'Internet, propriété des auteurs respectifs, le contenu est apporté par les utilisateurs d'Internet de manière spontanée et téléversé, ce site ne possède pas de propriété, n'a pas été traité par l'éditeur humain et n'assume aucune responsabilité juridique. Si vous trouvez du contenu suspect de violation de droits d'auteur, veuillez envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois vérifié, ce site supprimera immédiatement le contenu suspect de violation de droits d'auteur.)