【问题标题】:WCF UserName authentication and fault contractsWCF 用户名身份验证和故障合同
【发布时间】:2009-08-24 14:28:33
【问题描述】:

我有一个 WCF 服务配置为通过 System.IdentityModel.Selectors.UserNamePasswordValidator 类的重写 Validate() 方法使用自定义用户名验证。

合同的所有方法都已使用 FaultContractAttribute 进行修饰,以将自定义 SOAP 错误指定为可返回。

当抛出 FaultException(其中 T 是 FaultContractAttribute 中指定的类型)时,一切都按预期运行,并且我在响应 XML 中得到了自定义错误。

但是,如果我尝试在用户名身份验证类的重写 Validate() 方法中抛出 FaultException,我会得到一个通用 SOAP 错误,原因如下:

“此故障的创建者未指定原因。”

但是,如果我更改代码以引发一般 SOAP 错误,如下所示:

throw new FaultException("Authentication failed.");

我至少会得到“身份验证失败”。在原因元素中。

我的问题是:

  • 为什么在 Validate() 中抛出的 FaultException 异常与在服务实现中的处理方式不同?
  • Validate() 方法中抛出的异常是否可以符合合约方法中指定的 FaultContractAttribute?

非常感谢任何帮助。我自己的猜测是,身份验证发生在消息与合同的任何方法关联之前,因此与 FaultContractAttribute 无关,但任何确认这一点并提供解决方法的文章都会非常有用。

大理

【问题讨论】:

  • 感谢您发布此问题。有什么解决办法吗?我仍在寻找 2013 年 3 月的答案。

标签: wcf authentication wcf-security soapfault


【解决方案1】:

这有点烦人,但我通过这样做解决了它:

SecurityTokenValidationException stve = new SecurityTokenValidationException("无效的用户名或密码"); throw new FaultException(stve, stve.Message);

另外包含该消息意味着您不会收到愚蠢的“未指定原因”消息。

【讨论】:

    【解决方案2】:

    问题是自定义验证代码在任何特定OperationContract 的上下文之外运行,因此没有FaultContract 可供WCF 处理。所以简短的回答是否定的,你不能从你的自定义验证器中抛出异常来尊重FaultContract

    这里有几个选项。我更喜欢的是抛出非通用FaultException 并提供预先确定的FaultCode;这样,我的 catch 块可以区分合同故障和“管道”故障。请注意,您从自定义验证器中抛出的任何异常都应返回为 MessageSecurityException,如下所示:

    // 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.
    }
    

    【讨论】:

    • 我尝试了上述方法,但是当我尝试将 ex.innerException 强制转换为 FaultException 时,我得到了一个空值。任何帮助将不胜感激。
    • 那么,内部异常是什么类型的异常呢?如果它不是故障异常,那么您的问题不在服务中。
    • 我在服务器中抛出了一个 Fault Exception 类型,但在客户端它说内部异常是 system.net.webexception 类型,我没有从服务器抛出的 msg。
    • 您确定您使用的是 WCF“服务引用”,而不是尝试使用 WCF over SOAP/XML(“Web 引用”)吗?我相信您所描述的行为是当 WCF 服务异常被抛出到旧版 Web 服务客户端时发生的情况。
    • 我没有使用服务引用我尝试使用 CreateChannel 类与服务进行通信。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2013-10-02
    • 1970-01-01
    • 2010-09-17
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多