Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.119.109.119] |
|
Сообщ.
#1
,
|
|
|
Помогите разобраться с UserNamePasswordValidator. У меня есть свой валидатор
public class AdminUserNameValidator : UserNamePasswordValidator { UserProvider _ProviderUser = new UserProvider(); public override void Validate(string userName, string password) { if (!_ProviderUser.UserExists(userName, password)) throw new SecurityTokenException("Пользователь с таким именем/паролем не найден в системе"); if (!_ProviderUser.UserIsAdmin(userName)) throw new SecurityTokenException("Пользователь не имеет прав администратора"); } } Соответственно эксепшены идут на сервере, а клиент ничего не знает об ошибке. Ему только через некоторое время сообщают об истечении таймаута. Как передавать причину отказа непосредственно клиенту?? Код сервиса _Host = new ServiceHost(typeof(ServiceAdmin)); // создаем двунаправленную привязку // и устанавливаем аутентификацию по UserName WSDualHttpBinding binding = new WSDualHttpBinding(); binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; // устанавливаем параметры аутентификации _Host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; _Host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new AdminUserNameValidator(); // ищем нужный сертификат в хранилище X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); X509Certificate2 cert = null; certStore.Open(OpenFlags.ReadOnly); for (int i = 0; i < certStore.Certificates.Count; i++) if (certStore.Certificates[i].SubjectName.Name == "CN=CertServer") cert = certStore.Certificates[i]; certStore.Close(); if (cert == null) { Logger.LogError("Не найден сертификат для сервера", "Сервер не запущен!"); return; } // указываем используемый сертификат _Host.Credentials.ServiceCertificate.Certificate = cert; // наша конечная точка _Host.AddServiceEndpoint(typeof(IServiceAdmin), binding, new Uri("http://localhost:999/ServiceAdmin")); // mex _Host.Description.Behaviors.Add(new ServiceMetadataBehavior()); Binding mexBinding = MetadataExchangeBindings.CreateMexHttpBinding(); _Host.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, new Uri("http://localhost:999/ServiceAdmin/mex")); _Host.Open(); И клиента (со сгенеренными прокси) // указываем используемый сертификат X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); X509Certificate2 cert = null; certStore.Open(OpenFlags.ReadOnly); for (int i = 0; i < certStore.Certificates.Count; i++) if (certStore.Certificates[i].SubjectName.Name == "CN=CertClient") cert = certStore.Certificates[i]; certStore.Close(); _Client.ClientCredentials.ClientCertificate.Certificate = cert; _Client.ClientCredentials.UserName.UserName = "name"; _Client.ClientCredentials.UserName.Password = "pass"; // тут эксепшн _Client.Open(); |
Сообщ.
#2
,
|
|
|
Посмотри сюда: Обработка ошибок в Windows Communication Foundation
|
Сообщ.
#3
,
|
|
|
почему-то так и предполагал
|
Сообщ.
#4
,
|
|
|
В MSDN нашел примерчик How to: Use a Custom User Name and Password Validator. Сделал по аналогии - не работает. У клиента вылетает тот же TimeOutException.
Вообще как FaultException может передаться клиенту если сам канал еще не создан? |
Сообщ.
#5
,
|
|
|
все работает. только не так как я предполагал. FaultException оборачивается в другое исключение в моем случае это MessageSecurityException. Такой код решил проблему
try { сlient.Open(); } catch (MessageSecurityException ex) { if (ex.InnerException as FaultException != null) { Console.WriteLine(ex.InnerException.Message); } else throw; } |