tags:

views:

222

answers:

4

I've read several articles about how to use Attached Properties to bind to the value of a PasswordBox in WPF. However, every article also references the .NET documentation which explains why the PasswordBox was not made bindable in the first place.

I do not consider myself a security expert by any means, but I figure that someone at Microsoft knew what they were doing, and I shouldn't be putting forth the effort trying to undo it.

So, instead, I came up with my own solution.

public class LoginViewModel
{
   // other properties here

   public PasswordBox Password
   {
      get { return m_passwordBox; }
   }

   // Executed when the Login button is clicked.
   private void LoginExecute()
   {
      var password = Password.SecurePassword;

      // do more stuff...
   }
}

Then, in my XAML, I just render the PasswordBox by binding the Password field to a ContentPresenter.

So my question is... is there a problem with doing it this way? I realize that I'm sort of breaking the MVVM in a way by letting actual controls appear in my ViewModel, but at least this seems more correct than just un-securing the password field.

If this is, in fact, a problem, has anyone come up with a solution that doesn't involve using Attached Properties and storing the password in the ViewModel?

Thanks! -J

+1  A: 

What is wrong with storing the password in the VM at least while it is needed during login? You are correct that according to MVVM pattern the VM should not have a reference to a control like a PasswordBox.

In the view, add a handler to the PasswordChanged event. In the handler, update a SecureString property in the VM with the SecurePassword of the passwordbox.

Wallstreet Programmer
As mentioned above, I'm no security expert, I'm just trying my best to follow the guidelines laid out by the documentation. But are there any risks involved with keeping an in-memory reference to a SecureString, as opposed to a string? It seems like if this wasn't an issue, then binding directly to it would be part of the framework.
ph0enix
The reason why Password property of PasswordBox is not a DP is explained here by someone from Microsoft: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/7ca97b60-2d8e-4a27-8c5b-b8d5d7370a5e/. I guess the new SecurePassword property is not a DP is because they are afraid it will be anchored in memory if someone databinds to it and forgets to clear it after login. But that is only a guess.
Wallstreet Programmer
Thanks for the response. Is there a method of "clearing it" after login, so I can guarantee that the value is not sitting in memory after the login page disappears?
ph0enix
OK, duh... I just got to tinkering with the API, and realized that there is a Clear method on the SecureString. I assume this is what I'm looking for? TIA -J
ph0enix
My solution ended up being a hodge-podge of ideas, but this was the idea that got me started. Essentially, I created an Attached Property which allows me to bind to the SecurePassword property. Thanks for your input!
ph0enix
A: 

I like your idea.

Yes, you are violating ViewModel best practices here, but

  • best practices are "recommendations that work well in most cases" rather than strict rules and
  • writing simple, easy-to-read, maintainable code and avoiding unnecessary complexity is also one of those "best practice" rules (which might be violated slightly by the "attached property" workaround).

Whether breaking the View/ViewModel barrier here will be a problem for you or not depends on why you are using ViewModels in the first place (e.g., separation of concerns, unit testing, reusability), so I cannot answer that.

Heinzi
+1  A: 

it is only an opinion hope it can help you.

  1. I think the idea not tomake Password as DP is it is easily tracked by external software such as SNOOP.
  2. The least dependency on View Model you have, the better your code. it will help you on unit testing and Upgrade or changes (what would you do if in the future you want to use a third party password box?)
  3. Throw away the state "Code Behind is Useless" use it wisely.

Consider this in your code behind:

void loginButton_Clicked(object s, EventArgs e)
{
    myViewModel.Password = txPwdBox.Password;
    myViewModel.Login();
}
ktutnik
i forgot.. you should use View-First approach to do this.
ktutnik
A: 

my 2 cents:

Encrypt the password in the view model, use the attached properties, and use a ValueConverter to encrypt/decrypt the password. with this even if somebody uses snoop then all they see is the encrypted data.

let us know what works best with your situation

nathan_hc