读书人

WCF- 访问远程服务SOAP异常

发布时间: 2012-09-17 12:06:51 作者: rapoo

WCF- 访问远程服务SOAP错误
先谢过 再提问。 大侠问题如下:


1 服务其实很简单没什么 ,就是包含了加减乘除四个方法。服务的宿主是个windows service.
2 客户端就是利用服务利用svcutil导出的一个配置文件和元数据cs文件创建了一个客户端来调用服务方法。 但是本地没问题,一旦利用网络中另外一台计算机访问就报错 SOAP security negotiation with "http://../service" failed。

异常

System.ServiceModel.Security.SecurityNegotiationException: SOAP security negotiation with 'http://10.200.46.197:8000/ServiceModelSamples/service' for target 'http://10.200.46.197:8000/ServiceModelSamples/service' failed. See inner exception for more details. --->
at System.ServiceModel.Security.WindowsSspiNegotiation.Decrypt(Byte[] encryptedContent)
at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.CreateWrappedKeyToken(String id, String encryptionMethod, String carriedKeyName, SecurityKeyIdentifier unwrappingTokenIdentifier, Byte[] wrappedKey, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.ReadTokenCore(XmlDictionaryReader reader, SecurityTokenResolver tokenResolver)

Inner Exception:
System.ComponentModel.Win32Exception: The message or signature supplied for verification has been altered
at System.ServiceModel.Security.WindowsSspiNegotiation.Decrypt(Byte[] encryptedContent)
at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.CreateWrappedKeyToken(String id, String encryptionMethod, String carriedKeyName, SecurityKeyIdentifier unwrappingTokenIdentifier, Byte[] wrappedKey, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.WSSecurityJan2004.WrappedKeyTokenEntry.ReadTokenCore(XmlDictionaryReader reader, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.WSSecurityTokenSerializer.ReadTokenCore(XmlReader reader, SecurityTokenResolver tokenResolver)
at System.ServiceModel.Security.WSTrust.Driver.GetIssuedToken(RequestSecurityTokenResponse rstr, SecurityTokenResolver resolver, IList`1 allowedAuthenticators, SecurityKeyEntropyMode keyEntropyMode, Byte[] requestorEntropy, String expectedTokenType, ReadOnlyCollection`1 authorizationPolicies, Int32 defaultKeySize, Boolean isBearerKeyType)
at System.ServiceModel.Security.RequestSecurityTokenResponse.GetIssuedToken(SecurityTokenResolver resolver, IList`1 allowedAuthenticators, SecurityKeyEntropyMode keyEntropyMode, Byte[] requestorEntropy, String expectedTokenType, ReadOnlyCollection`1 authorizationPolicies, Int32 defaultKeySize, Boolean isBearerKeyType)
at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnNegotiationComplete(SspiNegotiationTokenProviderState sspiState, RequestSecurityTokenResponse negotiationRstr, RequestSecurityTokenResponse authenticatorRstr)
at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.GetNextOutgoingMessage(Message incomingMessage, T negotiationState)
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
-----------------------------------

service app config 文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="PubBaseService.CalcService"
behaviorConfiguration="CalculatorServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
</baseAddresses>
</host>
<!-- this endpoint is exposed at the base address provided by host: http://localhost:8000/ServiceModelSamples/service -->


<endpoint address=""
binding="wsHttpBinding"
contract="PubBaseService.ICalc" />
<!-- the mex endpoint is explosed at http://localhost:8000/ServiceModelSamples/service/mex -->
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

--------------------------------

客户端 config 文件

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICalc" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://10.200.46.197:8000/ServiceModelSamples/service"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalc"
contract="ICalc" name="WSHttpBinding_ICalc">
<identity>
<servicePrincipalName value="host/syman-604f21" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>

---------------------------------------------



[解决办法]
<security mode="Message">


改为
<security mode="None">

这个要服务器端和客户端同时修改,禁用默认的安全验证,默认的是用微软的系统登录用户进行验证的,显然不适合不同电脑使用,因为基本不可能两台电脑设置相同的用户名和密码登录。
[解决办法]
这个就要去问微软了,为什么总喜欢使用默认Windows身份验证,我只能告诉你必须关闭。
我们能用的无非就是不验证或者用证书验证,那个Windows身份验证只能在相同用户名密码的情况下使用(使用域管理所有计算机的情况不清楚)。
如果你这类代码写多了,就会发现,很多默认安全配置都应该禁用,微软提供的安全验证基本都是多余且垃圾,我们都是禁用了它的安全认证而启用自己的认证方法——自己建立用户表,匹配登录用户名和密码。

读书人网 >C#

热点推荐