Проблемы с выходом из системы с помощью WPF и служб клиентских приложений - PullRequest
2 голосов
/ 22 октября 2010

Я недавно создавал прототип приложения, используя WPF и Client Application Services. Я пытаюсь использовать все три функции служб клиентских приложений: проверку подлинности с помощью форм, безопасность ролей и профиль клиента. Мне удалось заставить все работать, но я чувствую, что мое решение - клочок и хочу лучшего пути.

Для обсуждения предположим следующее:

У меня есть два окна WPF:

Первое окно - моя основная форма заявки. Имеет две кнопки «Войти» и «Проверить тему» ​​

Второе окно представляет собой форму входа в систему, которая реализует интерфейс IClientFormsAuthenticationCredentialsProvider для использования метода GetCredentials для возврата нового объекта ClientFormsAuthenticationCredentials с введенными именем пользователя и паролем.

Приложение запускается, загружается главное окно, и пользователь нажимает кнопку входа в систему. В событии нажатия кнопки вызывается System.Web.Security.Membership.ValidateUser (String.Empty, String.Empty). Это вызывает метод GetCredentials в моей форме входа в систему, который в свою очередь показывает окно входа в систему. Код в событии нажатия кнопки главного окна ожидает, пока пользователь не введет информацию в окно входа в систему.

Как только пользователь отправляет информацию для входа в систему, форма входа в систему закрывается, поток выполнения возвращается к событию щелчка входа в главное окно. Если введенные имя пользователя и пароль действительны, Thread.CurrentPrincipal имеет соответствующий принципал FormAuthentication.

Если мы вернемся к форме главного окна и нажмем кнопку «Проверить принципала потока» и проверим Thread.CurrentPrincipal для события нажатия кнопки, мы увидим, что Thread.CurrentPrincipal больше не является принципалом FormsAuthentication, а вместо этого общий принципал Windows.

В своем исследовании я нашел несколько способов справиться с этим:

Первый - вызвать AppDomain.CurrentDomain.SetThreadPrincipal (Thread.CurrentPrincipal) сразу после проверки пользователя. Это обеспечит сохранение принципала FormsAuthentication в течение всего срока службы приложения. Проблема в том, что я не могу установить его дважды. Поэтому, если я вызываю метод ClientFormsAuthenticationMembershipProvider.LogOut () и пытаюсь снова выполнить процесс входа в систему. Я получаю исключение «Основной объект по умолчанию не может быть установлен дважды».

Второй метод, и метод, который я выбрал для своего прототипа, заключается в создании класса с именем UserAuthentication. В этом классе есть статическое свойство с именем Current, которое возвращает синглтон типа UserAuthentication. В классе UserAuthentication я поддерживаю свои собственные свойства CurrentPrinipal и Original Principal, которые имеют тип IPrincipal. У меня также есть методы LogIn и LogOut, которые управляют вызовами к System.Web.Security.Membership.ValidateUser (String.Empty, String.Empty) и ClientFormsAuthenticationMembershipProvider.LogOut () и поддерживают состояние моих инкапсулированных свойств CurrentPrinipal и Original Principal.

Делая это как единое целое, я все еще могу получить доступ к функциональности IsInRole, вызвав CommonAssembly.UserAuthentication.Current.CurrentPrincipal.IsInRole ("SomeRole"). И я могу реализовать функцию профиля клиента, гарантируя, что перед вызовом Properties.Settings.Default.Save () я вызываю System.Threading.Thread.CurrentPrincipal = CommonAssembly.UserAuthentication.Current.CurrentPrincipal.

Это работает, но я чувствую, что это клочок, и в своих исследованиях я не смог найти адекватного решения. Я понимаю, что часть проблемы заключается в том, как WPF обрабатывает контекст выполнения, но я чувствую, что ДОЛЖЕН быть лучший способ.

Надеюсь, мои пояснения и примеры встроенного кода не слишком запутаны. Код, необходимый для реализации всего этого, - больше, чем я могу поместить в пост.

FYI. Я видел похожие потоки при переполнении стека, но ни один из них не дал адекватного ответа на вопрос. Я также видел примеры реализации служб клиентских приложений в Интернете, но ни один из них не использовал WPF без Silverlight.

Так есть ли лучший метод, который позволяет мне использовать Thread.CurrentPrincipal для входа в систему / выхода из системы, который устраняет необходимость в моем собственном Принципале?

Я ценю любую помощь или понимание, которое может предоставить каждый.

С уважением,

Bernie

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...