2009-08-24 17 views
6

Mam usługę WCF skonfigurowaną do używania niestandardowego sprawdzania poprawności nazwy użytkownika za pomocą overriden Validate() metody klasy System.IdentityModel.Selectors.UserNamePasswordValidator.Uwierzytelnianie WCF UserName i umowy o błędzie

Wszystkie metody umowy zostały udekorowane za pomocą FaultContractAttribute w celu określenia niestandardowego błędu SOAP jako podlegającego zwrotowi.

Podczas rzucania wyjątku FaultException <T>, gdzie T jest typem określonym w klasie FaultContractAttribute, wszystko działa zgodnie z oczekiwaniami, a otrzymuję niestandardowy błąd w pliku XML odpowiedzi.

Jednak gdy próbuję i rzucać FaultException <T> w nadpisane Walidacja() metoda klasy uwierzytelniania nazwę użytkownika, dostaję ogólny błąd SOAP z następującego powodu:

„Twórca tego błędu nie nie określaj przyczyny. "

Jednakże, jeśli mogę zmienić kod, aby rzucić ogólny błąd SOAP jak w:

throw new FaultException("Authentication failed.");

będę przynajmniej dostać „Uwierzytelnienie nie powiodło się.” w elemencie przyczyny.

Moje pytania są następujące:

  • Dlaczego nie są FaultException <T> wyjątki traktowane tak samo, jeśli są wyrzucane w Weryfikuj(), ponieważ są one w ramach realizacji usługi?
  • Czy możliwe jest, aby wyjątki zgłoszone w metodzie Validate() były zgodne z FaultContractAttribute określonym w metodach umowy?

Każda pomoc bardzo doceniona. Domyślam się, że uwierzytelnienie przychodzi, zanim wiadomość jest powiązana z jakąkolwiek metodą umowy, a zatem nie jest powiązane z FaultContractAttribute, ale każdy artykuł potwierdzający to i dający obejście byłby bardzo użyteczny.

Tali

+0

Dzięki za komentarz na to pytanie. Jakieś rozwiązania? Nadal szukam odpowiedzi w marcu 2013 r. –

Odpowiedz

0

To trochę irytujące, ale mam okrągły go w ten sposób:

 
SecurityTokenValidationException stve 
    = new SecurityTokenValidationException("Invalid username or password"); 
throw new FaultException<SecurityTokenValidationException>(stve, stve.Message); 

tym komunikacie dodatkowo oznacza, że ​​nie dostaniesz głupie „nie określił powód” message .

0

Problem polega na tym, że niestandardowy kod sprawdzania poprawności działa poza kontekstem określonego OperationContract, więc nie ma miejsca, w którym można obsługiwać WCF. Tak więc krótka odpowiedź brzmi: nie, nie można uzyskać wyjątków wyrzuconych z niestandardowego walidatora w celu uczczenia FaultContract.

Masz kilka opcji tutaj. Ten, który preferuję, to rzucanie nietypowego FaultException i dostarczenie z góry określonego FaultCode; w ten sposób moje bloki chwytające mogą różnicować wady kontraktu od błędów "hydraulicznych". Należy pamiętać, że każdy wyjątek rzucasz z niestandardowych walidatora powinna wrócić jako MessageSecurityException, jak pokazano poniżej:

// Custom Validator: 
public override void Validate(string userName, string password) 
{ 
    throw new FaultException(
    "Invalid username or password.", 
    new FaultCode("AUTHENTICATION_FAILURE")); 
} 

// Client Code: 
try 
{ 
    client.DoSomething(); 
} 
catch (MessageSecurityException ex) 
{ 
    var inner = ex.InnerException as FaultException; 
    if (inner != null && inner.Code.Name.Equals("AUTHENTICATION_FAILURE")) 
    { 
    // Security failure. 
    } 
} 
catch (FaultException<SomethingFault> ex) 
{ 
    // Exception from the method itself. 
} 
+0

Próbowałem wyżej wymienionych, ale otrzymuję wartość null, gdy próbuję rzutować ex.innerException jako wyjątek FaultException. Każda pomoc będzie doceniona. – vikasse

+0

No cóż, jaki wyjątek stanowi wewnętrzny wyjątek? Jeśli nie jest to wyjątek błędu, problem nie dotyczy serwisu. –

+0

Wrzucam typ wyjątku błędów na serwerze, ale w kliencie jest napisane, że wewnętrzny wyjątek jest typu system.net.webexception i nie mam msg, który wyrzuciłem z serwera. – vikasse