I have a WCF service hooked up with a UserNamePasswordValidator through my web.config, no problem there. In my validator, I override Validate, check the credentials and throw a FaultException if necessary.
Example:
public class CredentialValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName != "dummy")
{
throw new FaultException<AuthenticationFault>(new AuthenticationFault(), "Invalid credentials supplied");
}
}
}
If I consume this service myself in a .NET application and provide invalid credentials, a MessageSecurityException is thrown with the following message:
"An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail."
The FaultException I had expected is the InnerException of the MessageSecurityException.
Is there any way to have the client receive just the FaultException?
The MessageSecurityException isn't particularly descriptive concerning the true cause of the exception (a quick search on SO yields a variety of problems including server/client time sync..), and since a third party will be consuming the service, I'd like to be as clear as possible.
I had the very same issue some months ago and after some research I came to the conclusion that you may throw whatever you want from validator code, but client will still get MessageSecurityException, which contains no useful information at all.
We had to however give the client to know what actually happened - 1. wrong username/password 2. password expired, change needed 3. some other custom application specific states
So we changed CredentialValidator logic in a way that it throws exception only in case 1. In other cases it would actually allow the real WCF method to be called, but there we would check also for password expiration etc. and in case of some problems throw FaultException already from method body.
In our case this worked well for only service with this type of validation was log-in service - so the client would always know why exactly he wasn't authenticated.
From custom password validator you can return FaultCode that describe what's wrong:
throw new FaultException("Invalid user name or bad password.", new FaultCode("BadUserNameOrPassword"));
throw new FaultException("Password expired.", new FaultCode("PasswordExpired"));
throw new FaultException("Internal service error.", new FaultCode("InternalError"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With