如何绑定到 MVVM 中的 PasswordBox [英] How to bind to a PasswordBox in MVVM

查看:19
本文介绍了如何绑定到 MVVM 中的 PasswordBox的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了绑定到 PasswordBox 的问题.这似乎是一个安全风险,但我使用的是 MVVM 模式,所以我希望绕过它.我在这里发现了一些有趣的代码(有没有人使用过这个或类似的东西?)

I have come across a problem with binding to a PasswordBox. It seems it's a security risk but I am using the MVVM pattern so I wish to bypass this. I found some interesting code here (has anyone used this or something similar?)

http://www.wpftutorial.net/PasswordBox.html

技术上看起来不错,但我不确定如何找回密码.

It technically looks great, but I am unsure of how to retrieve the password.

我的LoginViewModel 中基本上有UsernamePassword 的属性.Username 很好,并且像 TextBox 一样工作.

I basically have properties in my LoginViewModel for Username and Password. Username is fine and is working as it's a TextBox.

我按照上面的说明使用了代码并输入了这个

I used the code above as stated and entered this

<PasswordBox ff:PasswordHelper.Attach="True"
    ff:PasswordHelper.Password="{Binding Path=Password}" Width="130"/>

当我将 PasswordBox 作为 TextBoxBinding Path=Password 时,我的 LoginViewModel 中的属性已更新.

When I had the PasswordBox as a TextBox and Binding Path=Password then the property in my LoginViewModel was updated.

我的代码很简单,基本上我的Button有一个Command.当我按下它时 CanLogin 被调用,如果它返回 true 它调用 Login.
你可以看到我在这里检查了 Username 的属性,这很好用.

My code is very simple, basically I have a Command for my Button. When I press it CanLogin is called and if it returns true it calls Login.
You can see I check my property for Username here which works great.

Login 中,我向我的服务发送了一个 UsernamePasswordUsername 包含来自我的 Username 的数据code>View 但 PasswordNull|Empty

In Login I send along to my service a Username and Password, Username contains data from my View but Password is Null|Empty

private DelegateCommand loginCommand;

public string Username { get; set; }
public string Password { get; set; }


public ICommand LoginCommand
{
    get
    {
        if (loginCommand == null)
        {
            loginCommand = new DelegateCommand(
                Login, CanLogin );
        }
        return loginCommand;
    }
}

private bool CanLogin()
{
    return !string.IsNullOrEmpty(Username);
}

private void Login()
{
    bool result = securityService.IsValidLogin(Username, Password);

    if (result) { }
    else { }
}


这就是我在做的


This is what I am doing

<TextBox Text="{Binding Path=Username, UpdateSourceTrigger=PropertyChanged}"
         MinWidth="180" />

<PasswordBox ff:PasswordHelper.Attach="True" 
             ff:PasswordHelper.Password="{Binding Path=Password}" Width="130"/>

我有我的 TextBox,这没问题,但在我的 ViewModel 中,Password 是空的.

I have my TextBox, this is no problem, but in my ViewModel the Password is empty.

我是不是做错了什么或遗漏了一步?

Am I doing something wrong or missing a step?

我设置了一个断点,代码确实进入了静态帮助器类,但它从不更新我的 ViewModel 中的 Password.

I put a breakpoint and sure enough the code enter the static helper class but it never updates my Password in my ViewModel.

推荐答案

抱歉,您做错了.

人们应该在眼睑内侧纹上以下安全指南:
切勿将纯文本密码保存在内存中.

People should have the following security guideline tattooed on the inside of their eyelids:
Never keep plain text passwords in memory.

WPF/Silverlight PasswordBox 没有为 Password 属性公开 DP 的原因与安全相关.
如果 WPF/Silverlight 为 Password 保留一个 DP,它将要求框架在内存中保持密码本身未加密.这被认为是一个相当麻烦的安全攻击媒介.PasswordBox 使用加密内存(各种),访问密码的唯一方法是通过 CLR 属性.

The reason the WPF/Silverlight PasswordBox doesn't expose a DP for the Password property is security related.
If WPF/Silverlight were to keep a DP for Password it would require the framework to keep the password itself unencrypted in memory. Which is considered quite a troublesome security attack vector. The PasswordBox uses encrypted memory (of sorts) and the only way to access the password is through the CLR property.

我建议在访问 PasswordBox.Password CLR 属性时,不要将它放在任何变量中或作为任何属性的值.
将您的密码以纯文本形式保存在客户端计算机 RAM 上是一项安全禁忌.
所以摆脱那个 public string Password { get;放;} 你已经到了那里.

I would suggest that when accessing the PasswordBox.Password CLR property you'd refrain from placing it in any variable or as a value for any property.
Keeping your password in plain text on the client machine RAM is a security no-no.
So get rid of that public string Password { get; set; } you've got up there.

在访问PasswordBox.Password 时,只需将其取出并尽快发送到服务器.不要保留密码的值,也不要像对待任何其他客户端机器文本一样对待它.不要在内存中保留明文密码.

When accessing PasswordBox.Password, just get it out and ship it to the server ASAP. Don't keep the value of the password around and don't treat it as you would any other client machine text. Don't keep clear text passwords in memory.

我知道这打破了 MVVM 模式,但你永远不应该绑定到 PasswordBox.Password 附加的 DP,将你的密码存储在 ViewModel 或任何其他类似的恶作剧中.

I know this breaks the MVVM pattern, but you shouldn't ever bind to PasswordBox.Password Attached DP, store your password in the ViewModel or any other similar shenanigans.

如果您正在寻找一种过度架构的解决方案,这里有一个:
1. 使用一种返回密码明文的方法创建 IHavePassword 接口.
2. 让您的 UserControl 实现一个 IHavePassword 接口.
3. 向您的 IoC 注册 UserControl 实例以实现 IHavePassword 接口.
4. 当服务器请求需要您的密码时,调用您的 IoC 以实现 IHavePassword 实现,然后只获取梦寐以求的密码.

If you're looking for an over-architected solution, here's one:
1. Create the IHavePassword interface with one method that returns the password clear text.
2. Have your UserControl implement a IHavePassword interface.
3. Register the UserControl instance with your IoC as implementing the IHavePassword interface.
4. When a server request requiring your password is taking place, call your IoC for the IHavePassword implementation and only than get the much coveted password.

只是我的看法.

--贾斯汀

这篇关于如何绑定到 MVVM 中的 PasswordBox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