Изучаю WCF. Дано WinForms приложение и WCF сервисы.
Задача клиента вполне стандартная, отображать в гриде список данных и позволять редактировать его. Но так,
чтобы просматривать могли все (т.е. анонимные пользователи), а редактировать только зарегестрированные пользователи с определенными ролями. В двух словах, пользователь открывает пприложение — ему сразу загружаются какие то данные в гриды. Как только захотел поредактировать — залогинился и редактируй сколько хошь.
Остановился я на использовании message security с custom membership provider в качестве механизма аутентификации и авторизации.
При реализации столкнулся со следующими проблемами:
1. Если сервису установить binding с clientCredentialType = UserName и настроить membership provider и role provider
<binding name="UserNameBinding">
<security>
<message clientCredentialType="UserName" />
</security>
</binding>
то сервис прекрасно валидирует и проверяет роли пользователя, что нужно для редактирования. Но не позволяет выполнить методы анонимным пользователям, требуя credential-ы при выполнении любого метода.
А если сервису установить binding с clientCredentialType = None,
<binding name="AnonymousBinding">
<security>
<message clientCredentialType="None" />
</security>
</binding>
то прекрасно выполняются методы не требующие аутентификации и не требуется передача credentials, но при этом нельзя выполнить методы требующие проверки роли пользователя даже если credentials передаются.
Собственно вопрос, как можно сделать так, чтобы один и тот же сервис позволял выполнять одни методы любым пользователям (даже анонимным), а для выполнения других производил валидацию пользователя и пароля?
Windows аутентификацию не предлагать. Обязательное условие — использование membership provider модели.
2. Где и как наиболее удобно и секьюрно хранить введенные пользователем логин и пароль после аутентификации? На данный момент я не придумал ничего лучше , как создать свой Identity класс с открытым полем Password и записывать его в поток, выглядит так:
// если пользователь прошел проверку пароля
Thread.CurrentPrincipal = new WZPrincipal(new WZIdentity(username, password, true));
а дальше при каждом вызове метода сервиса я просто пихаю сохраненные креденшиалы.
WZIdentitycurrentIdentity = Thread.CurrentPrincipal.Identity as WZIdentity;
if (currentIdentity != null)
{
_WZClient.ClientCredentials.UserName.UserName = currentIdentity.Name;
_WZClient.ClientCredentials.UserName.Password = currentIdentity.Password;
}
// вызов метода сервиса
Нормально ли это?
Буду очень благодарен за любые советы.