我通过web.config连接了一个带有UserNamePasswordValidator的WCF服务,没问题。在我的验证器中,我重写Validate,检查凭据并在必要时抛出FaultException。
示例:
public class CredentialValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName != "dummy")
{
throw new FaultException<AuthenticationFault>(new AuthenticationFault(), "Invalid credentials supplied");
}
}
}
如果我在.NET应用程序中自己使用此服务并提供无效凭据,则会抛出MessageSecurityException,并显示以下消息:
“从另一方收到了一个不安全或不正确安全的故障。请参阅内部FaultException以获取故障代码和详细信息。”
我预期的FaultException是MessageSecurityException的InnerException。
有没有办法让客户端只收到FaultException?
MessageSecurityException并不特别描述异常的真正原因(快速搜索SO会产生各种问题,包括服务器/客户端时间同步......),并且由于第三方将使用该服务,因此我希望尽可能清楚。
答案 0 :(得分:3)
几个月前我遇到了同样的问题,经过一些研究后我得出的结论是,你可以从验证器代码中抛出任何你想要的东西,但是客户端仍然会得到MessageSecurityException,它根本不包含任何有用的信息。
然而,我们必须让客户知道实际发生了什么 - 1.用户名/密码错误 2.密码已过期,需要更改 3.一些其他自定义应用程序特定状态
所以我们改变了CredentialValidator逻辑,它只在案例1中抛出异常。在其他情况下,它实际上允许调用真正的WCF方法,但是我们也会检查密码到期等。如果是一些问题已经从方法体中抛出了FaultException。
在我们的案例中,这种方法仅适用于此类验证的服务是登录服务 - 所以客户端总是知道为什么他没有经过身份验证。
答案 1 :(得分:1)
从自定义密码验证程序中,您可以返回描述错误的FaultCode:
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"));
答案 2 :(得分:0)
将错误抛出为MessageSecurityException,内部异常为FaultException
public override void Validate(string userName, string password)
{
var isValid = ValidateUser(userName, password);
if (!isValid)
{
throw new MessageSecurityException("Userid or Password is invalid", new FaultException("Userid or Password is invalid"));
}
}