【问题标题】:Can a UserNamePasswordValidator throw anything other than a MessageSecurityException?UserNamePasswordValidator 可以抛出除 MessageSecurityException 之外的任何东西吗?
【发布时间】:2011-12-21 18:01:27
【问题描述】:

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

【问题讨论】:

    标签: c# wcf authentication validation fault


    【解决方案1】:

    几个月前我遇到了同样的问题,经过一些研究,我得出的结论是,你可以从验证器代码中抛出任何你想要的东西,但客户端仍然会得到 MessageSecurityException,它根本不包含任何有用的信息。

    然而,我们必须让客户知道实际发生了什么 - 1.错误的用户名/密码 2.密码过期,需要更改 3. 其他一些自定义应用特定状态

    所以我们更改了 CredentialValidator 逻辑,使其仅在情况 1 中引发异常。在其他情况下,它实际上允许调用真正的 WCF 方法,但我们还会检查密码过期等情况,以防万一有些问题已经从方法体中抛出了 FaultException。

    在我们的例子中,这仅适用于具有此类验证的服务是登录服务 - 因此客户端始终知道他未通过身份验证的确切原因。

    【讨论】:

    • 我不需要向客户端提供有关身份验证失败的详细信息,所以我想我会继续从我的验证器中抛出错误异常。
    【解决方案2】:

    从自定义密码验证器中,您可以返回描述问题所在的 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"));
    

    【讨论】:

    • 使用上述方法的行为是一个 MessageSecurityException 被捕获,而 InnerException 是带有消息和 FaultCode 集的 FaultException。
    【解决方案3】:

    将错误作为 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"));
        }
    }
    

    【讨论】:

    • 如果你抛出一个错误异常,这正是你得到的。 OP 想要传回一个自定义错误(例如 Fault)。
    • - DRAirey1 - 所以这对他不起作用,抛出 new MessageSecurityException("Userid or Password is invalid", new Fault("Userid or Password is invalid"));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 2019-09-25
    • 2021-02-05
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多