I am trying to send a request to a web service. The wsdl can be seen here
https://amsel.dpwn.net/abholportal/gw/lp/schema/1.0/var3ws.wsdl
Creating a request is straight forward
BookLabelRequest request = new BookLabelRequest();
RpPartnerType rpt = new RpPartnerTypeClient();
dhlService.BookLabelResponse response = rpt.BookLabel(new dhlService.BookLabelRequest());
but how do i pass the required parameters to it when there is no serializable BookLabelRequest exposed? and how do i pass the username/password in the header?
Sample SOAP request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:var="https://amsel.dpwn.net/abholportal/gw/lp/schema/1.0/var3bl">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<var:BookLabelRequest portalId ="OnlineRetoure" deliveryName="Deutschland_Var3"
shipmentReference="notreturnedonlabel" customerReference="CustomerRef1234567890"
labelFormat="PDF" senderName1="Markus" senderName2="Beck"
senderCareOfName="actualnotinuse" senderContactPhone=""
senderStreet="Buschmühlenstraße" senderStreetNumber="40"
senderBoxNumber="" senderPostalCode="58093" senderCity="Hagen"/>
</soapenv:Body>
The wsdl file isn't mine so i can't edit it. Is there any other way to import this. I tried to create a data contract from the xsd using svcutil but i got the error message:
The input read from "https://amsel.dpwn.net/abholportal/gw/lp/schema/1.0/
var3bl.xsd" is inconsistent with other options
I tried passing the username and password to the proxy as well
RpPartnerType test = new RpPartnerTypeClient();
((RpPartnerTypeClient)test).ClientCredentials.UserName.UserName = "username";
((RpPartnerTypeClient)test).ClientCredentials.UserName.Password = "password";
dhlService.BookLabelResponse response = test.BookLabel(new dhlService.BookLabelRequest());
but got the error: Authentication failed: No username given
The binding security is:
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
Your WSDL is importing XSD with serialization info from other path:
https://amsel.dpwn.net/abholportal/gw/lp/schema/1.0/var3bl.xsd
but location in WSDL should specify full this path.
If you need to use UserNameToken profile you must first specify binding for your your client:
<bindings>
<basicHttpBinding>
<binding name="secured">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
And use this binding in your client endpoint:
<client>
<endpoint address="..." name="..." contract="..." binding="basicHttpBining"
bindingConfiguration="secured" />
</client>
Once you have your client configured you need to create proxy of the service ans set credentials"
proxy.ClientCredentials.UserName.UserName = ...;
proxy.ClientCredentials.UserName.Password = ...;
Create a HttpWebRequest according to Mike Hadlow's blog and sent that.
http://mikehadlow.blogspot.com/2006/05/making-raw-web-service-calls-with.html
May be better ways to achieve this but it worked.
Related
I need to connect to a remote SOAP service. For several days that I have been trying all the many configurations without success.
Connection is OK when using SoapUI.
Connection is KO when calling from my .net application.
Errors : The username is not provided. Specify username in ClientCredentials.
My application and the remote application are both running on IIS.
Here is the remote binding :
<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 works with the following configuration :
Authorization : Basic
Username: DOMAIN\username
Password : pwd
Pre-Emptive authentication
When I check the raw request from SoapUI, it's sending this :
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>
Everything above is working.
Now, what am I doing in my .net 4.6.1 application ? I am trying to send the same request that SoapUI is sending.
Here is how I do : web.config with endpoints, bindings and behaviour extension. The extended behaviour implements an EndPoint Behaviour that calls an Inspector (from ApplyClientBehavior) from which I use the BeforeSendRequest to add two things :
a SOAP header <wsse:Security />
a Authorization: Basic http header.
Here are the details of the implementation.
<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>
Down the chain of c# class, we find this code :
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;
}
The resulting SOAP envelope at the remote server side* is this :
<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>
I have followed many blog and documentation to make it until this point and I am still stuck :D
*To get the message to hit the server I need to use the default binding configuration WsHttpBinding_Default. When I am using the WsHttpBinding_Authentication the request does not seem to be processed by the remote server.
I tried to play with the bindings configuration but no luck so far.
What is wrong with my current configuration ?
With WsHttpBinding_Authentication I got the said error (edited : wrong error copied pasted)The username is not provided. Specify username in ClientCredentials. An error occurred when verifying security for the message.
With WsHttpBinding_Default, the remote server processed a bit of the request and reject it with the following error :
the error :
<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>
Sorry for the wall of text, I hope everything needed to get a clear view of my issue is here.
Many thanks for having read so far :)
Edit : as you can see I also tried to put the header directly in the xml endpoint but no success so far.
Edit : The calling binding was wrong, it is now :
<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>
With that new binding my error is now :
{"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."]}
I find no content about this error, what is happening :/
Edit : Solved the error by re-adding establishSecurityContext="false" in the binding.
Edit : To add credentials I am using that post answers : Set WCF ClientCredentials in App.config
It seems to work, I am making progress toward an old error : An error occurred when verifying security for the message.
To add a username and password to the Service, you would need to do the following when setting up the service
// 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;
This is when you are using standard WS username and password, I have added an answer to my own question after experiencing the exact same thing as well, The link is WCF Service inside aspnet webforms throwing 302
You can read up more on from Microsoft
Solved !!!
So much frustration, but writing a SO post and keeping it updated helped a lot.
I go celebrated and I will come back to detail the solution.
In short, use the implementation from the link I add in my edits, not my previous way.
I am new to WCF/APIs and know little to nothing about security. Let me know if I need to provide any more information.
I am trying to connect to a service using
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ISalesOrderService">
<security mode="Transport" >
<transport clientCredentialType="Basic"></transport>
</security>
</binding>
<binding name="BasicHttpBinding_IDocumentationService">
<security mode="TransportCredentialOnly" >
<transport clientCredentialType="Basic"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="address1"
name="BasicHttpBinding_ISalesOrderService"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ISalesOrderService"
contract="SoCalls.ISalesOrderService" />
<endpoint address="address2"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IDocumentationService"
contract="DocCalls.IDocumentationService"
name="BasicHttpBinding_IDocumentationService" />
</client>
</system.serviceModel>
With this, I get this error:
'System.ServiceModel.Security.MessageSecurityException'
The HTTP request is unauthorized with client authentication scheme 'Basic'.
The authentication header received from the server was 'Basic Realm'.
Edit
I followed the instructions suggested in the link provided in the comments, still is giving me this error. I updated my code but I think I am still a bit confused on whether to use HTTP/HTTPS due to lack of knowledge of either service.
Here is how I instantiate my service:
private static SoCalls.SalesOrderServiceClient CreateSalesOrderServiceClient()
{
BasicHttpBinding myBinding = new BasicHttpBinding();
myBinding.MaxReceivedMessageSize = 10000 * 2;
myBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
EndpointAddress ea = new EndpointAddress("address1");
SoCalls.SalesOrderServiceClient client = new SoCalls.SalesOrderServiceClient();
client.ClientCredentials.UserName.UserName = ("username");
client.ClientCredentials.UserName.Password = ("password");
return client;
}
As it seems, I did not have access to the API with this specific database which is what was giving me my error. I tried sending other credentials for a separate database from the same server and it worked perfectly fine. Purchased the license required and the code works as expected.
We're trying to get data from an external web service using VB.Net.
We added a Service Reference, provinding the correct WSDL.
Our code for getting data is:
Dim MyClient As New ExtConn.GetConnectorSoapClient()
MyClient.ClientCredentials.UserName.UserName = "AOL\12345.abcde"
MyClient.ClientCredentials.UserName.Password = "pass123"
Dim MyReq As New ExtConn.GetDataRequest
Dim MyResponse As New ExtConn.GetDataResponse
Dim MyCred As New System.ServiceModel.Description.ClientCredentials()
Dim MyReqBody As New ExtConn.GetDataRequestBody("Environment123", "AOL\12345.abcde", "pass123", "12345.abcde", "GetData", "")
MyReq.Body = MyReqBody
MyResponse = MyClient.ExtConn_GetConnectorSoap_GetData(MyReq)
MsgBox(MyResponse.Body.GetDataResult)
Our app.config is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpsBinding>
<binding name="GetConnectorSoap">
<security mode="Transport" >
<transport clientCredentialType="Ntlm" realm="" />
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpsBinding>
</bindings>
<client>
<endpoint address="https://ota.externalservice.nl/ourservices/getconnector.asmx"
binding="basicHttpsBinding" bindingConfiguration="GetConnectorSoap"
contract="ExtConn.GetConnectorSoap" name="GetConnectorSoap" />
</client>
</system.serviceModel>
</configuration>
The respons is:
The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'Negotiate,Kerberos,NTLM'.
My questions are: what are we doing wrong? If NTLM is accepted as authentication mode, why do we get this error?
You could try to add it as an web reference (Add service reference > Advanced.. > Add Web reference)
GetConnector connector = new GetConnector();
connector.Credentials = new NetworkCredential("username", "password", "domain");
string response = connector.GetData();
I'm trying to use WCF to consume a web service provided by a third-party's Oracle Application Server. I pass a username and password in a UsernameToken as part of the request and as part of the response the web service returns a standard security tag in the header which includes a digest and signature.
With my current setup, I successfully send a request to the server and the web service sends the expected response data back. However, when parsing the response WCF throws a MessageSecurityException, with an InnerException.Message of "Supporting token signatures not expected."
My guess is that WCF wants me to configure it to handle the signature and verify it. I have a certificate from the third party that hosts the web service that I should be able to use to verify the signature, although I'm not sure if I'll need it.
Here's a sample header from a response that makes WCF throw the exception:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<dsig:Signature xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<dsig:SignedInfo>
<dsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<dsig:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<dsig:Reference URI="#_51IUwNWRVvPOcz12pZHLNQ22">
<dsig:Transforms>
<dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<dsig:DigestValue>
[DigestValue here]
</dsig:DigestValue>
</dsig:Reference>
<dsig:Reference URI="#_dI5j0EqxrVsj0e62J6vd6w22">
<dsig:Transforms>
<dsig:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</dsig:Transforms>
<dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<dsig:DigestValue>
[DigestValue here]
</dsig:DigestValue>
</dsig:Reference>
</dsig:SignedInfo>
<dsig:SignatureValue>
[Signature Value Here]
</dsig:SignatureValue>
<dsig:KeyInfo>
<wsse:SecurityTokenReference xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Reference URI="#BST-9nKWbrE4LRv6maqstrGuUQ22" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/>
</wsse:SecurityTokenReference>
</dsig:KeyInfo>
</dsig:Signature>
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="BST-9nKWbrE4LRv6maqstrGuUQ22" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
[Security Token Here]
</wsse:BinarySecurityToken>
<wsu:Timestamp wsu:Id="_dI5j0EqxrVsj0e62J6vd6w22" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsu:Created>2010-05-26T18:46:30Z</wsu:Created>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body wsu:Id="_51IUwNWRVvPOcz12pZHLNQ22" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
[Body content here]
</soap:Body>
</soap:Envelope>
My binding configuration looks like:
<basicHttpBinding>
<binding name="myBinding" 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="Text" 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>
I think that basically what I have to do is configure WCF to use UserName client credentials in the request and Certificate client credentials in the response. I don't know how to do this though.
I'm new at WCF, so I'm sorry if this is a bit of a dumb question. I've been trying to Google solutions, but there seem to be so many different ways to configure WCF that I'm getting overwhelmed.
Thanks in advance!
For anyone who is interested, I was able to work around this problem by creating a CustomMessageEncoder (with help from this MSDN article) to intercept the response message before WCF was able to handle it. There, I removed the BinarySecurityToken and Signature elements from the response before handing it off to WCF. I used the following method to remove the offending elements from the stream:
private Stream RemoveSignatures(Stream stream)
{
XmlDocument doc = new XmlDocument();
doc.Load(stream);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
nsMgr.AddNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#");
nsMgr.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
XmlNode signatureNode = doc.SelectSingleNode("/soap:Envelope/soap:Header/wsse:Security/dsig:Signature", nsMgr);
XmlNode binarySecurityTokenNode = doc.SelectSingleNode("/soap:Envelope/soap:Header/wsse:Security/wsse:BinarySecurityToken", nsMgr);
XmlNode headerNode = doc.SelectSingleNode("/soap:Envelope/soap:Header/wsse:Security", nsMgr);
headerNode.RemoveChild(signatureNode);
headerNode.RemoveChild(binarySecurityTokenNode);
return new MemoryStream(new UTF8Encoding().GetBytes(doc.OuterXml));
}
Obviously this is not the greatest solution. It's very 'hacky'. But it works and if need be I can continue using it because the message security is already being taken care of by HTTPS transport.
If anyone can tell me a better way to solve this, I'm open.
Seems like service isn't waiting for credentials at a place you providing them. Try to specify username and password for transport level instead.
I've created one WCF service and deployed it on Server. When I browse this service it gives me positive response with ?wsdl URL. Now I'm trying to test the service through WCF Test client. It shows proper metadata. But when I try to invoke any of the method from the service it shows me an exception... here are the erro details with stack trace..
The HTTP request is unauthorized with
client authentication scheme
'Anonymous'. The authentication header
received from the server was
'Negotiate,NTLM'.
Server stack trace:
at
System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest
request, HttpWebResponse response,
WebException responseException,
HttpChannelFactory factory)
The HTTP request is unauthorized with client
authentication scheme 'Anonymous'. The
authentication header received from
the server was 'Negotiate,NTLM'.
Server stack trace:
at
System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest
request, HttpWebResponse response,
WebException responseException,
HttpChannelFactory factory)
Client Bindings:
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IServiceMagicService" 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="None">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
Server Bindings:
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_SEOService" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="true" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="999524288" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="900000" maxArrayLength="900000" maxBytesPerRead="900000" maxNameTableCharCount="900000" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />
</security>
</binding>
<binding name="WSHttpServiceMagicBinding" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="true" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="999524288" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="900000" maxArrayLength="900000" maxBytesPerRead="900000" maxNameTableCharCount="900000"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
Client's Client Section:
<client>
<endpoint address="http://hydwebd02.solutions.com/GeoService.Saveology.com/ServiceMagicService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServiceMagicService"
contract="IServiceMagicService" name="WSHttpBinding_IServiceMagicService" />
</client>
Server's Services Section:
<services>
<service behaviorConfiguration="GeoService.Saveology.com.CityStateServiceProviderBehavior"
name="GeoService.Saveology.com.CityStateServiceProvider">
<endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_SEOService"
contract="SEO.Common.ServiceContract.ICityStateService" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="GeoService.Saveology.com.ServiceMagicServiceProviderBehavior"
name="GeoService.Saveology.com.ServiceMagicServiceProvider">
<endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpServiceMagicBinding"
contract="SEO.Common.ServiceContract.IServiceMagicService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
</service>
</services>
I didn't have control over the security configuration for the service I was calling into, but got the same error. I was able to fix my client as follows.
In the config, set up the security mode:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
In the code, set the proxy class to allow impersonation (I added a reference to a service called customer):
Customer_PortClient proxy = new Customer_PortClient();
proxy.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
I have a similar issue, have you tried:
proxy.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
Another possible solution to this error that I found. Might not have answered OP's exact question but may help others who stumble across this error message.
I was creating my Client in code using WebHttpBinding, in order to replicate the following line:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
I had to do:
var binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Windows;
as well as setting proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
I had a similar problem and tried everything suggested above. Then I tried changing the clientCreditialType to Basic and everything worked fine.
<basicHttpBinding>
<binding name="BINDINGNAMEGOESHERE" >
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"></transport>
</security>
</binding>
</basicHttpBinding>
I see this isn't answered yet, this is an exact quote from here:
WSHttpBinding will try and perform an internal negotiate at the SSP layer. In order for this to be successful, you will need to allow anonymous in IIS for the VDir. WCF will then by default perfrom an SPNEGO for window credentials. Allowing anonymous at IIS layer is not allowing anyone in, it is deferring to the WCF stack.
I found this via: http://fczaja.blogspot.com/2009/10/http-request-is-unauthorized-with.html
After googling: http://www.google.tt/#hl=en&source=hp&q=+The+HTTP+request+is+unauthorized+with+client+authentication+scheme+%27Anonymous
Here's what I had to do to get this working. This means:
Custom UserNamePasswordValidator (no need for a Windows account, SQLServer or ActiveDirectory -- your UserNamePasswordValidator could have username & password hardcoded, or read it from a text file, MySQL or whatever).
https
IIS7
.net 4.0
My site is managed through DotNetPanel. It has 3 security options for virtual directories:
Allow Anonymous Access
Enable Basic Authentication
Enable Integrated Windows Authentication
Only "Allow Anonymous Access" is needed (although, that, by itself wasn't enough).
Setting
proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
Didn't make a difference in my case.
However, using this binding worked:
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Windows" />
<message clientCredentialType="UserName" />
</security>
I had the same error today, after deploying our service calling an external service to the staging environment in azure. Local the service called the external service without errors, but after deployment it didn't.
In the end it turned out to be that the external service has a IP validation. The new environment in Azure has another IP and it was rejected.
So if you ever get this error calling external services
It might be an IP restriction.
I had this error too , and finally this codes worked for me in dot net core 3.1
first install svcutil in command prompt : dotnet tool install --global dotnet-svcutil
Then close command prompt and open it again.
Then create the Reference.cs in command prompt :
dotnet-svcutil http://YourService.com/SayHello.svc
(It needs an enter key and UserName and Password)
Add a folder named Connected Services to project root.
Copy Reference.cs file to Connected Services folder.
Add these 4 lines to Reference.cs after lines where creating BasicHttpBinding and setting MaxBufferSize :
result.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
result.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
result.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
Use this service in your Controller :
public async Task<string> Get()
{
try
{
var client = new EstelamClient();
client.ClientCredentials.UserName.UserName = "YourUserName";
client.ClientCredentials.UserName.Password = "YourPassword";
var res = await client.EmployeeCheckAsync("service parameters");
return res.ToString();
}
catch (Exception ex)
{
return ex.Message + " ************ stack : " + ex.StackTrace;
}
}
Do not forget install these packages in csproj :
<PackageReference Include="System.ServiceModel.Duplex" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.Http" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.Security" Version="4.6.*" />
Just got this problem on a development machine (production works just fine). I modify my config in IIS to allow anonymous access and put my name and password as credential.
Not the best way I am sure but it works for testing purposes.
Try providing username and password in your client like below
client.ClientCredentials.UserName.UserName = #"Domain\username";
client.ClientCredentials.UserName.Password = "password";