WCF 给出了一个不安全或不正确安全的错误

我正在尝试使用一个远程 svc Web 服务。我使用 svcutil.exe创建了代理类,之后我将这个类添加到我的控制台应用中,但是它产生了一个错误:

从另一方收到不安全的错误或不正确的安全错误。有关错误代码和详细信息,请参见内部错误异常。

System.ServiceModel.FaultException: 在验证消息的安全性时发生错误

我没有创建 WCF 端,这是一个远程 svc。请帮助。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="EloquaDataTransferService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Mtom" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://secure.eloqua.com/API/1.2/DataTransferService.svc"
binding="basicHttpBinding" bindingConfiguration="EloquaDataTransferService"
contract="DataTransferService" name="EloquaDataTransferService" />
</client>
</system.serviceModel>
</configuration>

这是我的 app.config文件。我提供的用户名和密码在我的 consoleApp.cs文件使用 obj.ServiceCredentials.UserName.UserName="xxxxxx".Password="xxxXx"

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="EloquaDataTransferService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Mtom" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://secure.eloqua.com/API/1.2/DataTransferService.svc" binding="basicHttpBinding" bindingConfiguration="EloquaDataTransferService" contract="DataTransferService" name="EloquaDataTransferService" />
</client>
</system.serviceModel>
</configuration>
146430 次浏览

显然,WCF 安全子系统存在问题。你用的是什么装订?什么认证?加密?签字?你必须跨域边界吗?

进一步的研究表明,如果客户端和服务器的时钟不同步(超过5分钟) ,那么其他人就会遇到这个错误,因为一些安全模式依赖于同步的时钟。

尝试将您的安全模式更改为“传输”。

您的安全标记和传输标记不匹配。

这是 WCF 服务抛出的一个非常隐晦的错误。问题是 WCF 无法验证传递给服务的消息的安全性。

这几乎总是因为服务器时间偏差。远程服务器和客户机的系统时间必须(通常)相距不超过10分钟。否则,安全性验证将失败。

我会给 eloqua.com 打电话,看看他们的服务器时间是多少,然后和你的服务器时间进行比较。

我还遇到过服务引用过期的问题,即使服务器和客户端在同一台机器上也是如此。运行“更新服务参考”通常会修复这个问题。

在我的例子中,我在测试客户机-服务器应用程序的同一台机器上得到了这个错误。但是这个问题通过“更新服务参考”得到了解决。

  • Tushar G. Walavalkar

值得一提的是——我也有这个错误,发现它是由 web services web.config 中的连接字符串被设置为连接到错误的机器引起的。

虽然你的问题已经通过上面的一个解决方案得到了解决,但是为了其他人的利益,这里还有另一个选择。

当不正确的凭据被传递 到使用用户名消息凭据的基本端点(SOAP 1.1)时,您也可以得到这个异常。例如,如果您从代码调用服务并执行以下操作:

var service = new TestService();


service.ClientCredentials.UserName.UserName = "InvalidUser";
service.ClientCredentials.UserName.Password = "InvalidPass";

这与传递无效凭据时抛出 AccessDeniedException的 WSHTTP 端点(SOAP 1.2)不同。我个人认为这里包含的信息有一点误导性(我第一次遇到它的时候肯定花了我几分钟的时间) ,但是当我查阅 WCF 诊断跟踪日志的时候,潜在的原因是明确的。

在我的例子中,当我将 wshttpbinding协议从 https改为 http时,它就开始工作了。

如果您正在从客户端传递用户凭据(如下面的代码块所示) ,那么它应该与服务器上的用户名/密码相匹配。否则就会得到这个错误。

仅供参考,在我的例子中,我使用了带有“ Transportation WithMessageCredential”安全模式的“ basicHTTPAuthentication”。WCF 服务驻留在 https 上的 IIS 中。

var service = new TestService();


service.ClientCredentials.UserName.UserName = "InvalidUser";
service.ClientCredentials.UserName.Password = "InvalidPass";

希望这对某人有所帮助... :)

我的客户端应用程序遇到的同样问题是 WinForms 应用程序 C # 4.0

当我在这里阅读解决方案,我检查日期和客户端计算机的时间,但这是正确的,当前的时间显示,但我仍然面临这些问题。

经过一些工作,我发现错误的时区已经选择,我在印度和时区是加拿大,主机服务器位于科威特。

我发现这个系统可以把时间转换成宇宙时间。

当我把时区改成印度时区时,问题就解决了。

在我的例子中,有两个问题将引发此异常。

