2010-08-09 11 views
8

Przeczytałem kilka artykułów o tym, jak używać Attached Properties do wiązania wartości PasswordBox w WPF. Jednak każdy artykuł odwołuje się również do dokumentacji .NET, która wyjaśnia, dlaczego PasswordBox nie został w ogóle stworzony jako bindable.Używanie PasswordBox z WPF - MVVM

Nie uważam się w żaden sposób za eksperta od zabezpieczeń, ale sądzę, że ktoś w firmie Microsoft wiedział, co robią, i nie powinienem wysilać się, próbując go cofnąć.

Zamiast tego wpadłem na własne rozwiązanie.

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

Następnie w moim XAML, po prostu uczynić PasswordBox poprzez wiązanie pole Hasło do ContentPresenter.

Moje pytanie brzmi: czy jest jakiś problem z robieniem tego w ten sposób? Zdaję sobie sprawę, że w pewien sposób przełamuję MVVM, pozwalając, by rzeczywiste formanty pojawiły się w moim ViewModelu, ale przynajmniej wydaje się to bardziej poprawne niż po prostu odblokowanie pola hasła.

Jeśli to jest rzeczywiście problem, czy ktoś ma rozwiązanie, które nie wymaga użycia Załączonych właściwości i przechowywania hasła w ViewModel?

Dzięki! -J

+1

Na czym polega problem z załączonym podejściem do nieruchomości? Czy typ własności to ciąg? Dlaczego nie zrobić SecureString? –

+0

Tak jak powiedziałem powyżej, po prostu wydawało się, że był powód, dla którego nie był to DependencyProperty, więc znalezienie sposobu na obejście problemu wydawało się niewłaściwym podejściem. Przypuszczam, że mógłbym równie łatwo "związać" się z właściwością SecurePassword. – jeremyalan

+1

Problem, gdy właściwość Hasło można powiązać, to: wartość jest łatwo śledzona przez oprogramowanie zewnętrzne. takie jak SNOOP. jak łatwo ukraść twoje hasło. – ktutnik

Odpowiedz

6

Co jest złego przechowywania hasła w VM przynajmniej, gdy jest to potrzebne przy logowaniu? Masz rację, że zgodnie ze wzorem MVVM maszyna wirtualna nie powinna mieć odniesienia do kontrolki takiej jak PasswordBox.

W widoku dodaj program obsługi do zdarzenia PasswordChanged. W module obsługi zaktualizuj właściwość SecureString w maszynie wirtualnej za pomocą haseł SecurePassword w polu hasła.

+0

Jak wspomniano powyżej, nie jestem ekspertem ds. Bezpieczeństwa, staram się jak najlepiej postępować zgodnie z wytycznymi określonymi w dokumentacji. Ale czy istnieje jakiekolwiek ryzyko związane z utrzymywaniem odwołania do pamięci w funkcji SecureString, w przeciwieństwie do łańcucha? Wydaje się, że gdyby to nie był problem, to wiążące bezpośrednio do niego byłoby częścią ram. – jeremyalan

+0

Powodem, dla którego właściwość Hasło hasła PasswordBox nie jest DP, wyjaśniono tutaj przez osobę z firmy Microsoft: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/7ca97b60-2d8e-4a27-8c5b- b8d5d7370a5e /. Domyślam się, że nowa właściwość SecurePassword nie jest DP, ponieważ obawiają się, że zostanie zakotwiczona w pamięci, jeśli ktoś się na nią zapisze i zapomni wyczyścić ją po zalogowaniu. Ale to tylko domysły. –

+0

Dzięki za odpowiedź. Czy istnieje metoda "wyczyszczenia" po zalogowaniu, więc mogę zagwarantować, że wartość nie jest przechowywana w pamięci po zniknięciu strony logowania? – jeremyalan

0

Podoba mi się twój pomysł.

Tak, jesteś naruszono ViewModel najlepszych praktyk tutaj, ale

  • najlepsze praktyki są „Zalecenia, które działają dobrze w większości przypadków” zamiast surowych zasad i
  • pisanie proste, łatwe do odczytania, Kod konserwowalny i unikanie niepotrzebnej złożoności jest również jedną z tych zasad "najlepszej praktyki" (która może być nieznacznie naruszona przez obejście "dołączonej nieruchomości").

czy łamiąc barierę View/ViewModel tutaj będzie dla Ciebie problem, czy nie, zależy od dlaczego używasz ViewModels w pierwszej kolejności (np oddzielenie obawy, testowanie jednostkowe, ponownego użycia), więc nie mogę na to odpowiedzieć.

2

to tylko opinia, że ​​może ci pomóc.

  1. Myślę, że pomysł nie tomake Password jako DP jest łatwy do śledzenia za pomocą zewnętrznego oprogramowania, takiego jak SNOOP.
  2. Najmniejsza zależność od modelu widoku, tym lepszy kod. to pomoże Ci na testowanie jednostkowe i uaktualnienia lub zmiany (co byś zrobił, gdyby w przyszłości chcesz użyć trzeciego pola hasło partia?)
  3. Wyrzucić stan „Code Behind jest bezużyteczny” używać go mądrze.

Rozważ to w kodzie za:

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

zapomniałem. Powinieneś użyć metody View-First, aby to zrobić. – ktutnik

0

moje 2 centy:

zaszyfrować hasło w modelu widoku, za pomocą dołączonych właściwości i użyć ValueConverter do szyfrowania/deszyfrowania hasło. z tym, nawet jeśli ktoś używa snoopa, to widzą tylko zaszyfrowane dane.

daj nam znać, co najlepiej pasuje do Twojej sytuacji.