title: DelphiXE8 and WSDL, disable authentication via Smart Card Reader
body: <p>With Delphi XE8 I imported a WSDL and use the HTTPRIO component
  For use authentication:</p>
  
  <pre><code>property HTTPRIO:
    HTTPWebNode -&gt;
      ClientCertificate -&gt;  CertName = ServiceSSL.cer
      InvokeOptions [soIgnoreInvalidCerts,soPickFirstClientCertificate]
   Event HTTPRIO
      HTTPWebNode -&gt; OnBeforePost = HTTPRIO1HTTPWebNode1BeforePost
  
  
  procedure HTTPRIO1HTTPWebNode1BeforePost(const HTTPReqResp: THTTPReqResp;
    Data: Pointer);
  var
   auth: String;
   FUserName, FPassword : string;
  begin
   FUserName:=UtenteTS;
   FPassword:=PassTS;
   auth := 'Authorization: Basic ' + TNetEncoding.Base64.Encode(FUserName + ':' + FPassword);
   HttpAddRequestHeaders(Data, PChar(auth), Length(auth), HTTP_ADDREQ_FLAG_ADD);
  end;
  </code></pre>
  
  <p>Works well.</p>
  
  <p>The problem is:
  when a Smart Card Reader with a digital signature card is inserted in the PC,
  during authentication it communicates with the smart card, opening a PIN request window.</p>
  
  <p><a href="https://i.stack.imgur.com/puJ7E.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/puJ7E.jpg" alt="enter image description here"></a></p>
  
  <p>I don't want this, i want to prioritize authentication through HTTPRIO1HTTPWebNode1BeforePost !</p>
  
  <p>Note:</p>
  
  <p>Run debug, HTTPRIO1HTTPWebNode1BeforePost, it is processed and then communication with the 
  smart card is started.
  How can I disable Smart Card Reader reading?</p>
  
  <p>The card with the digital signature I need connected to the PC because my program has to digitally sign documents.</p>
  
  <h2>I add details.</h2>
  
  <p>I noticed that after the call HTTPRIO1HTTPWebNode1BeforePost</p>
  
  <p>this code is executed twice</p>
  
  <pre><code> { line 1151 of soap.SOAPHTTPtrans.pas  Posting Data Event }
        if Assigned(FOnPostingData) then
          FOnPostingData(DatStr.Size, BuffSize);
  
        RetVal := ERROR_SUCCESS;
  {$IFDEF UNICODE}
        HttpSendRequest(Request, nil, 0,
                        DatStr.Bytes, DatStr.Size);
  {$ELSE}
        HttpSendRequest(Request, nil, 0,
                        @DatStr.DataString[1],
                        Length(DatStr.DataString));
  {$ENDIF}
        RetVal := HandleWinInetError(GetLastError, Request, True);
  
        case RetVal of
          ERROR_SUCCESS: break;
          ERROR_CANCELLED: System.SysUtils.Abort;
          ERROR_INTERNET_FORCE_RETRY: {Retry the operation};
        end;
  </code></pre>
  
  <p>The first RetVal pass has value 12032 = ERROR_INTERNET_FORCE_RETRY: {Retry the operation};</p>
  
  <p>the second step HttpSendRequest(Request, nil, 0, DatStr.Bytes, DatStr.Size); starts the smart card reader and opens the message login window which requests the PIN of the digit signature entered in the reader.  RetVal = 0</p>
  
  <p>I tried to use InternetSetOption(Data, INTERNET_FLAG_NO_AUTH, ????, ????) but I do not know how I can do it.</p>
  
  <p>I don't want the login message box to open, request smart card PIN. How can I do? </p>
  
  <hr>
  
  <h2><strong>update to my request</strong></h2>
  
  <p>after reading this: I tried this:<a href="https://stackoverflow.com/questions/8185923/delphi-soap-https-authentication-failure-pops-up-a-dialog-box">post</a> "Replace WinINet by WinHTTP component. Both have very close APIs, and the 2nd does not create any UI interaction, but will return error codes, just like any other API. The UI part of WinINet may be a good idea for some software, but it sounds like if does not fit your needs."</p>
  
  <p>How can I use winHttp with HttpRio? I tried:</p>
  
  <pre><code>uses winHTTP;
  ...
  procedure HTTPRIOHTTPWebNode1BeforePost(const HTTPReqResp: THTTPReqResp; Data: Pointer);
  
  auth := 'Authorization: Basic ' + TNetEncoding.Base64.Encode(FUserName + ':' + FPassword);
  
  if not WinHttpAddRequestHeaders(Data, PChar(auth), Length(auth), WinHTTP_ADDREQ_FLAG_ADD) then ShowMessage('demat WinHttpAddRequestHeaders:  ' + SysErrorMessage(GetLastError()));
  </code></pre>
  
  <p>if I use HttpAddRequestHeaders (in winInet.dll) it works: </p>
  
  <pre><code>HttpAddRequestHeaders(Data, PChar(auth), Length(auth), HTTP_ADDREQ_FLAG_ADD)
  </code></pre>
  
  <p>if I use WinHttpAddRequestHeaders (in winhttp.dll) it NOT works, and I receive error: invalid handle.:</p>
  
  <p>Handle is Data type Point.</p>
  
  <p>in post <a href="https://docs.microsoft.com/it-it/windows/win32/winhttp/hinternet-handles-in-winhttp" rel="nofollow noreferrer">About HINTERNET Handles</a>
  "Microsoft Win32 Internet (WinInet) functions also use HINTERNET handles. However, the handles used in WinInet functions cannot be interchanged with the handles used in WinHTTP functions. For more information about WinInet, see About WinINet."</p>
  
  <p>So I can't use WinHttpAddRequestHeaders with Httprio. I am sorry.</p>
  
  <p>"  WinHttpAddRequestHeaders(Data, PChar(auth), Length(auth), WinHTTP_ADDREQ_FLAG_ADD)
  I want to try using winHttp with HttpRio instead of winInet. As I read, using winHttp, I will not receive the windows security window (PIN request). I don't know how to use winHttp with HttpRio. " You can help me?</p>