Delphi Internal Authentication

I am using the WinINet library to connect to a website.

Using Internet Explorer (Win10), it works and shows me a message to select the certificate to use.

This is the delphi code I call:

FUNCTION TRAD.lastOrganization(): Integer; VAR js:TlkJSONobject; ws: TlkJSONstring; url, resp: String; count,statusCodeLen, bodyCodeLen: Cardinal; header,tmp: String; buffer, body: String; statusCode: ARRAY [0 .. 1024] OF Char; bodyCode: ARRAY [0 .. 1024] OF Char; UrlHandle: HINTERNET; BEGIN buffer := '00000000000000000000'; url := contextUrl + '/rest/organization/count'; UrlHandle := InternetOpenUrl(NetHandle, PChar(url), nil, 0, INTERNET_FLAG_RELOAD, 0); IF NOT ASSIGNED(UrlHandle) THEN SHOWMESSAGE('Unable to read the amount of Organization using the URL ' + url + ': ' + SysErrorMessage(GetLastError)); statusCodeLen := Length(statusCode); bodyCodeLen := Length(bodyCode); count := 0; IF HttpQueryInfo(UrlHandle, HTTP_QUERY_STATUS_CODE, @statusCode[0], statusCodeLen, count) THEN BEGIN buffer := statusCode; IF buffer <> '200' THEN BEGIN ShowMessage('While read amount of Organization I got a status code ' + buffer + ' but 200 was expected.'); EXIT; END; END; count := 0; body := ''; REPEAT FillChar(bodyCode, bodyCodeLen, 0); IF NOT InternetReadFile(UrlHandle, @bodyCode[0], bodyCodeLen, count) THEN BEGIN ShowMessage('Problem on reading from response stream while read the amount of Organization using the URL ' + url + '.'); EXIT; END; IF count > 0 THEN BEGIN tmp := bodyCode; body := body + LeftStr(tmp, count); END; UNTIL count = 0; InternetCloseHandle(UrlHandle); Result := strtoint(body); END; 

If I call the method, I get this message:

enter image description here

Buuut using Edge-Browser, I have to specify a certificate, and it works fine.

enter image description here

Question

How to specify a certificate?

Edit (new information):

If I changed the code to

 FUNCTION TRAD.lastOrganization(): Integer; VAR js:TlkJSONobject; ws: TlkJSONstring; url, resp: String; count,statusCodeLen, bodyCodeLen: Cardinal; header,tmp: String; buffer, body: String; statusCode: ARRAY [0 .. 1024] OF Char; bodyCode: ARRAY [0 .. 1024] OF Char; UrlHandle: HINTERNET; BEGIN buffer := '00000000000000000000'; url := contextUrl + '/rest/organization/count'; UrlHandle := InternetOpenUrl(NetHandle, PChar(url), nil, 0, INTERNET_FLAG_RELOAD, 0); IF NOT ASSIGNED(UrlHandle) THEN raiseLastOSError(); 

He shows: enter image description here

+5
source share
1 answer

Using WinHTTP (you can do the same with WinInetHTTP), you can install such a certificate through ActiveX:

 // Instantiate a WinHttpRequest object. var HttpReq = new ActiveXObject("WinHttp.WinHttpRequest.5.1"); // Open an HTTP connection. HttpReq.Open("GET", "https://www.fabrikam.com/", false); // Select a client certificate. HttpReq.SetClientCertificate( "LOCAL_MACHINE\\Personal\\My Middle-Tier Certificate"); // Send the HTTP Request. HttpReq.Send(); 

So easy with ActiveX, but that’s not exactly what you want (I gave you an example to illustrate). Thus, using the Windows API, WinHTTP allows you to select and send a certificate from a local certificate store. The following code example shows how to open the certificate store and find the certificate by subject name after the ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED error was returned.

 if( !WinHttpReceiveResponse( hRequest, NULL ) ) { if( GetLastError( ) == ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED ) { //MY is the store the certificate is in. hMyStore = CertOpenSystemStore( 0, TEXT("MY") ); if( hMyStore ) { pCertContext = CertFindCertificateInStore( hMyStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, (LPVOID) szCertName, //Subject string in the certificate. NULL ); if( pCertContext ) { WinHttpSetOption( hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, (LPVOID) pCertContext, sizeof(CERT_CONTEXT) ); CertFreeCertificateContext( pCertContext ); } CertCloseStore( hMyStore, 0 ); // NOTE: Application should now resend the request. } } } 
0
source

Source: https://habr.com/ru/post/1276046/


All Articles