Delphi Datasnap客户端代码未获得未经授权的异常

时间:2017-01-30 01:53:08

标签: delphi exception authorization datasnap

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

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

以交互方式调用客户端上的调用到DataSnap服务器方法时,我得到两个关于"未授权"的弹出例外。

第一个冒泡并被第二个更换。

第二个例外被吃掉"吃掉了#34;并且会话/连接只是关闭,然后该方法返回一个空白结果(例如,如果返回类型是整数则为零,而字符串返回类型为空字符串)。

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

except
  on E: TDSRestProtocolException do
    LSessionExpired;
end;

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

我认为这是Update 2的新功能,我记得在Update 2之前看到这些异常会出现在我的代码中。

Attached是一个骨架示例(由Delphi向导生成的标准示例),用于演示此问题 - 单击按钮即可获得""而不是" 4321"因为用户没有被授权 - 但没有运行时异常。

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

提前感谢您提供有用的回复=)

3 个答案:

答案 0 :(得分:1)

由于DSAuthenticationManager1组件已添加到服务器的webmodule并且客户端无法进行身份验证,因此发生这种情况。

请仔细阅读以查看如何使用身份验证 Adding Authentication and Authorization

答案 1 :(得分:0)

嗯..我不确定但是在创建服务器方法实例之前尝试为DSRestConnection1组件提供用户名和密码

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

并尝试从ur clientform

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

答案 2 :(得分:0)

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

简而言之(或更长一点): 直到接收服务器通过发送401响应来请求凭据,客户端组件才发送凭据。客户端收到此(正确格式)响应后,将再次尝试查看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;

因为我的应用程序提供了一些可下载项(例如徽标等),所以我将检查范围限制为仅与数据快照有关的URL。

希望这对其他人有用!