我需要连接到远程SOAP服务。几天来,我一直在尝试所有所有配置,但均未成功。
使用SoapUI时连接正常。 从我的.net应用程序调用时,连接为KO。
错误: 未提供用户名。在ClientCredentials中指定用户名。
我的应用程序和远程应用程序都在IIS上运行。
这是远程绑定:
<bindings>
<wsHttpBinding>
<binding name="WsHttpBinding_Default" maxReceivedMessageSize="524288000" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
SoapUI使用以下配置:
当我检查SoapUI的原始请求时,它正在发送此消息:
POST https://domain.name/TestNode/V_ServicePartenaireDS/v5.svc HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="http://URI/getUser"
Authorization: Basic UEFSVFxzdmMtaWlzYmsdfsdfsdfphZG1pbjEyMy0t
Content-Length: 1371
Host: proxy-int.part.lan.net
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v2="http://cnc.fr/Circe/Partenaires/v2.7">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsse:Security soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Timestamp wsu:Id="TS-268FDC1861EA4F5F3C154297086643492">
<wsu:Created>2018-11-23T11:01:06Z</wsu:Created>
<wsu:Expires>2018-11-23T16:34:26Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-268FDC1861EA4F5F3C154297086643491">
<wsse:Username>PART\svc-iisbackend</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pwd</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">yi71/jQzUJw/lzReixSgOA==</wsse:Nonce>
<wsu:Created>2018-11-23T11:01:06.434Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<wsa:Action>http://UIR/getUser</wsa:Action>
</soap:Header>
<soap:Body>
<v2:getUser>
<!--Optional:-->
<v2:id>200785</v2:id>
</v2:getUser>
</soap:Body>
</soap:Envelope>
以上所有内容均有效。
现在,我在.net 4.6.1应用程序中正在做什么?我正在尝试发送与SoapUI正在发送的相同请求。
这是我的工作方式:带有端点,绑定和行为扩展的web.config。扩展行为实现了一个Endpoint Behavior,该Endpoint Behavior调用了一个Inspector(来自ApplyClientBehavior),我使用BeforeSendRequest从中添加了两件事:
<wsse:Security />
以下是实现的详细信息。
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WsHttpBinding_Default" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
<binding name="WsHttpBinding_Authentication" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00">
<security mode="Transport">
<transport clientCredentialType="Basic" />
<message clientCredentialType="UserName" />
</security>
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</wsHttpBinding>
<basicHttpBinding>
<binding name="BasicHttp_Default" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00" />
</basicHttpBinding>
</bindings>
<extensions>
<behaviorExtensions>
<add name="localSecurity" type="Users.UsersImplementation.Service.ImplementationCommon.BehaviorExtensionBasicAuthent, Users.UsersImplementation"/>
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="LocalWsBehavior">
<callbackDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<localSecurity/>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="https://domain/TestNode/V_ServiceUser/v5.svc" behaviorConfiguration="LocalWsBehavior" binding="wsHttpBinding" bindingConfiguration="WsHttpBinding_Authentication" contract="App.UserDSContract.IServiceUserDS" name="" />
<!--<headers>
<wsse:Security xmlns:soap="schemas.xmlsoap.org/soap/envelope" soap:mustUnderstand="true" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Timestamp wsu:Id="TS-268FDC1861EA4F5F3C154289160250080">
<wsu:Created>2018-11-22T15:15:02Z</wsu:Created>
<wsu:Expires>2018-11-22T18:33:22Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-268FDC1861EA4F5F3C154289160250079">
<wsse:Username>PART\svc-iisbackend</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pws</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">NcDsjgc1/cRNuHVMR7kJBw==</wsse:Nonce>
<wsu:Created>2018-11-22T15:15:02.499Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</headers>
</endpoint>-->
</client>
</system.serviceModel>
在c#类的链下,我们找到以下代码:
void IClientMessageInspector.AfterReceiveReply(ref Message reply, object correlationState)
{
// nothing to do here
}
object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
{
SoapSecurityHeader header = new SoapSecurityHeader("PART\\svc-iisbackend", "pwd");
request.Headers.Add(header);
HttpRequestMessageProperty httpRequestMessage;
object httpRequestMessageObject;
if (request.Properties.TryGetValue(HttpRequestMessageProperty.Name, out httpRequestMessageObject))
{
httpRequestMessage = httpRequestMessageObject as HttpRequestMessageProperty;
if (string.IsNullOrEmpty(httpRequestMessage.Headers[HttpRequestHeader.Authorization]))
{
httpRequestMessage.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("PART\\svc-iisbackend-sagre" + ":" + "admin123--"));
}
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
else
{
httpRequestMessage = new HttpRequestMessageProperty();
httpRequestMessage.Headers.Add(HttpRequestHeader.Authorization, "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes("PART\\svc-iisbackend-sagre" + ":" + "admin123--")));
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
return header.Id;
}
在远程服务器端*上得到的SOAP信封是这样的:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://UIR/getUser</a:Action>
<a:MessageID>urn:uuid:2b66b328-778f-4967-925a-01b75d9ab607</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<wsse:Security s:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Timestamp wsu:Id="TS-f7abfe27c28e4209b8c028ef78bdf739">
<wsu:Created>2018-11-23T14:37:46.59Z</wsu:Created>
<wsu:Expires>2018-11-23T16:37:46.59Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UsernameToken-aff0ea1c178c4843babf4afa5cd280f6">
<wsse:Username>PART\svc-iisbackend</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">pwd</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">qdiFSufkRLuPRHTwDYPzBDTu1/o=</wsse:Nonce>
<wsu:Created>2018-11-23T14:37:46.593Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<a:To s:mustUnderstand="1">https://domain.url/V_ServiceUser/v5.svc</a:To>
</s:Header>
<s:Body>
<getUser xmlns="http://url">
<id>200472</id>
</getUser>
</s:Body>
</s:Envelope>
直到现在,我已经关注了许多博客和文档,但我仍然受困:D
*要获取发送到服务器的消息,我需要使用默认的绑定配置WsHttpBinding_Default。当我使用WsHttpBinding_Authentication时,远程服务器似乎未处理该请求。
我尝试使用绑定配置,但到目前为止还没有运气。
错误:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
<a:RelatesTo>urn:uuid:2b66b328-778f-4967-925a-01b75d9ab607</a:RelatesTo>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode>
<s:Value xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">a:InvalidSecurity</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="fr-FR">Une erreur s'est produite lors de la vérification de la sécurité du message.</s:Text>
</s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
对不起,我希望这里有清晰了解我问题的所有内容。 非常感谢您到目前为止阅读:)
Edit:如您所见,我还尝试将标头直接放在xml端点中,但到目前为止没有成功。
编辑:调用绑定错误,现在是:
<binding name="WsHttpBinding_Authentication" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" openTimeout="00:10:00" closeTimeout="00:10:00" sendTimeout="00:10:00" receiveTimeout="00:10:00">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic" />
<message clientCredentialType="UserName" />
</security>
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
有了新的绑定,我的错误现在是:
{"globalErrors":["Message with Action 'http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT' is unknown and cannot be forwarded to the recipient. This may happen if message Action was changed, or if operation was disabled or deleted from the service contract."]}
我找不到有关此错误的内容,发生了什么:/
编辑:通过在绑定中重新添加establishSecurityContext="false"
解决了该错误。
编辑:要添加凭据,我正在使用该答案:Set WCF ClientCredentials in App.config
似乎可行,我正在朝着一个旧错误迈进:An error occurred when verifying security for the message.
答案 0 :(得分:0)
要将用户名和密码添加到服务,则在设置服务时需要执行以下操作
// Instantiate the proxy
Service1Client proxy = new Service1Client();
// Set the user’s credentials on the proxy
proxy.ClientCredentials.UserName.UserName = username;
proxy.ClientCredentials.UserName.Password = password;
这是当您使用标准WS用户名和密码时,在遇到完全相同的问题后,我也对自己的问题添加了答案,链接为WCF Service inside aspnet webforms throwing 302
您可以从Microsoft
阅读更多内容答案 1 :(得分:0)
解决了!!!
非常沮丧,但是写一篇SO帖子并保持更新很有帮助。
我庆祝了,我将再次详细介绍解决方案。
简而言之,请使用我在编辑中添加的链接中的实现,而不是以前的方法。