Delphi - problem with consuming SOAP with x509 certificate authentication - web-services

We should use a SOAP web service that is written in c# with Delphi 10.4.2 OR 11.0
related WSDL file successfully imported and the Delphi related code is generated no problem.
the problem is we should use x509 certificate as authentication method but webservice is on HTTP not HTTPS
first we install certificate on local machine and use certificate in HTTPRIO.HTTPWebNode.ClientCertificate by its serial number and call a method with no success. server just close the connection with 0 length reply.
after that we receive a simple working code in c#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GeneralUtilityService.GeneralUtilityServiceSR;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel.Security;
namespace GeneralUtilityServiceProject
{
class Program
{
static void Main(string[] args)
{
GeneralUtilityService client = new GeneralUtilityService();
client.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2("d:/test/test.cer");
client.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2("d:/test/test.p12", "123456", X509KeyStorageFlags.PersistKeySet);
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
var result = client.getLastStatusOfEmployees("username","password");
var nn = result[0].lastStatusCheck;
Console.WriteLine(nn);
Console.ReadKey();
}
}
}
but i don't know its equivalent in Delphi to handle certificate like this
any helps would be appreciated
best regards

Related

Add certificate to both server and client using WCF and gSOAP

I have WCF web service that need to be secured using SSL/TLS protocol. In the other hand I have C++ client that consume WCF web service using gSOAP library. Already only server needs to have certificate. Now I have tasked to enforce client to have certificate. My earlier implementation for client is like this:
soap_ssl_init();
int soapResult = soap_ssl_client_context(soapPtr, SOAP_SSL_NO_AUTHENTICATION, "client.pem", NULL,
NULL, "cacert.pem", NULL);
if (soapResult)
{
soap_print_fault(soapPtr, stderr);
throw new ClientLogException("Can not use ssl for comminucations!");
}
else
{
}
struct soap mySoap = *soapPtr;
WSHttpBinding_USCOREILogServicesProxy proxy(mySoap);
input.request = &request;
int callCode = proxy.CallWebService(WEB_SERVICE_ADDRESS, NULL, &input, response);
if (callCode != 0)
{
cout << "Web service call code: " + callCode << endl;
throw new ClientLogException("Error in calling web service with call code: " + callCode);
}
which I does it from gSOAP documents. It works fine with only server required to have certificate. I viewed communication using WireShark and connection was completely encrypted.
Now for enforcing client to use certificate, I am going to use Nine simple steps to enable X.509 certificates on WCF article. But the article uses a C# WCF client. I must implement client configuration in my gSOAP C++ client. I can add client certificate in above code when calling soap_ssl_client_context and in third parameter.
I have 2 problem here:
1- I don't know is it possible calling web service that both client and server have certificates and communication be secured when server uses WCF and client uses gSOAP.
2- In the CodeProject article it seems that web service call is using http and I am wonder there is no encryption in communication.
In the end if anyone has better solution, or recommend other tools will be welcome.
HTTPS works out of the box with gsoap if you compile with -DWITH_OPENSSL and link against the OpenSSL libs. The out-of-the-box default settings will encrypt messages with https://, but this does not enforce authentication because you need to register the server certificates first with soap_ssl_client_context() as you point out.
To authenticate both server and client, the gsoap manual suggests the following:
int soapResult = soap_ssl_client_context(soapPtr,
SOAP_SSL_DEFAULT, // requires server to authenticate
"client.pem", // client cert (+public key) to authenticate to server
"password", // you need this when client.pem is encrypted
NULL, // capath to certs, when used
"cacert.pem", // should contain the server cert
NULL);
Also, you may need to convert PEM to CER (or the other way) for windows.

Unable to communicate with web service using Apache Axis2

I have a web service hosted on a Windows Server which I can connect to with .net code and I am trying to gain access using Apache Axis2. I have been working with clj-soap which isn't being maintained but appears moderately stable.
Connecting to the service endpoint works ie (soap/client-fn service-address) but whenever I attempt to call a function Axis2 gives this exception:
org.apache.axis2.transport.http.HTTPSender sendViaPost
Unable to sendViaPost to url[MY-URL]
org.apache.axis2.AxisFault: Transport error: 404 Error: Not Found
Through some googling I've ran across things like this, which tells me that Windows is requiring some authentication or proxy configuration. I'm not sure what kind of authentication the server requires. The .net code does not authenticate with a password, so I am at a loss.
I'm looking for some help determining what information to give Axis2 to pass along to the server so my program can communicate with the web service.
The C# code is provided below, as a reference. It uses the ServiceModel library.
class Program {
private static MyService CreateServiceChannel () {
BasicHttpBinding binding = new BasicHttpBinding ( BasicHttpSecurityMode.Transport );
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.MaxReceivedMessageSize = 204003200;
binding.ReaderQuotas.MaxArrayLength = 2147483647;
binding.ReaderQuotas.MaxStringContentLength = 2147483647;
EndpointAddress address = new EndpointAddress ( "https://...service.svc" );
ChannelFactory<MyService> channelFactory = new ChannelFactory<MyService> ( binding, address );
MyService channel = channelFactory.CreateChannel ();
return channel;
}
static void Main ( string[] args ) {
Console.WriteLine ( CreateMyChannel ().CallFunction ( 1 ) );
}
}

