Ken Davis
Ken Davis

Reputation: 67

Authentication fails to TEMSClientAPI when in 64 bit in Rad Server 10.3.1

We use Embarcadero RAD Server for a web application. It has been in production for a couple years and is currently compiled in Delphi 10.3.1.

The server was originally configured for 32bit and we recently compiled it in 64bit and tried to upgrade the server. It is running in Apache on Windows Server.

Mostly things went ok with the execption of authenticating to Rest.Backend.EMSApi.TEMSClientAPI. When compiled in 64bit, we received the following error:

enter image description here

when making this call

LEMSClientAPI.QueryUserName(LAgency + '.' + LUserName, LUser)

Researching that error suggests a TLS mismatch somewhere, however, the error is just talking to a delphi component. I am at a complete loss as to how to start troubleshooting this issue. When running the code in the EMSDevServer internally, authentication worked just fine (however none of it was encrypted). I believe the apache server is configured correctly because if the user was already authenticated, the user could access endpoints other than the authentication endpoints.

Does anyone have any ideas or questions? My code is listed below:

procedure TCustomLogonResource.PostLogin(const AContext: TEndpointContext;
  const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
var
  LEMSAPI       : TEMSInternalAPI;
  LEMSClientAPI : Rest.Backend.EMSApi.TEMSClientAPI;
  LResponse     : IEMSResourceResponseContent;
  LValue        : TJSONValue;
  LUserName     : string;
  LPassword     : string;
  ObjCons       : TJSONObject;
  ObjID         : String;
  LUser         : REST.Backend.EMSApi.TEMSClientAPI.TUser;
  LLogin        : REST.Backend.EMSApi.TEMSClientAPI.TLogin;
  LAgency       : String;
  myJSON        : TJSONObject;
  myUsers       : TArray<string>;
  ARec          : TEMSClientAPI.TUpdatedAt;
  AInfo         : TEMSClientAPI.TConnectionInfo;
  LEID          : String;
  LFullName     : String;
  LProfile      : String;
  LModuleName   : String;
  LToken        : String;
  iPos          : Integer;
  LOTP          : String;
  LOTU          : String;
  sList: TStringList;
  tempJSONArray: TJSONArray;
  tempJSONValue: TJSONValue;
  tempJSONObject: TJSONObject;
  tempStream: TStream;
  i: Integer;
  slDiag: TStringList;
begin
  ObjCons := nil;
  tempJSONArray := nil;
  slDiag := nil;
  LModuleName := '';
  LToken  := '';
  iPos := 0;
  LOTP := '';
  LOTU := '';
  myJSON := TJSONObject.Create;
  // Create in-process EMS API
  LEMSAPI := TEMSInternalAPI.Create(AContext);
  AInfo.BaseURL := 'https://www.notmyrealurl.com/api/';
  AInfo.MasterSecret := '**************';
  LEMSClientAPI := Rest.Backend.EMSApi.TEMSClientAPI.Create();
  LEMSClientAPI.ConnectionInfo := AInfo;
  LEMSClientAPI.Authentication := REST.Backend.EMSApi.TEMSClientAPI.TAuthentication.MasterSecret;
  try
    Try
      // Extract credentials from request
      if not (ARequest.Body.TryGetValue(LValue) and
        LValue.TryGetValue<string>(TEMSInternalAPI.TJSONNames.UserName, LUserName) and
        LValue.TryGetValue<string>(TEMSInternalAPI.TJSONNames.Password, LPassword))
      then
        AResponse.RaiseBadRequest('', 'Missing credentials')
      LAgency := ANSILowerCase(Trim(LeftStr(LUserName, Pos('.', LUserName) - 1)));

      ARequest.Body.TryGetObject(tempJSONObject);
      tempJSONObject.TryGetValue<string>('module_name', LModuleName);
      tempJSONObject.TryGetValue<string>('otu', LOTU);
      tempJSONObject.TryGetValue<string>('otp', LOTP);

      // if the username are valid user in the Agency's Users Table in their Agency DB, then proceed
      if ValidateCredentials('', LPassword, LModuleName, LOTU, LOTP, LUserName, LEID, LFullName, LProfile, LToken) then
      begin
        // if not using OTP/OTU
        if LOTU = '' then
        begin
          sPlace := 'Before LEMSClientAPI';

          // if the user doesn't exist in the EMS database, we need to add him
          if not LEMSClientAPI.QueryUserName(LAgency + '.' + LUserName, LUser) then
          begin
            LEMSClientAPI.SignupUser(LAgency + '.' + LUserName,LPassword,nil,LLogin);
          end
          // if the user already exists in the EMS database
          else
          begin
            ObjId := LUser.UserID;
            ObjCons := TJSONObject.Create;
            ObjCons.AddPair('password', LPassword);
            LEMSClientAPI.UpdateUser(LUser,ObjCons,ARec);
          end;
        end; // end if not using OTU/OTP

        if LToken = '' then
        begin
          LResponse := LEMSAPI.LoginUser(LAgency + '.' + LUserName, LPassword);
          LEMSClientAPI.LoginUser(LAgency + '.' + LUserName,LPassword, LLogin);
          UpdateSessionToken(LAgency + '.' + LUserName,LLogin.AuthToken);
        end;

        iPos := Pos('.', LUserName);
        myJSON.AddPair('agency_key',LAgency);
        myJSON.AddPair('user',LUserName);
        myJSON.AddPair('username',LAgency + '.' + LUserName);
        myJSON.AddPair('eid',LEID);
        myJSON.AddPair('fullname',Trim(LFullName));
        myJSON.AddPair('profile',Trim(LProfile));
        myJSON.AddPair('sessionToken',IfThen(LToken = '', LLogin.AuthToken, LToken));
        myJSON.AddPair('module_name ',LModuleName);
        
        AResponse.StatusCode := 200;
      end
      else
      begin
        myJSON.AddPair('module_name',LModuleName);
        myJSON.AddPair('Authentication Failed','Invalid username or password');

        AResponse.StatusCode := 400;
      end;
    except
      on e: exception do
      begin
        raise Exception.Create(e.Message);
      end;
    end;
  finally
    AResponse.Body.SetValue(myJSON,true);
    LEMSAPI.Free;
    ObjCons.Free;
    slDiag.Free;
  end;
end;

Upvotes: 0

Views: 82

Answers (0)

Related Questions