Has anyone got any experience with working with the OpenEMM web services?
When ever I connect to the services I get the following error:
com.sun.xml.wss.XWSSecurityException: Receiver Requirement for Digested Password has not been met; nested exception is com.sun.xml.wss.XWSSecurityException: com.sun.xml.wss.XWSSecurityException: Receiver Requirement for Digested Password has not been met
Here is my web.config file:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="openemmSoap11">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Digest" />
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://newsletter.********.co.uk/openemm-ws2/" binding="basicHttpBinding"
bindingConfiguration="openemmSoap11" contract="emmservice.openemm"
name="openemmSoap11" />
</client>
</system.serviceModel>
(I had great fun installing an ssl certificate on apache)
Here is my implementation:
var param = new[]
{
new MapItem {key = "email", value = "*******************"},
new MapItem {key = "mailtype", value = "0"}, new MapItem {key = "gender", value = "0"}
};
var service = new AddSubscriberRequest
{
parameters = param,
overwrite = false,
doubleCheck = true,
keyColumn = "email"
};
var request = new openemmClient();
request.ClientCredentials.UserName.UserName = "***********";
request.ClientCredentials.UserName.Password = "********";
request.Open();
request.AddSubscriber(service);
request.Close();
Any ideas where I could be going wrong?
OpenEMM Web services 2.0 require creation of creation of nonce, timestamp and password encryption. Official documentation is HERE
You have no nonce nor password encryption first try documentation example
if you need help with implementation - ask!
Related
I have to make a client for a WSDL. But I keep getting a
"No Security header in message but required by policy."
Here is my code
USImportoerService service = new USImportoerService();
X509Certificate2 cert = new X509Certificate2(certPath, PASSWORD, X509KeyStorageFlags.MachineKeySet);
service.ClientCertificates.Add(cert);
var result = ser.getUSKoeretoej();
And heres the App.config
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="USImportoerService_Port">
<security authenticationMode="CertificateOverTransport" securityHeaderLayout="LaxTimestampLast" includeTimestamp="true"
enableUnsecuredResponse="true">
</security>
<textMessageEncoding messageVersion="Soap11" />
<httpsTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="HTTPS TO WSDL"
binding="customBinding" bindingConfiguration="USImportoerService_Port"
contract="ServiceReferenceUSImportoer.USImportoerServiceType"
name="Port1" />
</client>
</system.serviceModel>
Hope someone can help
Use HttpClient to call SOAP Service
USImportoerService service = new USImportoerService();
X509Certificate2 cert = new X509Certificate2(certPath, PASSWORD, X509KeyStorageFlags.MachineKeySet);
HttpClientHandler handler = new HttpClientHandler();
handler.ClientCertificates.Add(cert);
HttpClient client = new HttpClient(handler);
// Call service using httpClient
//var result = ser.getUSKoeretoej();
How to call SOAP Service using httpClient
Client to send SOAP request and receive response
I am trying to consume a SOAP service and am having authentication problems and think I may be missing something useful. I think the issue may be in that I'm passing in the header more than just the credentials (which I believe is what I have to do, but think it just makes the situation more unique). Below is my config file and the code I'm using to authenticate.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MemberSoap">
<security mode="Transport" />
</binding>
<binding name="MemberSoap1" />
<binding name="TransactionSoap">
<security mode="Transport" />
</binding>
<binding name="TransactionSoap1" />
<binding name="CertificateSoap" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647">
<readerQuotas maxDepth="32" maxArrayLength="2147483647" maxStringContentLength="2147483647"/>
<security mode="Transport" />
</binding>
<binding name="CertificateSoap1" />
<binding name="MembershipSoap">
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="None" realm="" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
<binding name="ContentSoap">
<security mode="Transport" />
</binding>
<binding name="ContentSoap1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://membership/member.asmx"
binding="basicHttpBinding" bindingConfiguration="MemberSoap"
contract="Member.MembershipWsMemberSoap" name="Ovs.Membership.Ws.MemberSoap" />
<endpoint address="https://membership/transaction.asmx"
binding="basicHttpBinding" bindingConfiguration="TransactionSoap"
contract="MembershipWsTransactionSoap" name="TransactionSoap" />
<endpoint address="https://membership/certificate.asmx"
binding="basicHttpBinding" bindingConfiguration="CertificateSoap"
contract="MembershipWsCertificateSoap" name="CertificateSoap" />
<endpoint address="https://ngmembership/Membership.svc"
binding="basicHttpBinding" bindingConfiguration="MembershipSoap"
contract="Membership.IMembership" name="MembershipSoap" />
<endpoint address="https://membership/content.asmx"
binding="basicHttpBinding" bindingConfiguration="ContentSoap"
contract="Content.MembershipWsContentSoap" name="ContentSoap" />
</client>
</system.serviceModel>
<appSettings>
<add key="UsernameAuth" value="user" />
<add key="PasswordAuth" value="pass" />
</appSettings>
</configuration>
I left out the base url for security purposes as well as the full namespaces, but the one I'm mainly concerned about is the name="MembershipSoap" service. Here is my first attempt at the code I'm using to authenticate.
public Transaction[] GetAllBookingInfo(string memberId, string partnerId)
{
AllBookingsByMemberIdRS response;
using (var client = new MembershipClient())
using (new OperationContextScope(client.InnerChannel))
{
// add the basic auth header
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name]
= GetBasicAuthHeader("user", "pass");
var request = new AllBookingsByMemberIdRQ
{
MemberId = memberId,
PartnerId = partnerId
};
response = AuthenticateServiceUser.membershipSession.GetAllBookingsByMemberId(request);
}
var trans = response.Transactions;
return trans;
}
protected HttpRequestMessageProperty GetBasicAuthHeader(string userName, string password)
{
// get the basic auth header
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(userName + ":" + password));
return httpRequestProperty;
}
At this I get an error saying that there were 'Invalid web service credentials used'. So after reading I switched the first method to this.
public Transaction[] GetAllBookingInfo(string memberId, string partnerId)
{
AllBookingsByMemberIdRS response;
var client = new MembershipClient();
client.ClientCredentials.UserName.UserName = "user";
client.ClientCredentials.UserName.Password = "pass";
using (new OperationContextScope(client.InnerChannel))
{
var request = new AllBookingsByMemberIdRQ
{
MemberId = memberId,
PartnerId = partnerId
};
response = AuthenticateServiceUser.membershipSession.GetAllBookingsByMemberId(request);
}
var trans = response.Transactions;
return trans;
}
And now I'm getting a 'The username is not provided. Specify username in ClientCredentials' error. So now I feel like I'm moving further away to where I was before. Maybe someone can shed some light on this? Thanks in advance!
I figured it out. I stupidly reference another client in my code - one without credentials. It's always those simple mistakes that get overlooked.
public Transaction[] GetAllBookingInfo(string memberId, string partnerId)
{
AllBookingsByMemberIdRS response;
using (var client = new MembershipClient())
using (new OperationContextScope(client.InnerChannel))
{
// add the basic auth header
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name]
= GetBasicAuthHeader("user", "pass");
var request = new AllBookingsByMemberIdRQ
{
MemberId = memberId,
PartnerId = partnerId
};
response = client.GetAllBookingsByMemberId(request);
}
return response.Transactions;
}
I'm trying to move the endpoint and wshttpbinding configuration to a c# file so I can change the endpoint address at runtime (select from dropdown, process etc). However after creating a WsHttpBinding object, EndpointAddress object and passing them to my client. It will throw the following exception:
System.ServiceModel.FaultException: The caller was not authenticated
by the service
This is the same exception I get if the user credentials are incorrect. However they haven't changed from using the Web.config file to creating these config options programmatically.
Web.config (works):
<binding name="myService" maxReceivedMessageSize="2147483647">
<readerQuotas
maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
</binding>
<client>
<endpoint
address="https://address/myservice.svc"
binding="wsHttpBinding"
bindingConfiguration="myService"
contract="MyService.IMyService"
name="myService"
/>
</client>
MyService service = new MyService();
service.username = "user";
service.password = "pass";
//Success
Programmatically (does not work):
WSHttpBinding wsHttp = new WSHttpBinding();
wsHttp.MaxReceivedMessageSize = 2147483647;
wsHttp.ReaderQuotas.MaxDepth = 2147483647;
wsHttp.ReaderQuotas.MaxStringContentLength = 2147483647;
wsHttp.ReaderQuotas.MaxArrayLength = 2147483647;
wsHttp.ReaderQuotas.MaxBytesPerRead = 2147483647;
wsHttp.ReaderQuotas.MaxNameTableCharCount = 2147483647;
wsHttp.Security.Mode = SecurityMode.TransportWithMessageCredential;
wsHttp.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
wsHttp.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
wsHttp.Security.Message.EstablishSecurityContext = false;
EndpointAddress endpoint = new EndpointAddress("https://address/myservice.svc");
MyService service = new MyService(wsHttp, endpoint);
service.username = "user";
service.password = "pass";
//System.ServiceModel.FaultException: The caller was not authenticated by the service
I've tried following tutorials / looking at answers but I can't figure it out.
My solution
Keep the binding the same.
Change the endpoint so there is no address
<client>
<endpoint
binding="wsHttpBinding" bindingConfiguration="myService"
contract="MyService.IMyService" name="myService" />
</client>
Change endpoint at run time by changing the Uri object and pass the endpoint name your service as the first argument
Uri uri = new Uri("https://address/myservice.svc");
var address = new EndpointAddress(uri);
service= new MyService("myService", address);
service.username = "user";
service.password = "pass";
You can remove EVERYTHING in your app.config - so there is no binding or interface info.
Your runtime code is this:
//create an endpoint address
var address = new EndpointAddress("http://localhost:51353/EmployeeService.svc");
//create a WSHttpBinding
WSHttpBinding binding = new WSHttpBinding();
//create a channel factory from the Interface with binding and address
var channelFactory = new ChannelFactory<IEmployeeService>(binding, address);
//create a channel
IEmployeeService channel = channelFactory.CreateChannel();
//Call the service method on the channel
DataSet dataSet = channel.SelectEmployees();
Just for reference, here is my app.config:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
/************ You can dumb this down to this: ********************************/
var factory = new ChannelFactory<IEmployeeService>(new WSHttpBinding());
var channel = factory.CreateChannel(new EndpointAddress("http://localhost:51353/EmployeeService.svc"));
Our php webservice provides webfunctions for clients. We have used the following code to do the authentication.
$client = new SoapClient("some.wsdl",
array('login' => "some_name",
'password' => "some_password"
));
The client has been build in C# and we have been able to set up a connection without authentication but we haven't been able to apply the authentication.
what kind of properties should we provide for the clients?
I have tried this configuration in combination with the username credentials.
<basicHttpBinding>
<binding name="webserviceControllerBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
client.ClientCredentials .UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
What kind of security is our php service using?
How can we set-up a reliable connection with authentication but without using certificates or https.
It seems I have to put the authentication in the soapheader.
http://ericphan.info/blog/2010/6/3/adding-custom-http-header-to-all-wcf-requests.html
http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/c96c8f6e-0711-4ba1-a97c-008f44610f0e/
http://www.codeproject.com/KB/webservices/SOAPHeaderAuthentication.aspx
Going by some of the examples on the internet.
But i haven't found a example for my case jet.
MessageHeader header= MessageHeader.CreateHeader("My-CustomHeader","http://myurl","Custom Header.");
using (phptoebiTestclient.ServiceReference1.webserviceControllerPortTypeClient client = new phptoebiTestclient.ServiceReference1.webserviceControllerPortTypeClient())
{
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageHeaders.Add(header);
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("username:password");
httpRequestProperty.Headers.Add("Authorization: Basic "+ System.Convert.ToBase64String(toEncodeAsBytes));
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
string str = client.getVacanciesReference("");
}
}
Code above has solved my problem (I used these URLs for reference)
http://caught-in-a-web.blogspot.com/2008/04/how-to-add-custom-http-header-in-wcf.html
http://en.wikipedia.org/wiki/Basic_access_authentication
Try
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
UPDATED: It should be TransportWithMessageCredential mode
When I am trying to read a meta data I got this error any Idea here is My code
WSHttpBinding binding = new WSHttpBinding(SecurityMode.None);
binding.MaxReceivedMessageSize = Int32.MaxValue; // DPNote: This may actually be too big. see how it performs.
binding.ReaderQuotas.MaxNameTableCharCount = 99999999;
MetadataExchangeClientMode exchangeMode = MetadataExchangeClientMode.HttpGet; // Default to a HttpGET
metaClient = new MetadataExchangeClient(binding);
metaClient.MaximumResolvedReferences = 10 * 100; //DPNote: Some arbitrary number. Default is 10, so this is bigger.
if (address.Scheme == "http")
exchangeMode = MetadataExchangeClientMode.HttpGet;
else if (address.Scheme == "https")
exchangeMode = MetadataExchangeClientMode.HttpGet;
else
exchangeMode = MetadataExchangeClientMode.MetadataExchange;
MetadataSet metadata = metaClient.GetMetadata(address, exchangeMode);
MetadataImporter importer = new WsdlImporter(metadata);
and this is the line which throws the error
MetadataSet metadata = metaClient.GetMetadata(address, exchangeMode);
If you are doing 'Update Reference' through visual studio, add these lines to devenv.exe.config
<system.serviceModel>
<client>
<endpoint binding="netTcpBinding" bindingConfiguration="GenericBinding" contract="IMetadataExchange" name="net.tcp" />
</client>
<bindings>
<netTcpBinding>
<binding name="GenericBinding"
maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
This is a error in Microsoft code,Http-Get not support Reader Quotas, so we can do this
var smAsm = AppDomain.CurrentDomain.GetAssemblies().First(a => a.FullName.StartsWith("System.ServiceModel,"));
var defTy = smAsm.GetType("System.ServiceModel.Channels.EncoderDefaults");
var rq = (System.Xml.XmlDictionaryReaderQuotas)defTy.GetField("ReaderQuotas", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
rq.MaxArrayLength = int.MaxValue;
rq.MaxDepth = int.MaxValue;
rq.MaxNameTableCharCount = int.MaxValue;
rq.MaxStringContentLength = int.MaxValue;
Have you tried incrementing any of these other values inside of binding.ReaderQuotas beyond their default values:
maxDepth, maxStringContentLength, maxArrayLength, maxBytesPerRead?
It could also be the maxBufferPoolSize of the binding
The problem seems to be fixed in .NET 4.0. According to Reflector, MetadataExchangeClient now reads the quotas from the supplied binding, and if it doesn't have those, it falls back to EncoderDefaults. Previously, I think it only used EncoderDefaults, that's why #BreakHead's solution seems to be the only solution (to change EncoderDefaults with reflection).