1

I work with Delphi Tokyo and the Indy components that come with it. I need to use a HTTPS REST webservice using NTLM. I always receive a "HTTP/1.1 401 Unauthorized" exception.

1) Any ideas of what I have to do to pass the credentials correctly?

2) Is it a typical reaction to raise an exception? I had expected a simply 401 response string.

uses
  SysUtils, Classes,

  IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP,
  IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL,
  IdAuthentication, IdAllAuthentications, IdAuthenticationNTLM,
  IdAuthenticationSSPI, IdHeaderList;

function TRestService.GetSSL(AURL: String): String;
  var AHTTP : TIdHTTP;
      ASSLSocket   : TIdSSLIOHandlerSocketOpenSSL;
begin
  ASSLSocket := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  ASSLSocket.SSLOptions.Method := sslvSSLv23;
  ASSLSocket.SSLOptions.Mode   := sslmClient;

  AHTTP := TIdHTTP.Create(nil);
  AHTTP.IOHandler              := ASSLSocket;
  AHTTP.ProtocolVersion        := pv1_1;
  AHTTP.HandleRedirects        := True;
  AHTTP.Request.ContentType    := 'application/json; charset=utf-8';
  AHTTP.HTTPOptions            := AHTTP.HTTPOptions + [hoKeepOrigProtocol] + [hoInProcessAuth];
  AHTTP.Request.Username       := Username;
  AHTTP.Request.Password       := Password;
  AHTTP.OnAuthorization        := OnAuthorization;
  AHTTP.OnSelectAuthorization  := OnSelectAuthorization;

  try
    Result := AHTTP.Get(AURL); // exception
  finally
    AHTTP.Free;
  end;
end;

procedure TRestService.OnAuthorization(Sender: TObject; Authentication: TIdAuthentication; var Handled: Boolean);
begin
  // never called
end;

procedure TRestService.OnSelectAuthorization(Sender: TObject; var AuthenticationClass: TIdAuthenticationClass; AuthInfo: TIdHeaderList);
begin
  // is called and gives:
  // AuthenticationClass.ClassName = TIdSSPINTLMAuthentication
end;
HJay
  • 193
  • 5
  • 13
  • 1
    1) try to follow [this question](https://stackoverflow.com/q/16230782/8041231). 2) yes, Indy components are [exception driven](https://stackoverflow.com/q/13950676/8041231). – Victoria Jun 22 '17 at 20:01
  • @Victoria: Thanks, however, the proxy stuff seems not to be relevant and the TIdSSPINTLMAuthentication is already automically recognized. I have no idea what to extract from that question which I read before I posted my question. – HJay Jun 22 '17 at 20:13
  • 1
    `TIdNTLMAuthentication` and `TIdSSPINTLMAuthentication` are largely untested (and I have no way of testing them myself, or I would), so there is no guarantee NTLM actually works correctly. If you don't want 401 raising an exception, you can enable the `hoNoProtocolErrorException` flag in the `TIdHTTP.HTTPOptions` property, or pass `401` in the optional `AIgnoreReplies` parameter of `TIdHTTP.Get()`. Also, if you include both `IdAuthenticationNTLM` and `IdAuthenticationSSPI` in your `uses` class, the last one listed will always be chosen for NTLM by default. Use one or the other, not both. – Remy Lebeau Jun 22 '17 at 22:35

0 Answers0