You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向WebService传递WindowsIdentity遇编译错误,求解决方案

解决Web服务传递WindowsIdentity的类型不匹配问题

我来帮你理清楚这个问题的原因和解决方案:

首先,你遇到的类型不匹配不是安全措施,而是SOAP Web服务(比如ASMX这类)的序列化机制导致的。当你添加Web服务引用时,Visual Studio会根据服务端的WSDL生成客户端代理类——服务端的WindowsIdentity会被解析成一个全新的、属于你的WS命名空间的WindowsIdentity类(也就是WSCommunicationTest.WS.WindowsIdentity),它和系统自带的System.Security.Principal.WindowsIdentity完全是两个不同的类型,只是字段可能类似,所以编译器会报错无法转换。

而且更关键的是:你根本没法直接传递WindowsIdentity对象。因为WindowsIdentity包含很多无法被SOAP序列化的内容,比如安全令牌的句柄、底层的安全上下文资源,这些都是不能通过XML跨进程传输的。

那该怎么处理你的需求呢?分两种情况:

1. 只是需要传递用户的身份信息(比如用户名、SID)

不要直接传WindowsIdentity,而是提取它的可序列化字段作为参数传递:

  • 服务端修改方法:
[WebMethod]
public void GetWI(string userSid) {
    // 根据SID重新构造WindowsIdentity(需要对应权限)
    using (WindowsIdentity wi = new WindowsIdentity(userSid))
    {
        // 你的业务处理逻辑
    }
}

或者传递用户名:

[WebMethod]
public void GetWI(string userName) {
    // 根据用户名完成身份验证或其他逻辑
}
  • 客户端调用时提取对应字段:
public void Test() {
    WindowsIdentity wd = WindowsIdentity.GetCurrent();
    WS.WStestSoapClient clt = new WS.WStestSoapClient();
    // 传递用户SID
    clt.getWI(wd.User.Value);
}

2. 需要传递当前用户的身份上下文,让服务端识别调用者身份

这时候根本不需要手动传参数,直接开启Web服务的Windows身份验证即可,客户端调用时会自动传递当前用户的Windows身份:

服务端配置(web.config)

<system.web>
  <!-- 启用Windows身份验证 -->
  <authentication mode="Windows"/>
  <!-- 拒绝匿名访问,确保只有授权用户能调用 -->
  <authorization>
    <deny users="?"/>
  </authorization>
</system.web>

服务端方法直接获取身份

[WebMethod]
public void GetWI() {
    // 直接从上下文获取当前调用者的Windows身份
    WindowsIdentity wi = HttpContext.Current.User.Identity as WindowsIdentity;
    if (wi != null)
    {
        // 你的业务处理逻辑
    }
}

客户端配置(app.config/web.config)

确保绑定启用Windows身份验证:

<system.serviceModel>
  <bindings>
    <basicHttpBinding>
      <binding name="WStestSoap">
        <security mode="TransportCredentialOnly">
          <!-- 指定使用Windows身份验证 -->
          <transport clientCredentialType="Windows"/>
        </security>
      </binding>
    </basicHttpBinding>
  </bindings>
</system.serviceModel>

客户端调用

public void Test() {
    WS.WStestSoapClient clt = new WS.WStestSoapClient();
    // 直接调用,身份会自动传递给服务端
    clt.getWI();
}

总结一下:直接传递WindowsIdentity对象是不可行的,要么传递它的可序列化字段,要么利用Windows身份验证自动传递上下文。

内容的提问来源于stack exchange,提问作者MrHeliose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:56:49