calling web service

I created web service :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data.SqlClient;
using System.Data;
namespace MemberWebService
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public DataSet GetMemberData(string memberId, string thirdName)
{
SqlConnection cn = new SqlConnection("Data Source=.;Initial Catalog=Healthy;Integrated Security=TRUE");
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
da.SelectCommand = new SqlCommand("SELECT * FROM MemberMaster WHERE MemberId=#MemberId and ThirdName=#ThirdName", cn);
da.SelectCommand.Parameters.Add("#MemberId", SqlDbType.NVarChar).Value = memberId;
da.SelectCommand.Parameters.Add("#ThirdName", SqlDbType.NVarChar).Value = thirdName;
ds.Clear();
da.Fill(ds);
return ds;
}
}
}
and when i run it this is the link :
http://localhost:19722/Service1.asmx
and it work OK.
if i call it in asp.net as a web reference it work correctly till the server port is open if i close the port the asp.net page cannot see the web service so
how can i solve the problem and if i want to make this web service work on another device how can i do it ?
That port is specifically used for Visual Studio - it's either Cassini or IIS Express, and is only used for debugging purposes, not for live production work. When you're ready to publish your service, it will likely go into IIS in a regular permanent port (probably 80). Once it's there, it will always be available for your client to call.
After you publish the service to IIS, you'll just need to update the config file for the client to point to the real permanent URL.

Writing Webservice clients using HttpURLConnection

I have a question related to Axis2 Webservices .
I have My Webservice deployed in Tomcat Server .
Right now i am writing a Client for my Webservice using
public static void main(String[] args) {
try {
samples.quickstart.StockQuoteServiceStub stub = new samples.quickstart.StockQuoteServiceStub();
samples.quickstart.StockQuoteServiceStub.GetPrice request = new samples.quickstart.StockQuoteServiceStub.GetPrice();
request.setSymbol("ABCDE");
samples.quickstart.StockQuoteServiceStub.GetPriceResponse response = stub
.getPrice(request);
}
catch (org.apache.axis2.AxisFault e) {
e.printStackTrace();
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
}
This works fine.
I have seen from net some clients are written using HttpURLConnection.
Please tell me what is the difference between writing clients by using the former way and the later way.
The way you have done give you a more abstract way. It has generated the code for you and you need only to provide the parameters to pass. Here Axis2 users the commons httpclient as to send message using http transport. As you can see Axis2 handles all the transport specific things for you.
On the other hand you can create the soap message to send from your own and send using an httpClient. But there you need to do a lot of work.

How To Use WebService In Windows Smart Phone 6?

I am Developing one Windows Smart Phone - 6 Application using C# in .Net 3.5 Framework. And I have created one Webservice project using ASP.Net Web Service Application 3.5. Into this Webservice project I have define Service1.asmx. Now I would like to call Webmethod "HelloWorld" on Button Click. Here is code.
Service1.asmx
using System.Web.Services;
namespace WebService1
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
And Button Click Event
private void button1_Click(object sender, EventArgs e)
{
WebService1.Service1 myService = new WebService1.Service1();
string str = myService.HelloWorld();
}
I am Getting Error On This Line
WebService1.Service1 myService = new WebService1.Service1();
Please Give Me Guidance As I am Very New In This.
Thanks In Advance
Pratik Bhatt
Use the add web reference dialog from visual studio and point them to your hosted service. The dialog creates the consuming client based on the generated WSDL.
Your approach doesn't work because hosting a webservice and consuming one uses a different set of classes.
Problem Solved.
Error Was Occurring Because The Smart Device Emulator has No Access Permission for internet(network)so you have to install Microsoft Active Sync to connect emulator to network
Thanks Ralf Ehlert For Suggesting.....