UserNamePasswordValidator可以抛出除MessageSecurityException以外的任何内容吗?

时间:2011-12-21 18:01:27

标签: c# wcf authentication validation fault

我通过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会产生各种问题,包括服务器/客户端时间同步......),并且由于第三方将使用该服务,因此我希望尽可能清楚。

3 个答案:

答案 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"));
    }
}