2010-08-09 23 views
8

He leído varios artículos sobre cómo usar las Propiedades adjuntas para vincular el valor de un PasswordBox en WPF. Sin embargo, cada artículo también hace referencia a la documentación de .NET que explica por qué PasswordBox no se hizo enlazable en primer lugar.Uso de PasswordBox con WPF - MVVM

No me considero un experto en seguridad de ninguna manera, pero me imagino que alguien en Microsoft sabía lo que estaban haciendo, y no debería esforzarme al máximo para deshacerlo.

Entonces, en cambio, se me ocurrió mi propia solución.

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... 
    } 
} 

Entonces, en mi XAML, sólo han prestado los PasswordBox mediante la unión del campo de contraseña a un ContentPresenter.

Así que mi pregunta es ... ¿hay algún problema al hacerlo de esta manera? Me doy cuenta de que estoy rompiendo el MVVM de alguna manera al permitir que los controles reales aparezcan en mi ViewModel, pero al menos esto parece más correcto que simplemente desproteger el campo de contraseña.

Si esto es, de hecho, un problema, ¿alguien ha presentado una solución que no implique el uso de Propiedades adjuntas y el almacenamiento de la contraseña en el modelo de vista?

Gracias! -J

+1

¿Cuál es exactamente el problema con el enfoque de la propiedad adjunta? ¿Es que el tipo de propiedad es una cadena? ¿Por qué no hacerlo SecureString? –

+0

Como dije antes, parecía que había una razón por la cual no era una DependencyProperty para empezar, por lo que encontrar una solución alternativa parecía ser el enfoque equivocado. Supongo que podría simplemente "enlazar" a la propiedad SecurePassword en su lugar. – jeremyalan

+1

El problema cuando la propiedad de Contraseña es enlazable es: su valor es fácilmente rastreado por un software externo. como SNOOP. qué fácil es robar tu contraseña entonces. – ktutnik

Respuesta

6

¿Qué hay de malo en almacenar la contraseña en la VM al menos mientras es necesaria durante el inicio de sesión? Tiene razón en que, según el patrón de MVVM, la VM no debería tener una referencia a un control como PasswordBox.

En la vista, agregue un controlador al evento PasswordChanged. En el controlador, actualice una propiedad SecureString en la máquina virtual con SecurePassword de la contraseña.

+0

Como se mencionó anteriormente, no soy un experto en seguridad, solo hago mi mejor esfuerzo para seguir las pautas establecidas en la documentación. Pero, ¿hay algún riesgo relacionado con mantener una referencia en memoria de un SecureString, en lugar de una cadena? Parece que si esto no fuera un problema, entonces vincularlo directamente sería parte del marco. – jeremyalan

+0

La razón por la cual la propiedad de contraseña de PasswordBox no es un DP se explica aquí por alguien de Microsoft: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/7ca97b60-2d8e-4a27-8c5b- b8d5d7370a5e /. Supongo que la nueva propiedad SecurePassword no es un DP porque temen que quede anclado en la memoria si alguien se une a él y olvida borrarlo después de iniciar sesión. Pero eso es solo una suposición. –

+0

Gracias por la respuesta. ¿Hay algún método para "borrarlo" después de iniciar sesión, por lo que puedo garantizar que el valor no se guarde en la memoria una vez que la página de inicio de sesión desaparezca? – jeremyalan

0

Me gusta tu idea.

Sí, se están violando las mejores prácticas ViewModel aquí, pero

  • mejores prácticas son "recomendaciones que funcionan bien en la mayoría de los casos" en lugar de reglas estrictas y
  • escritura sencilla, de fácil lectura-, código que se puede mantener y evitar la complejidad innecesaria es también una de esas reglas de "mejores prácticas" (que podrían ser violadas levemente por la solución de "propiedad adjunta").

Ya sea rompiendo la barrera Vista/modelo de vista que aquí será un problema para usted o no depende de qué está utilizando ViewModels en el primer lugar (por ejemplo, la separación de las preocupaciones, las pruebas unitarias, reutilización), por lo que no puedo responder eso.

2

es solo una opinión espero que pueda ayudarlo.

  1. Creo que la idea de no tomar Password como DP es que es fácilmente rastreado por un software externo como SNOOP.
  2. La menor dependencia en View Model que tenga, mejor será su código. lo ayudará con las pruebas unitarias y la Actualización o los cambios (¿qué haría si en el futuro desea utilizar un cuadro de contraseña de un tercero?)
  3. Deseche el estado "El código no sirve". Úselo con prudencia.

considerar esto en su código detrás:

void loginButton_Clicked(object s, EventArgs e) 
{ 
    myViewModel.Password = txPwdBox.Password; 
    myViewModel.Login(); 
} 
+0

lo olvidé ... debe usar el enfoque Vista-Primero para hacer esto. – ktutnik

0

mis 2 centavos:

cifrar la contraseña en el modelo de vista, utilizar las propiedades adjuntas, y utilizar un ValueConverter para cifrar/descifrar el contraseña. con esto, incluso si alguien usa snoop, entonces todo lo que ven son los datos encriptados.

díganos qué funciona mejor con su situación