Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I Authenticate to this HTTPS SOAP Service?

Tags:

soap

https

delphi

I am trying to create a little tool that will monitor how much bandwidth I have used and how much I have remaining from my ISP. They have a SOAP service which I must authenticate my UserName and Password and validate the client then I will get 2 GUIDS that must be passed into the function that will return the usage statistics from an array. These are then cached for 1 hour and I must authenticate again.

I have used the WSDL Importer from within Delphi 2010 and it has generated me a Unit. (I am not really sure that I should post this as it is quite large)?

I am trying to authenticate the first part with my Username and Password with the code below:

procedure TForm1.btnAuthClick(Sender: TObject);
var
  fGUID: string;
begin
  HTTPRIO1.URL := 'https://webservices.zen.co.uk/broadband/v3.11/serviceengine.asmx?WSDL';
  try
    fGUID := (HTTPRIO1 as ServiceEngineSoap).Authenticate(edtUserName.Text,edtPassword.Text);
    Label1.Caption := fGUID;
  except
    on E: Exception do
    Memo1.Lines.Text := E.Message;
  end;
end;

The above code always returns the Error below:

Header http://schemas.xmlsoap.org/ws/2004/08/addressing:Action for ultimate recipient is required but not present in the message.


I have tried using the WSDLLocation instead with the Service and the Port:

procedure TForm1.btnAuthClick(Sender: TObject);
var
  fGUID: string;
begin
  HTTPRIO1.WSDLLocation := 'https://webservices.zen.co.uk/broadband/v3.11/serviceengine.asmx?WSDL';
  HTTPRIO1.Service := 'ServiceEngine';
  HTTPRIO1.Port := 'ServiceEngineSoap';
  try
    fGUID := (HTTPRIO1 as ServiceEngineSoap).Authenticate(edtUserName.Text,edtPassword.Text);
    Label1.Caption := fGUID;
  except
    on E: Exception do
    Memo1.Lines.Text := E.Message;
  end;
end; 

This will always generate the Error below:

Unable to retrieve the URL endpoint for Service/Port 'ServiceEngine'/'ServiceEngineSoap' from WSDL 'https://webservices.zen.co.uk/broadband/v3.11/serviceengine.asmx?WSDL'


What am I doing wrong here? If I should actually send a Header then how would I do this to authenticate myself to the service?

like image 299
Shambhala Avatar asked Sep 18 '11 17:09

Shambhala


1 Answers

According to the docs

if the server requires authentication, use the properties of the THTTPReqResp object to provide the necessary information

It's in the THTTPReqResp object that you set the user/pw (HTTPRIO1.HTTPWebNode.UserName := 'xxx'; HTTPRIO1.HTTPWebNode.Password := 'yyy')

Also note from the docs on using HTTPS:

THTTPReqResp uses WinInet to establish a connection to the server. Wininet.dll must be installed on the client system. wininet.dll is found in the Windows system directory if you have IE3 or higher installed. WinInet has the advantage that it provides support for secure connections (https). To use WinInet, compile your project without the USE_INDY symbol defined

However, it looks like this user/pw may only be used in a Proxy situation according to the post below. Follow Jean-Marie Babet's link to the original workaround given from 2007 if they still haven't fixed this:

https://forums.codegear.com/thread.jspa?threadID=58755&tstart=0

Here's the workaround:

All you have to do is handle the OnBeforePost event on the HTTPRIO.HTTPWebNode component and use InternetSetOption. Here's an example from a sample that talks to MapPoint (MapPoint.NET uses 'digest' authentication - a variant of 'basic' authentication):

procedure TTestMapPointRender.HTTPRIO1HTTPWebNode1BeforePost(
  const HTTPReqResp: THTTPReqResp; Data: Pointer);
var
  UserName: string;
  PassWord: string;
begin
  UserName := GetWSToken('MapPoint', 'UserName');
  Password := GetWSToken('MapPoint', 'Password');
  if not InternetSetOption(Data,
               INTERNET_OPTION_USERNAME,
               PChar(UserName),
               Length(UserName)) then
     raiseException(SysErrorMessage(GetLastError));

  if not InternetSetOption(Data,
               INTERNET_OPTION_PASSWORD,
               PChar(Password),
               Length (Password)) then
     raiseException(SysErrorMessage(GetLastError));
end;
like image 120
Darian Miller Avatar answered Nov 12 '22 08:11

Darian Miller