wpf - PasswordBox PasswordHelper 多重绑定
问题描述
在 WPF 中 a 的Password
属性PasswordBox
不是 aDependencyProperty
所以我不能直接绑定到它。作为一种解决方法,我PasswordHelper
从https://www.wpftutorial.net/PasswordBox.html使用它,它附加了 aPasswordHelper.Password
以便PasswordBox
我可以绑定到它。
为了防止密码DataContext
以纯文本形式存在,我想使用一个转换器,它会在将密码保存到DataContext
. 因为我需要将 salt 和 salted hash 都保存到DataContext
我正在使用的 aMultiBinding
和 aIMultiValueConverter
转换器StringToSaltedHashConverter
中。
我Password
的问题是当我填写. 我已经检查了 Snoop 并且和的属性都根据我输入的内容而变化。我也被调用,我正在返回正确的值。PasswordSalt
DataContext
PasswordBox
Password
PasswordHelper.Password
PasswordBox
StringToSaltedHashConverter
我在这个表单上有一些其他的绑定(用户名、名字、姓氏、性别......),它们都可以正常工作。这是唯一不更新的。
¿ 为什么我DataContext
没有得到更新?
XAML:
<PasswordBox x:Name="Password"
Style="{DynamicResource PasswordBoxStyle1}"
local:PasswordHelper.Attach="True">
<local:PasswordHelper.Password>
<MultiBinding Converter="{StaticResource StringToSaltedHashConverter}"
Mode="OneWayToSource">
<Binding Path="Password" />
<Binding Path="PasswordSalt" />
</MultiBinding>
</local:PasswordHelper.Password>
</PasswordBox>
后面的代码:
public class StringToSaltedHashConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
string str = value as string;
string salt = Hash.CreateSalt();
string hash = Hash.CreateHash(str, salt);
object[] vs = { hash, salt };
return vs;
}
}
解决方案
这不是要走的路。PasswordHelper
班级和他们的喜欢应该被禁止上网。该PasswordBox.Password
属性不可绑定有一个很好的理由,这是有据可查的。访问此属性将创建一个纯文本string
表示,可以使用免费工具(例如 Microsoft Process Explorer)轻松检索该表示。
当您获得 Password 属性值时,您将密码作为纯文本公开在内存中。要避免这种潜在的安全风险,请使用 SecurePassword 属性以 SecureString 形式获取密码。
将此属性设置为 null 会导致基础密码设置为空。
您甚至将纯盐值存储在内存中 - 我真的希望这既不是商业应用程序也不是公共应用程序。您完全无法控制垃圾收集器何时从内存中删除任何值。由于String
是不可变类型,因此用户密码的多个副本很可能会在内存中保持公开。
在 Windows 环境中推荐的身份验证是使用 Windows 用户身份验证 API。
您至少应该PasswordBox.Password
通过设置它来清除该属性null
。
不应在视图中进行加密。
请编写负责任的代码!用户数据不是您的数据!
主窗口.xaml
<Window>
<Window.DataContext>
<ViewModel />
</Window.DataContext>
<PasswordBox x:Name="PasswordBox" />
</Window>
主窗口.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.PasswordBox.PasswordChanged += OnPasswordChanged;
}
private void OnPasswordChanged(object sender, RoutedEventArgs e)
{
(this.DataContext as ViewModel).Password = this.PasswordBox.SecurePassword;
}
}
视图模型.cs
pucblic class ViewModel
{
private Model Model { get; }
private SecureString password;
public SecureString Password
{
private get => this.password;
public set
{
this.password = value;
OnPasswordChanged();
}
}
private void OnPasswordChanged()
{
// Hash password in the model e.g. to compare it to a hashed database value
this.Model.TryLogin(this.Password);
}
}
模型.cs
public class Model
{
public bool TryLogin(SecureString password)
{
IntPtr unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(password);
string hashedPassword = HashPassword(Marshal.PtrToStringUni(unmanagedString));
return PasswordIsValid(hashedPassword);
}
private string HashPassword(string unsecurePassword)
{
// Hash algorithm
}
}
推荐阅读
- c# - NullException:值不能未定义。参数名称:来源
- azure - 将 spark 数据帧从 azure databricks 写入 S3 会导致 java.lang.VerifyError: Bad type on operand stack 错误
- python - 用os.walk()搜索所有的excel文件,然后调用函数读取这个excel,怎么办?
- javascript - ng2-file-upload 单个请求 clearQueue() 不起作用
- c# - 如何组合列表
与列表 - >?
- android - 在模块 jetified-hamcrest-core-1.3.jar 中发现重复的类 org.hamcrest.BaseDescription
- java - Postgres:将自定义类型从 Java 传递给 postgres 函数
- css - Angular - 单击按钮后更改表中行的背景颜色
- android - facebook sdk 还需要在 android 上手动初始化吗?
- java - 将自定义元数据添加到二进制文件