【问题标题】:Delphi Datasnap client code not getting unauthorized exceptionDelphi Datasnap 客户端代码未获得未经授权的异常
【发布时间】:2017-01-30 01:53:07
【问题描述】:

我正在使用 Delphi 10.1 Berlin Update 2 Enterprise 和 DataSnap 客户端/服务器 REST 框架。

如果我在未调试的情况下运行应用程序并调用用户无权调用的方法,则代码运行时没有任何异常,并且该方法返回空响应。

交互式调试客户端调用 DataSnap 服务器方法时,我收到两个关于“未经授权”的弹出异常。

第一个冒泡并被第二个取代。

第二个异常被“吃掉”,会话/连接简单地关闭,然后该方法返回一个空白结果(例如,如果返回类型为整数,则返回零,返回类型为空字符串)。

这发生在 Datasnap.DSClientRest 单元中 ExecuteRequest 方法末尾附近的以下代码部分中:

except
  on E: TDSRestProtocolException do
    LSessionExpired;
end;

为什么这些异常(例如 TDSRestProtocolException)没有到达我的代码?

我觉得这对于 Update 2 来说是新的,我记得在 Update 2 之前看到这些异常出现在我的代码中。

Attached 是一个演示问题的框架示例(由 Delphi 向导生成的标准示例) - 单击按钮,您会得到“”而不是“4321”,因为用户未获得授权 - 但没有运行时异常。

我是 DataSnap 的新手,请耐心等待 :-)

在此先感谢您提供有用的回复 =)

【问题讨论】:

  • 注意这是使用客户端 DataSnap REST 模块 (http),而不是简单的 TCP/IP 客户端 DataSnap 模块。

标签: delphi exception authorization datasnap


【解决方案1】:

这是由于 DSAuthenticationManager1 组件添加到服务器的 web 模块和客户端未能通过身份验证。

请通过此检查如何使用身份验证 Adding Authentication and Authorization

【讨论】:

  • 本文使用的是DataSnap Client Module,而不是我需要使用的DataSnap Client REST Module。即使我在客户端 DSRESTConnection1 组件上设置了用户名,授权异常仍然没有到达 UI。笔记!这些异常发生在库代码中,但不会出现在我的代码中。授权检查正在发生,但我的 UI 代码没有看到异常,因为它们在库代码中被吃掉了。
  • 为清楚起见,“添加身份验证和授权”一文中的 SQLConnection1 按预期工作,UI 看到未经授权的异常。我的示例项目中的 DSRestConnection1 在相同的配置下没有看到相同的异常。
【解决方案2】:

好吧..我不确定,但请尝试在创建服务器方法实例之前向 DSRestConnection1 组件提供用户名和密码

procedure TClientModule1.TestCon(aUsername, aPassword: string);
var
lServerMethodsClient : TServerMethodsClient;
begin
DSRestConnection1.UserName := aUsername;
DSRestConnection1.Password := aPassword;
lServerMethodsClient:=TServerMethodsClient.Create(DSRestConnection1);
end;

并尝试从您的客户端表单中调用此函数

procedure TF_ClientForm.Button1Click(Sender: TObject);
begin
ClientModule1.TestCon(EdtUsername.Text, EdtPassword.Text);
end;

【讨论】:

  • 问题不在于身份验证entication,而是身份验证ourizationation :-)
  • 我最终通过 TCP/IP 切换到“DataSnap 服务器”和“DataSnap 客户端模块”。工作精美。请注意为什么 REST 等价物有这个问题,但我已经浪费了足够的时间!谢谢,pn098,花时间贡献=D
【解决方案3】:

可能有点晚了,但今天早上我已经深入研究了这个问题,因为在从 Delphi XE6 升级到 Tokyo 10.2 之后,我使用 TDSRestConnection 组件的应用程序被破坏了。尽管我提供了正确的用户名和密码,但它们并未出现在 TDSAuthenticationManager.OnUserAuthenticate 事件中。 “问题”与新的 System.Net.HttpClient 实现有关。

长话短说(或稍长一点): 客户端组件不会发送凭据,直到接收服务器通过发送 401 响应要求提供凭据。在接收到这个(正确格式化的)响应后,客户端会再次查看 de TDSConnection 凭据。在客户端,维护了具有凭据要求的完整 url 列表,因此对同一 url 的重复调用变得“更顺畅”。

我将此代码添加到服务器的 WebModule(TDSRESTWebDispatcher 所在的位置),从而解决了我的问题:

procedure TwbmMain.WebModuleBeforeDispatch(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  LAuthorization: string;
begin
  inherited;

  if Request.PathInfo.StartsWith('/datasnap/') then
  begin
    LAuthorization := TNetEncoding.Base64.Decode(Request.Authorization.Replace('Basic ', ''));

    if LAuthorization.IsEmpty then
    begin
      Response.StatusCode := 401;
      Response.WWWAuthenticate := 'Basic';
      Handled := True;
    end;
  end;
end;

因为我的应用程序提供了一些可下载的项目,例如徽标等,所以我将检查限制在与 datasnap 有任何关系的那些 URL。

希望这对其他人有用!

【讨论】:

    猜你喜欢
    • 2020-05-30
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 2013-08-03
    • 2020-07-14
    • 2015-02-01
    • 2021-12-03
    相关资源
    最近更新 更多