Delphi 7 SOAP Authentication and SessionID HowTo - delphi

I am developing a 3 tier database application.
1.) MS SQL DB
2.) Middle tier SOAP Server (with Delphi 7) connected to the DB
3.) Clients (first win32 gui (with Delphi 7) - later other platfomrs) connected to the SOAP server
I chose a SOAP Server to be open to various clients at a later stage (also some of the win32 gui clients will be stationed abroad - so the clients need to be thin) (this as suggested by Dr. Bob).
I am new to SOAP and have been looking at different examples and papers about authentication. But cant quite get my head around it.
I have made a SOAP server and client with Delphi's SOAP Server Application Wizard and added a SOAP SERVER Data Module, added a database connection and some datasets and providers. Connected the client with dbgrid etc and that part works fine.
But I want the client first to login and then be able to access data and I want the server to log each connection and also when the client logs off or is disconnected, so I am guessing I need the sessionID and a timeout. I also want the server to be able to tell the clients who else is "connected" (or whos session is still active) at any given time.
I have gathered that I need to make a authentication header, but cant figure out where or who I can get a sessionID. I presume that each time a client connectes to the server the server generates a sessionID? How do I get this?
Any help or suggestions/pointer would be appreciated,
thanks
Justin

Soap servers do not provide sessions by default. Your server has to implement Session life cycle managment (Login / Logout) etc.
A basic solution is documented here: Managing sessions with Delphi 6 Web services
Note however that this solution is far from perfect (see comments), for example it does not provide a session timeout mechanism.

OK - figured it out - I had not:
InvRegistry.RegisterHeaderClass(TypeInfo(IThorPayServerDB), TAuthHeader);
in the initialization
But I still cant figure out how to get the session ID - or some unique way of know which client session is loged in to the server - any ideas?

Delphi XE uses a newer version of SOAP, maybe that is the answer:
https://forums.embarcadero.com/thread.jspa?messageID=200793

Related

Getting a webservice to use a certificate

the title might be a bit off but I really didnt know how to put it in a title.
The situation is as follows.
There are 3 applications.
1. A stand alone windows application
2. A webservice that runs in IIS
3. A REST server
Our users work with the windows application(1).
The REST server only allows calls by using our client certificate, we want to prevent that just anyone can do calls so we added another layer by letting people do a call to our webservice (2) which then does the call to the REST server(3).
We have 2 versions of this webservice, one is standalone, the other is running in IIS. When we use the standalone version it all works fine, but when we use the IIS version we get an error
REST Request failed: Unspecified certificate from client.
I assume that the client certificate that was installed is not accessible by IIS and i've been searching on google without result so far.
Basicly I am looking for a way to install the certificate in such a way that the webservice will use this certificate when making the call to the REST server.
Any help on this would be much appreciated.
The windows standalone application is made with Delphi, so is the webservice.
If there is additional information required please let me know and I will provide what I can.
Thanks in advance
Q: By #mjn "Can you provide more details about how your IIS application is coded? (coded in Delphi? which HTTP client library? How does the actual HTTP request code like like?)"
A: Yes it's coded in Delphi, for the request I used a class that uses the delphi component TRestClient
Example of a request:
Call to the request:

Connect to already open Quickbooks instance via QBXML

I'm trying to help a client who has a web application (ASP/C#) that integrates with Quickbooks via the QBXML SDK.
I want to open up a connection to an already active QuickBooks instance in a user session.
The relevant code in question:
if (rp == null)
rp = new RequestProcessor2();
if (!connected)
{
rp.OpenConnection2("IMS", "Internal Management System", QBXMLRPConnectionType.localQBD);
connected = true;
}
if (xticket == null)
xticket = rp.BeginSession(cfg.qbfile, QBFileMode.qbFileOpenMultiUser);
As is, this will attempt to launch a new instance of Quickbooks via DCOM, which is not a viable option. Following the QBSDK documention, I attempted to pass null to BeginSession's first argument, which should use the open qbw file.
However, instead of the expected action of connecting to the running instance of Quickbooks, it launches a new instance, eventually yielding the error:
"If the QuickBooks company data file is not open, a call to the "BeginSession" method must include the name of the data file."
The IIS AppPool running the web app uses the same user as the Quickbooks instance I'm trying to connect to.
This was all set up by a third party who is no longer available, and, of course, they left no documentation whatsoever on how this system was supposed to work. Any assistance would be welcome.
I'm trying to help a client who has a web application (ASP/C#) that integrates with Quickbooks via the QBXML SDK.
Unfortunately, this approach will not work.
It's a well-known limitation of QuickBooks that:
QuickBooks has to be running in the user session you're trying to connect from
QuickBooks has to have access to a GUI (it uses a GUI message pump to function)
Because your web app is running in from within IIS, neither of those two criteria are met, and connections to QuickBooks will fail. You should be using the QuickBooks Web Connector instead.
I want to open up a connection to an already active QuickBooks instance in a user session.
Unfortunately, QuickBooks won't allow this.
I managed to create an acceptable workaround to my problem, for anyone trying something similar. (Which, honestly, I don't recommend. I'm working with legacy code here.)
First, a brief overview of my research:
The QBXml interface with QuickBooks uses COM requests in order to communicate. Now, for whatever reason, whether design, bug, or limitation in COM, Quickbooks cannot communicate across LSA Logon Sessions. In practice, this means that the same console session that Quickbooks is running under must also run the QBXml code. Additionally, both Quickbooks and your application must have the same UAC elevation status.
I found no way to get IIS to reliably launch Quickbooks. The individual who setup this system before me managed to do so through some very... unorthodox methods. It was incredibly flaky, and the cause of multiple issues.
Regardless, I did manage an acceptable workaround, in the form of IIS Express. IIS Express can run under a standard user session. As such, running both Quickbooks and the web app (through IIS Express) under the same Logon Session allowed them to communicate successfully.
It is not a permanent solution, as there are drawbacks to running a service such as this in a standard user paradigm, but it is an acceptable workaround, and will allow my client to run their business while we refactor. I plan to first decouple the portions of the app that communicate with Quickbooks, moving them into their own codebase. This will allow the web facing portions of the app to operate in a more standard manner, and communicate with the QB integration code through a more reliable means than COM calls.
Thanks to Keith Palmer for helping point me in the right direction.

