Bonjour,
En WPF il est impossible de binder la propriété Password d'une PasswordBox. La raison invoquée est la sécurité.
Cependant en silverlight (depuis la version 3) c'est possible.
Quelqu'un connait-il la raison de cette différence ?
Bonjour,
En WPF il est impossible de binder la propriété Password d'une PasswordBox. La raison invoquée est la sécurité.
Cependant en silverlight (depuis la version 3) c'est possible.
Quelqu'un connait-il la raison de cette différence ?
En WPF le mot de passe n'est pas stocké en clair en mémoire, il est stocké dans une SecureString (accessible via la propriété SecurePassword). La propriété Password matérialise le mot de passe en clair.
Pour pouvoir binder la propriété Password, il faudrait que ce soit une DependencyProperty, et dans ce cas sa valeur serait stockée en mémoire ce qui annule l'intérêt du SecurePassword.
En Silverlight, la classe SecureString n'est pas disponible, donc pas de SecurePassword, donc le mot de passe est stocké en clair en mémoire de toutes façons. Donc il n'y a pas de raison que ce ne soit pas une DependencyProperty...
Perso j'ai jamais été très convaincu de l'intérêt de la classe SecureString. A un moment ou un autre, on va avoir besoin du password en clair de toutes façons...
Il y a une astuce pour contourner ce problème : il faut créer une propriété attachée qui va gérer le password via l'évènement PasswordChanged.
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public static class PasswordBoxBehavior { public static bool GetBindPassword(DependencyObject obj) { return (bool)obj.GetValue(BindPasswordProperty); } public static void SetBindPassword(DependencyObject obj, bool value) { obj.SetValue(BindPasswordProperty, value); } public static readonly DependencyProperty BindPasswordProperty = DependencyProperty.RegisterAttached( "BindPassword", typeof(bool), typeof(PasswordBoxBehavior), new UIPropertyMetadata( false, BindPasswordChanged)); private static void BindPasswordChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { var passwordBox = o as PasswordBox; if (passwordBox == null) return; var oldValue = (bool)e.OldValue; var newValue = (bool)e.NewValue; if (oldValue && !newValue) { passwordBox.PasswordChanged -= passwordBox_PasswordChanged; } else if (newValue && !oldValue) { string password = GetPassword(passwordBox); if (!string.IsNullOrEmpty(password)) passwordBox.Password = password; passwordBox.PasswordChanged += passwordBox_PasswordChanged; } } static void passwordBox_PasswordChanged(object sender, RoutedEventArgs e) { var passwordBox = (PasswordBox)sender; if (passwordBox == null) return; SetPassword(passwordBox, passwordBox.Password); } public static string GetPassword(DependencyObject obj) { return (string)obj.GetValue(PasswordProperty); } public static void SetPassword(DependencyObject obj, string value) { obj.SetValue(PasswordProperty, value); } public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached( "Password", typeof(string), typeof(PasswordBoxBehavior), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, PasswordChanged)); private static void PasswordChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { var passwordBox = o as PasswordBox; if (passwordBox == null) return; string newValue = (string)e.NewValue; if (GetBindPassword(passwordBox)) { string current = passwordBox.Password; if (current != newValue) passwordBox.Password = newValue; } } }
Ca s'utilise comme ça :
Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 <PasswordBox Name="pwd" my:PasswordBoxBehavior.BindPassword="True" my:PasswordBoxBehavior.Password="{Binding Password, UpdateSourceTrigger=PropertyChanged}" />
Pas de questions techniques par MP ! Le forum est là pour ça...
Tutoriels : Les nouveautés de C# 6 - Accès aux données avec Dapper - Extraction de données de pages web à l'aide de HTML Agility Pack - La sérialisation XML avec .NET (Aller plus loin) - Les markup extensions en WPF
Merci pour cette précision.
Je trouve quand même très bizarre que dans un cas on considère la sécurité et que dans l'autre on n'en ai plus rien à faire...
Je suis d'accord avec toiPerso j'ai jamais été très convaincu de l'intérêt de la classe SecureString. A un moment ou un autre, on va avoir besoin du password en clair de toutes façons...
Partager