如何对此 HTTPS SOAP 服务进行身份验证?

发布于 2024-12-05 08:18:57 字数 1661 浏览 2 评论 0原文

我正在尝试创建一个小工具来监控我已经使用了多少带宽以及我的 ISP 还剩多少带宽。他们有一个 SOAP 服务,我必须验证我的用户名和密码并验证客户端,然后我将获得 2 个 GUID,必须将其传递到将从数组返回使用统计信息的函数中。然后这些会被缓存 1 小时,我必须再次进行身份验证。

我在 Delphi 2010 中使用了 WSDL Importer,它为我生成了一个单元。 (我不太确定我应该发布这个,因为它很大)?

我尝试使用以下代码使用我的用户名和密码验证第一部分:

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;

上面的代码始终返回以下错误:

标题 http://schemas.xmlsoap.org/ws/2004/08 /addressing:最终收件人的操作是必需的,但未出现在消息中。


我尝试使用 WSDLLocation 代替服务和端口:

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; 

这将始终生成以下错误:

无法从 WSDL“https://webservices.zen.co.uk/broadband/v3.11/serviceengine.asmx?WSDL”检索服务/端口“ServiceEngine”/“ServiceEngineSoap”的 URL 端点


我是什么这里做错了吗?如果我实际上应该发送一个标头,那么我将如何执行此操作来向服务验证自己的身份?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

女中豪杰 2024-12-12 08:18:58

根据 文档

如果服务器需要身份验证,请使用
THTTPReqResp对象提供必要的信息

您可以在 THTTPReqResp 对象中设置用户/密码 (HTTPRIO1.HTTPWebNode.UserName := 'xxx'; HTTPRIO1.HTTPWebNode.Password := 'yyy')

另请注意有关使用 HTTPS 的文档:

THTTPReqResp 使用 WinInet 建立与服务器的连接。
Wininet.dll 必须安装在客户端系统上。 wininet.dll 是
如果您有 IE3 或更高版本,可在 Windows 系统目录中找到
安装。 WinInet 的优点是它提供支持
安全连接 (https)。要使用 WinInet,请编译您的项目
没有定义 USE_INDY 符号

但是,根据下面的帖子,看起来这个用户/密码只能在代理情况下使用。如果 Jean-Marie Babet 的链接仍未修复此问题,请访问 2007 年给出的原始解决方法:

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

这是解决方法:

您所要做的就是处理 OnBeforePost 事件
HTTPRIO.HTTPWebNode 组件并使用 InternetSetOption。这是一个
与 MapPoint 对话的示例中的示例(MapPoint.NET 使用
“摘要”身份验证 - “基本”身份验证的变体):

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;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文