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
Related
I'm trying to call soap service in script task but getting this following error. I've added a serviceReference through wsdl url. I don't have idea about what this error is referring to. However i'm able to get the data in SOAPUI
"The header 'ReliableMessaging' from the namespace 'http://sap.com/xi/XI/Message/30' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding."
below is the code i'm using
EndpointAddress endPointAddress = new EndpointAddress("https://sapnxcci.intel.com:8220/XISOAPAdapter/MessageServlet?senderParty=&senderService=MC4510&receiverParty=&receiverService=&interface=Segments&interfaceNamespace=http://intel.com/xi/Intel-MDM/Project/Segment");
SegmentsClient client = new SegmentsClient(BindingUtility.GetInitiativesBinding(), endPointAddress);
client.ClientCredentials.UserName.UserName = "sys_idwcons";
client.ClientCredentials.UserName.Password = "abdc";
SegmentResponse results = client.ListSegments(new SegmentRequest() { SegmentName = "" });
In GetInitiativesBinding contains the following.
public static BasicHttpBinding GetInitiativesBinding()
{
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
binding.MaxReceivedMessageSize = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.ReceiveTimeout = TimeSpan.FromMinutes(5);
binding.SendTimeout = TimeSpan.FromMinutes(5);
return binding;
}
and my App.Config file looks like this
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="SegmentsBinding" />
<binding name="SegmentsBinding1">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://sapnxcci.intel.com:8420/XISOAPAdapter/MessageServlet?senderParty=&senderService=MC4510&receiverParty=&receiverService=&interface=Segments&interfaceNamespace=http%3A%2F%2Fintel.com%2Fxi%2FIntel-MDM%2FProject%2FSegment"
binding="basicHttpBinding" bindingConfiguration="SegmentsBinding"
contract="ServiceReference1.Segments" name="HTTP_Port" />
<endpoint address="https://sapnxcci.intel.com:8220/XISOAPAdapter/MessageServlet?senderParty=&senderService=MC4510&receiverParty=&receiverService=&interface=Segments&interfaceNamespace=http%3A%2F%2Fintel.com%2Fxi%2FIntel-MDM%2FProject%2FSegment"
binding="basicHttpBinding" bindingConfiguration="SegmentsBinding1"
contract="ServiceReference1.Segments" name="HTTPS_Port" />
</client>
</system.serviceModel>
</configuration>
I think it's because the return message from PI contains the tags.
tags are only useful when you have a PI - PI connection.
Reference: https://archive.sap.com/discussions/thread/1839924
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"));
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!
WCF Service WebConfig(partial).
<services>
<service name="Bricks99.LicensingServer.LicensingService"
behaviorConfiguration="Bricks99ServiceBehavior">
<!-- use base address specified above, provide one endpoint -->
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="Bricks99Binding"
contract="Bricks99.LicensingServer.ILicensingService" />
<!--<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />-->
</service>
</services>
<basicHttpBinding>
<binding name="Bricks99Binding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic" />
</security>
</binding>
</basicHttpBinding>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Bricks99.LicensingServer.CCustomValidatorClass, Bricks99.LicensingServer"/>
</serviceCredentials>
Client is ASP.NET 2.0
LicensingService service = new LicensingService();
//Authentication
CredentialCache credCache = new CredentialCache();
credCache.Add(new Uri(service.Url), "Basic", new NetworkCredential("Test", "1234567"));
service.Credentials = credCache;
service.PreAuthenticate = true;
service.UseDefaultCredentials = false;
result = service.VerifyLicenseKey(licenseKey, string.Empty);
The result is always The request failed with HTTP status 401: Unauthorized. I have also turned off Anonymous Access on the folder. Its still not working.
Any ideas on how to set the credentials correctly?
EDIT: Seems like the overridden method
public override void Validate(string userName, string password)
{
try
{
if(userName != "Test" || password != "1234567")
{
throw new FaultException("The provided credentials are invalid.");
}
}
catch(FaultException ex)
{
LicensingData.Operations.LogError(ex);
}
}
is never getting hit.
Well after hours of research I found out that the hosting provider did not allow basic authentication by default. For custom authentication to work it is necessary that basic authentication be enabled in IIS.