簡體   English   中英

Delphi Datasnap 客戶端代碼未獲得未經授權的異常

[英]Delphi Datasnap client code not getting unauthorized exception

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

如果我在沒有調試的情況下運行應用程序並調用用戶無權調用的方法,則代碼運行沒有任何異常,並且該方法返回空響應。

當以交互方式調試客戶端上對 DataSnap 服務器方法的調用時,我收到兩個關於“未經授權”的彈出異常。

第一個冒泡並被第二個取代。

第二個異常被“吃掉”,會話/連接簡單地關閉,然后該方法返回一個空白結果(例如,如果返回類型是整數則返回零,而對於字符串返回類型則返回空字符串)。

這發生在 Datasnap.DSClientRest 單元中 ExecuteRequest 方法末尾附近的以下代碼部分中:

except
  on E: TDSRestProtocolException do
    LSessionExpired;
end;

為什么這些異常(例如 TDSRestProtocolException)沒有到達我的代碼?

我有點認為這是更新 2 的新內容,我記得在更新 2 之前看到這些異常冒泡到我的代碼中。

附件是一個框架示例(由 Delphi 向導生成的標准示例),它演示了這個問題——單擊按鈕,你得到“”而不是“4321”,因為用戶沒有被授權——但沒有運行時異常。

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

預先感謝有用的回復 =)

這是由於 DSAuthenticationManager1 組件添加到服務器的 webmodule 和客戶端無法進行身份驗證而發生的。

請通過此檢查如何使用身份驗證添加身份驗證和授權

好吧..我不確定,但嘗試在創建服務器方法實例之前向 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;

也許有點晚了,但今天早上我已經深入研究了這一點,因為在從 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;

因為我的應用程序提供了一些可下載的項目,例如徽標等,所以我將檢查限制在那些與數據快照有關的 URL。

希望這對其他人有用!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM