views:

415

answers:

3

Hi

In a delphi program (running as a service) i need to call some webservices.
The calls works fine if basic Authentications is not requerired. The calls also works fine if Basic Authentication is requerired and username/password is provided (in BeforePost) using:

InternetSetOption(Data, INTERNET_OPTION_USERNAME,...
InternetSetOption(Data, INTERNET_OPTION_PASSWORD,...

But if Basic Authentication is Requeried, and username/password is not provided, the program brings up af prompt for the username/password (thats a NO-GO in a servcice).

So how can I signal that i DON'T want a prompt, but instead an error?

The problem is, as i can se it, in the SOAPHTTPTrans function THTTPReqResp.Send(const ASrc: TStream): Integer; (line 762 (second call to InternetErrorDlg i that method)).

EDIT1:
if i change the Flags in the beginning of the send method (in SOAPHTTPTRANS) to include INTERNET_FLAG_NO_AUTH, it works as i wanted.
But how do i do that without changing the SAOPHTTPTrans (if possible)?

EDIT2:

ws := THTTPRIO.Create(Self);
ws.URL := 'http://excample.com/ws.asmx';
ws.HTTPWebNode.InvokeOptions := [soIgnoreInvalidCerts];
ws.HTTPWebNode.OnBeforePost := WebServiceCallBeforePost;
AvailabilityWebservice := (ws as AvailabilityServiceSoap);
sTemp := AvailabilityWebservice.GetVersion;

Where AvailabilityServiceSoap is the interface generated using the WSDL importer.

+1  A: 

You could create a new class which Inherits from THTTPReqResp and override the send method so that you can include your own flags. You should be able to set ws.HTTPWebNode to a new node using the new class.

Something Like

ws := THTTPRIO.Create(Self);
MyNewNode := MyNewClass.Create;
ws.HTTPWebNode := MyNewNode;
ws.URL := 'http://excample.com/ws.asmx';
ws.HTTPWebNode.InvokeOptions := [soIgnoreInvalidCerts];
ws.HTTPWebNode.OnBeforePost := WebServiceCallBeforePost;
AvailabilityWebservice := (ws as AvailabilityServiceSoap);
sTemp := AvailabilityWebservice.GetVersion;
JamesB
That seems like a workable solution, I just dont like having to copy the 170 lines from THTTPReqResp.Send . So if there is any way do achieve it without copying that code it seems better.
BennyBechDk
I tried to copy the Send method to my own object, but to many private variables was used. So got get it working the entire unit has to be copied and modified.
BennyBechDk
+1  A: 

I had this problem when trying to let Windows Live Messenger work through a web filter.

I ended up writing a small program that auto-authenticates every so often.

Hope this helps you too.

uses
  ... IdHTTP ...;

...
var
  httpGetter: TIdHTTP;
...    
httpGetter.Request.Username := username;
httpGetter.Request.Password := password;
httpGetter.HandleRedirects := True;
httpGetter.Request.BasicAuthentication := True;

//custom useragent required to let live messenger work
//this part is probably not necessary for your situation
httpGetter.Request.UserAgent := 'MSN Explorer/9.0 (MSN 8.0; TmstmpExt)';

httpGetter.Get(url,MS);
...
JosephStyons
It dosn't solve the problem. The problem is when username and password is NOT entered, the program displays a prompt af waits (and running as a service on a unattended server, this is not god). I'b be happy recieving an error, and handling that like any other error.
BennyBechDk
+1  A: 

How about checking the servers authentication mode first?

http://en.wikipedia.org/wiki/Basic_access_authentication

  • The client asks for a page that requires authentication but does not provide a user name and password. Typically this is because the user simply entered the address or followed a link to the page.
  • The server responds with the 401 response code and provides the authentication realm.

So the client service application could send a Get and see if the response has a header like

WW-Authenticate: Basic realm="Secure Area"
mjustin