请注意,我的环境使用单点登录(或 STS,如果您愿意)通过 ASP.NET MVC 站点对用户进行身份验证。MVC 站点依次向我的服务端点发出服务调用,通过传递之前用 Bootstrap 令牌从 STS 服务器请求的持有者令牌。我得到的错误是当我从 MVC 网站打服务电话。

  1. 在我的 SSO 中,WCF 服务没有配置为依赖方(如果您愿意,也可以称为 STS)。

  2. 服务的配置没有正确配置,特别是在 system.Identity 模型的 audenceUris 节点上,它必须与服务端点 URL 完全匹配。

    <system.identityModel>
    <identityConfiguration>
    <audienceUris>
    <add value="https://localhost/IdpExample.YService/YService.svc" />
    </audienceUris>
    ....
    </identityConfiguration>
    </system.identityModel>
    

确保打开客户机后 SendTimeout没有过期。

试试这个:

catch (System.Reflection.TargetInvocationException e1)
String excType
excType = e1.InnerException.GetType().ToString()
choose case excType
case "System.ServiceModel.FaultException"
System.ServiceModel.FaultException e2
e2 = e1.InnerException
System.ServiceModel.Channels.MessageFault fault
fault = e2.CreateMessageFault()
ls_message = "Class: uo_bcfeWS, Method: registraUnilateral ~r~n" + "Exception(1): " + fault.Reason.ToString()
if (fault.HasDetail) then
System.Xml.XmlReader reader
reader = fault.GetReaderAtDetailContents()
ls_message += " " + reader.Value
do while reader.Read()
ls_message += reader.Value
loop
end if
case "System.Text.DecoderFallbackException"
System.Text.DecoderFallbackException e3
e3 = e1.InnerException
ls_message = "Class: uo_bcfeWS, Method: registraUnilateral ~r~n" + "Exception(1): " + e3.Message
case else
ls_message = "Class: uo_bcfeWS, Method: registraUnilateral ~r~n" + "Exception(1): " + e1.Message
end choose
MessageBox ( "Error", ls_message )
//logError(ls_message)
return false

由于 BasicHttpBinding 没有向正在调用的服务发送兼容的 messageVersion,我得到了这个错误。我的解决方案是使用下面这样的自定义绑定

 <bindings>
<customBinding>
<binding name="Soap11UserNameOverTransport" openTimeout="00:01:00" receiveTimeout="00:1:00" >
<security authenticationMode="UserNameOverTransport">
</security>
<textMessageEncoding messageVersion="Soap11WSAddressing10" writeEncoding="utf-8" />
<httpsTransport></httpsTransport>
</binding>
</customBinding>
</bindings>

在我的例子中,我使用证书进行身份验证,证书验证模式设置为“ PeerTrust”,我忘记在 windows store (LocalMachine TrustedPeople)中安装客户端证书,以使其被服务器接受。

只是为了分享... 我有一个罕见的情况下,让我抓了我的后脑勺几分钟。即使时间偏差的解决方案是非常精确的,我以前解决过这个问题,这次不同。我在一台新的 Win8.1机器上,我记得有一个时区问题,我手动调整了时间。尽管服务器和客户端显示的时间只有几秒钟的差异,但是我还是不断得到这个错误。我所做的就是在“日期和时间设置”中激活“夏季储存选项”(注意我确实在夏季储存时间,但是手动设置了时间) ,然后进入互联网时间部分并刷新... 我电脑中的时间保持不变,但是错误消失了。

希望这对任何人都有用!

大多数情况下,这种异常发生在服务器中出现一些错误时,最常见的错误是身份验证数据库的错误配置或身份验证。在我的情况下,有不同的时钟同步 确保客户端和服务器具有相同的设置

点击右下角的时间-> “更改日期时间设置...”-> “因特网时间”选项卡-> 更改设置...-> 检查“与因特网时间服务器同步”选项,如果它未被选中-> 从服务器下拉菜单中选择“ times.windows.com”-> 立即更新-> 确定

<wsHttpBinding>
<binding name="ISG_Binding_Configuration" bypassProxyOnLocal="true" useDefaultWebProxy="false" hostNameComparisonMode="WeakWildcard" sendTimeout="00:30:00" receiveTimeout="00:30:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
<readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" />
<security mode="None">
<message establishSecurityContext="false" clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>

在它工作之前,我必须将 SecurityMode 更改为 Message (WSHttpBinding)。

_wcf = new ServiceRequestClient(new WSHttpBinding(SecurityMode.Message),
new EndpointAddress(_wcfRequestServerAddress));

在我的例子中,它是 IIS 应用程序池上的一个设置。

选择应用程序池—— > 高级设置—— > 将“启用32位应用程序”设置为 True。

然后回收应用程序池。

在我的例子中,服务器时间不正确。因此,我将服务器 Datetime 设置更改为自动设置时间,它解决了这个问题。