1
votes

I have set up a very basic DataSnap Server Application (Delphi XE3), containing the 2 sample methods, EchoString and ReverseString. I have added authentication so that only if the user calling the method is called "standard", they have access to the ReverseString method.

procedure TServerContainer1.DSAuthenticationManager1UserAuthenticate(
Sender: TObject; const Protocol, Context, User, Password: string;
var valid: Boolean; UserRoles: TStrings);
begin
  valid := (User <> '');

  if (SameText(User, 'standard') = True) then
  begin
    UserRoles.Add('standard');
  end;
end;

type
TServerMethods1 = class(TDSServerModule)
private
  { Private declarations }
public
  { Public declarations }
  function EchoString(Value: string): string;
  [TRoleAuth('standard')]
  function ReverseString(Value: string): string;
end;

If I call this method from a browser directly, e.g.

http://localhost:8080/datasnap/rest/TServerMethods1/ReverseString/TestFromBrowser

then I get the expected response (after the browser's default login prompt, in which I enter an invalid user, e.g. Jason):

{"error":"jason is not authorized to perform the requested action."}

However, if I call it from a Delphi client application using Indy (TIdHTTP):

IdHTTP1.Request.BasicAuthentication := True;
IdHTTP1.Request.Username := 'jason';
IdHTTP1.Request.Password := 'jason';

Label2.Caption := IdHTTP1.Get('http://localhost:8080/datasnap/rest/TServerMethods1/ReverseString/TestFromDelphi');

I get this response:

HTTP/1.1 500 Internal Server Error

How can I avoid the error and receive the same RESTful response that I got in the browser? I have been trying to figure out how to view the HTTP request sent by the browser vs that sent by Indy but haven't managed it, even using Ethereal.

1
to capture requests and responses you can use Fiddler 2 as a HTTP proxymjn
Thanks mjn I'll take a look.J__
Or Wireshark (the successor to Ethereal), since the connection is not using SSL. If you use Fiddler, you have to configure the TIdHTTP.ProxyParams property accordingly so TIdHTTP will connect to Fiddler.Remy Lebeau
What HTTP authentication scheme(s) does the DataSnap server support? BasicAuthentication := True allows TIdHTTP to fallback to the BASIC scheme if no other authentication is used. What values are being reported in the AuthInfo parameter of the TIdHTTP.OnSelectAuthorization event? That will tell you which schemes the server supports (if you cannot see it in Wireshark/Fiddler). TIdHTTP uses a plugin architecture for HTTP authentication, so make sure have added the relevant IdAuthentication... units to your uses clause for each scheme you want to enable.Remy Lebeau
Thanks Remy, will take a further look. Datasnap only supports Basic authentication as far as I have read, which is fine for the purpose I need.J__

1 Answers

1
votes

I have been able to establish what is going on. Using Wireshark and Rawcap (to capture local loopback requests), I can see that even though the browser is showing the meaningful message:

{"error":"jason is not authorized to perform the requested action."}

it is also returning an HTTP 500 Internal Server Error. However, the meaningful response text is also returned as part of this response, which is being displayed by the browser.

Response from Browser

Checking the Indy HTTP response, it is the same; the actual response code is a 500, but the text I want to display is also being returned.

enter image description here

This is accessible by capturing the EIdHTTPProtocolException and accessing its ErrorMessage property.