IIS部署wsHttpBinding绑定WCF服务报错:调用方未通过服务身份验证
问题根因
wsHttpBinding 默认使用 Windows 集成身份验证 作为安全模式,本地VS开发环境运行时,服务会自动携带当前登录用户的Windows凭据完成认证,所以可以正常跑通;但部署到IIS后,仅在IIS层面开启了匿名认证,没有修改WCF绑定的默认安全配置,服务端仍然要求客户端提供Windows身份凭据,客户端默认未传递对应凭据,就会抛出The caller was not authenticated by the service错误。
修复方案
方案1:公开匿名访问场景(无需身份校验)
直接同步修改服务端、客户端的wsHttpBinding配置,关闭绑定层的安全校验即可。
- 第一步:修改服务端
web.config的wsHttpBinding节点,显式关闭安全认证:
<bindings> <wsHttpBinding> <binding name="wsHttpBinding"> <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> <!-- 新增以下配置关闭安全认证 --> <security mode="None" /> </binding> </wsHttpBinding> </bindings>
- 第二步:同步修改客户端
app.config的wsHttpBinding节点,安全模式必须和服务端完全一致:
<bindings> <wsHttpBinding> <binding name="WSHttp_OA_Server_Endpoint2" > <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> <!-- 新增以下配置,和服务端安全模式保持一致 --> <security mode="None" /> </binding> </wsHttpBinding> </bindings>
- 第三步:删除客户端配置中
<identity>节点下的SPN配置,该配置仅用于Windows域认证场景,匿名访问不需要保留:
<!-- 删除整段identity配置 <identity> <servicePrincipalName value="host/AMAZONA-XXXXXX1" /> </identity> -->
修改完成后重启IIS站点,直接运行客户端测试即可,不需要重新生成服务引用。
方案2:Windows身份认证场景(内网域环境使用)
如果业务要求必须做Windows身份校验,不要关闭安全配置,按以下步骤调整:
- 第一步:打开IIS站点的「身份验证」功能,禁用匿名身份验证,启用「Windows身份验证」;如果IIS功能列表里找不到Windows身份验证选项,先去服务器管理器添加Windows认证对应的角色功能。
- 第二步:修改服务端wsHttpBinding配置,显式指定安全模式和凭据类型:
<!-- HTTP站点用Message模式 --> <security mode="Message"> <message clientCredentialType="Windows" /> </security> <!-- HTTPS站点用Transport模式 <security mode="Transport"> <transport clientCredentialType="Windows" /> </security> -->
- 第三步:客户端配置的安全模式和服务端保持一致,调用代码里显式传入凭据:
ServiceReference4.WSHttp_OA_ServerSoapClient c1 = new ServiceReference4.WSHttp_OA_ServerSoapClient(); // 传入当前登录用户的Windows凭据 c1.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials; // 跨域访问时需要显式指定域账号信息 // c1.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("用户名","密码","域名"); string[] a = c1.GetMethods(); foreach (string ss in a) { Console.WriteLine(ss); }
- 第四步:核对客户端配置里的SPN值,必须和IIS应用程序池的运行账号匹配:应用程序池用NetworkService/LocalSystem内置账号时,SPN值填
host/服务访问域名;用自定义域账号运行池时,SPN要配置为对应域账号的注册SPN。
常见排查点
- 核对服务端
web.config里的服务name属性、端点contract属性,必须和实际服务类、服务接口的完全限定名(命名空间+类名)完全一致,命名空间写错会导致自定义配置不生效,自动走默认绑定规则。 - 先在浏览器直接访问
http://example.com/Service1.svc,能正常打开WCF服务说明页才说明服务部署本身没有问题。 - 配置正确仍然报错时,可以开启WCF消息日志查看具体的认证失败环节,能快速定位是配置不匹配、凭据无效还是SPN错误。
内容的提问来源于stack exchange,提问作者user2717643
相关产品推荐
相关产品推荐