Fetch data from Siebel CRM

I'm planning to develop an adapter to access Siebel CRM data for my iOS app. I'm a new bee into this Siebel technology. I 've the Siebel CRM up an running in my workstation with sample db data. Could any one help me in getting this done? please excuse me if i've hosted this ques in a wrong stack.
There seems to be only 2 valid ways to do that:
SOAP webservices
REST api (but for this you need to have jboss or weblogic server: Sebel Bookshelf)
all other ways (Java Siebel Data Bean, COM interfaces, direct db access) got lots of issues: like issues with java on iOS ( I think it is not possible to run on iPhone), issues with legacy COM interfaces on iOS and numerous issues with direct db connection (complexity, stability, reusability...)
SOAP is out of the box on Siebel but requires more coding on iOS side, REST is easier on iOS or any webpage but requires some middlware:
JBoss/WebLogic + and RESTfull Siebel client form Siebel (available somewhere on their page)
java data bean app that produces REST
soap client that produces REST
I have worked on 2 projects involving iOS and Siebel: first one using JBoss and second project that used SOAP client which translated requests to/from REST. SOAP client approach was more stable (in comparison to RESTfull client from vendor - as the RESTfull client connects to Siebel internally using Java Data Bean) on Siebel 7.8.
In both cases we picked REST to talk to iOS as it allows easier deveopment on iOS side and also possiblity to easly utilize it in projects creating webpages to simplify/tune siebel GUI for different purpose..
If you're current system is sample db, then you have installed developer instance of Siebel. It uses a Sybase database. The server installation will use Oracle/MSSQL server. If you are ok with database connection, you can check that.
For Webservices, by default , Siebel does not support JSON/REST api. Only the older SOAP structure is supported. You will have to go through oracle bookshelves to setup an inbound webservice in Siebel.
But just to add, the latest version of Siebel's UI uses javascript/CSS, and runs on any browser, including IOs .

DataSnap server - redirect HTTP requests to another DataSnap server

My application consists of a 'gateway' DataSnap REST server that is the first point of access for all clients. Depending on the username the clients pass in their requests (basic authentication), the request needs to be redirected to another DataSnap server. My question - is there anyway of building the 'gateway' server so that it simply redirects whatever the request is to another server based on the username, or other values in the HTTP request headers? I'm trying to avoid having to repeat all the server methods in the 'gateway' service i.e. I'd rather not 'chain' 2 requests together but somehow just have 1 request redirected.
Not sure if this is possible, but thought somebody might prove me wrong? I'm using Delphi XE2 and the DataSnap servers are Windows services.
I can see two options here:
use the first server only to return the address of the real server after logging in
or
use a Apache or NGINX reverse proxy in front of the Datasnap servers and RewriteRules based on the authentication data (however my Google-Fu for today seems to be exhausted, maybe this can be placed as a HTTP / Apache specfifc question here on SO)
Short version: the solution will depend on which level (HTTP, DataSnap, in between) you know where to target the request to.
If you can make the decision on the DataSnap level, there are two kinds of solutions:
The purists way to do this is write a generic DataSnap gateway that can interrogate a datasnap target server, dynamically creates both a proxy server and client for it, then intercepts the traffic and decides which datasnap target server to hand over the request to.
A more pragmatic approach would be the one you are afraid of.
Another approach would be on the HTTP level. That will only work if you can determine at the HTTP level to which target server a request should be handed over to.

Single page apps keeping client and server in sync

I am trying to understand how single page apps spa's work.
My understanding of a spa is that you load the data on start-up and you use ajax calls for save etc, and the whole idea is that your models cache data on the client so you have a rich snappy experience in your browser.
I am confused as to how the client stays in sync with the server changes.
E.G. If I have multiple users logged into my spa and they are all making changes, how does my client know that another user has updated a persons details if it is using cached data?
My guess is that something similar needs to happen server side to update the client on a change. Does this exist or am I misunderstanding something?
Any help or pointers to additional info would be much appreciated.
Thank you in advance.
For server to client communication you can use SignalR.
SignalR allows you to create a hub on the server which you can then tell to update the clients.
It works with a fallback mechanism, it tries to use the following techniques and falls back onto the next one if it's not available in the browser:
Web Sockets
server sent events
forever frame
long polling
Link for fallbacks: http://www.asp.net/signalr/overview/introduction/transports-and-fallbacks
Link for signalR: http://signalr.net/

Resources