IHttpRequest::NegotiateClientCertificate Method

IIS 7.0
 

Initiates client certificate negotiation with a Web client.

HRESULT NegotiateClientCertificate(  
   IN BOOL fAsync,  
   OUT BOOL* pfCompletionPending = NULL  
)   

Parameters

fAsync
[IN] true to specify that negotiation should occur asynchronously; otherwise, false.

pfCompletionPending
[OUT] true to specify that an asynchronous completion is pending; otherwise, false.

An HRESULT. Possible values include, but are not limited to, those in the following table.

ValueDefinition
S_OKIndicates that the operation was successful.
E_FAILIndicates that the operation failed.

Developers can use the NegotiateClientCertificate method to manually initiate client certificate negotiation with a Web client, even if IIS is configured to accept or ignore client certificates. NegotiateClientCertificate supports both synchronous and asynchronous operation by specifying the appropriate setting in the fAsync parameter. When your module calls NegotiateClientCertificate asynchronously, the module must return processing to the integrated request-processing pipeline immediately after calling the method if the pfCompletionPending value indicates that an asynchronous completion is pending.

The following example demonstrates how to call NegotiateClientCertificate method.

REQUEST_NOTIFICATION_STATUS
CMyHttpModule::OnBeginRequest(
                              IHttpContext*       pHttpContext,
                              IHttpEventProvider* // pProvider  
                              )
{
   static long cnt;     
   InterlockedIncrement (&cnt);  // keep track of how many times we are called
   HRESULT hr = E_FAIL;
   IHttpRequest *pIHTTPR = pHttpContext->GetRequest();

   HTTP_REQUEST * pRawRequest = pIHTTPR->GetRawHttpRequest();
   HTTP_COOKED_URL hcu = pRawRequest->CookedUrl;

   // Send URL and count to the trace window
   TRC_MSGW_FULL( L"cnt = " << cnt << " URI: " << hcu.pFullUrl );

   // return immediately if not a HTTPS request
   if ( pRawRequest->pSslInfo == NULL ){
      TRC_MSG( "connection is not using SSL");
      return RQ_NOTIFICATION_CONTINUE;
   }

   // change the bForce flag to test behavior of forcing load of client cert
   bool bForce=true;
   if(bForce){
      TRC_MSG("forcing load of client cert");
      hr = pIHTTPR->NegotiateClientCertificate(FALSE);
      if(FAILED(hr)){
         LOG_ERR_HR(hr, "NegotiateClientCertificate : HR = ");
         return RQ_NOTIFICATION_CONTINUE;
      }
   }
   else
      TRC_MSG("Not forcing load of client cert");

   HTTP_SSL_CLIENT_CERT_INFO *pClientCertInfo;
   BOOL fccNeg;
   hr = pIHTTPR->GetClientCertificate(&pClientCertInfo,&fccNeg);

   // If you have not selected "Require Client Certificates" or called
   // NegotiateClientCertificate(), you  may get  ERROR_NOT_FOUND 

   if( hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND)){
      TRC_MSG( "Cert not found" );
      return RQ_NOTIFICATION_CONTINUE;
   }
   if(FAILED(hr)){
      LOG_ERR_HR("GetClientCertificate", hr);
      return RQ_NOTIFICATION_CONTINUE;
   }	

   if( fccNeg && pClientCertInfo != NULL){
      ULONG uSiz = pClientCertInfo->CertEncodedSize;
      TRC_MSG( "cert size: " << uSiz  \
         << " Previously negotiated " << fccNeg );
      unsigned long certCrc = genCRC(pClientCertInfo->pCertEncoded,
         pClientCertInfo->CertEncodedSize);
      TRC_MSG( "cert crc: " << certCrc );
   }
   else
      TRC_MSG( "No client certificate.");

   return RQ_NOTIFICATION_CONTINUE;
}

For more information on how to create and deploy a native DLL module, see Walkthrough: Creating a Request-Level HTTP Module By Using Native Code.

You can optionally compile the code by using the __stdcall (/Gz) calling convention instead of explicitly declaring the calling convention for each function.

TypeDescription
Client- IIS 7.0 on Windows Vista
- IIS 7.5 on Windows 7
- IIS 8.0 on Windows 8
- IIS 10.0 on Windows 10
Server- IIS 7.0 on Windows Server 2008
- IIS 7.5 on Windows Server 2008 R2
- IIS 8.0 on Windows Server 2012
- IIS 8.5 on Windows Server 2012 R2
- IIS 10.0 on Windows Server 2016 Technical Preview
Product- IIS 7.0, IIS 7.5, IIS 8.0, IIS 8.5, IIS 10.0
- IIS Express 7.5, IIS Express 8.0, IIS Express 10.0
HeaderHttpserv.h

IHttpRequest Interface
IHttpRequest::GetClientCertificate Method

Show: