Поделиться через


Метод IHttpRequest::GetClientCertificate

Извлекает сертификат клиента, связанный с запросом.

Синтаксис

HRESULT GetClientCertificate(  
   OUT HTTP_SSL_CLIENT_CERT_INFO** ppClientCertInfo,  
   OUT BOOL* pfClientCertNegotiated  
);  

Параметры

ppClientCertInfo
[OUT] Указатель на структуру HTTP_SSL_CLIENT_CERT_INFO .

pfClientCertNegotiated
[OUT] true Значение , если сертификат клиента уже согласован; в противном случае — false. Дополнительные сведения см. в разделе «Примечания».

Возвращаемое значение

Объект HRESULT. Допустимые значения включают, но не ограничиваются, значения, приведенные в следующей таблице.

Значение Определение
S_OK Указывает, что ошибки не произошло, но не гарантирует, что сертификат найден. Дополнительные сведения см. в разделе «Примечания».
HRESULT_FROM_WIN32(ERROR_NOT_FOUND) Указывает, что сертификат клиента не найден. ERROR_NOT_FOUND определяется в Winerror.h.
ERROR_INVALID_PARAMETER Указывает, что ppClientCertInfo параметр или pfClientCertNegotiated имеет значение NULL.

Комментарии

Успешное выполнение HRESULT не гарантирует, что сертификат клиента найден. Разработчики также должны убедиться, что ppClientCertInfo значение не равно NULL.

Значение pfClientCertNegotiatedtrue не гарантирует, что ppClientCertInfo не равно NULL.

Разработчики могут использовать GetClientCertificate метод для получения сертификата клиента, связанного с текущим запросом. После вызова GetClientCertificate метода ppClientCertInfo параметр будет содержать указатель на структуру HTTP_SSL_CLIENT_CERT_INFO , которая будет содержать сертификат клиента, если он доступен, или NULL, если сертификат недоступен.

Для URL-адресов, для которых не требуется сертификат клиента, можно вызвать метод NegotiateClientCertificate перед вызовом GetClientCertificate , чтобы попытаться загрузить сертификат клиента вручную.

Пример

В следующем примере показано, как получить указатель на структуру HTTP_SSL_CLIENT_CERT_INFO путем реализации метода CHttpModule::OnBeginRequest .

void   checkForClientCert(IHttpContext*  pHttpContext)
{
   static long cnt;     
   // keep track of how many times we are called
   InterlockedIncrement (&cnt);  
   HRESULT hr = S_OK;
   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;
   }

   HTTP_SSL_CLIENT_CERT_INFO *pClientCertInfo=NULL;
   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) ||
      pClientCertInfo == NULL ){
         TRC_HR_MSG(hr, "Cert not found" );
         return;
   }
   if(FAILED(hr)){
      LOG_ERR_HR("GetClientCertificate", hr);
      return;
   }	

   // You must verify pClientCertInfo != NULL

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

REQUEST_NOTIFICATION_STATUS
CMyHttpModule::OnBeginRequest(
                              IHttpContext*       pHttpContext,
                              IHttpEventProvider* // pProvider  
                              )
{
   checkForClientCert(pHttpContext);
   return RQ_NOTIFICATION_CONTINUE;
}

Дополнительные сведения о создании и развертывании собственного модуля DLL см. в разделе Пошаговое руководство. Создание модуля HTTP Request-Level с помощью машинного кода.

При необходимости можно компилировать код с помощью соглашения о __stdcall (/Gz) вызовах вместо явного объявления соглашения о вызовах для каждой функции.

Требования

Тип Описание
клиент — IIS 7.0 в Windows Vista
— IIS 7.5 в Windows 7
— IIS 8.0 в Windows 8
— IIS 10.0 в Windows 10
Сервер — IIS 7.0 в Windows Server 2008
— IIS 7.5 в Windows Server 2008 R2
— IIS 8.0 в Windows Server 2012
— IIS 8.5 в Windows Server 2012 R2
— IIS 10.0 в Windows Server 2016
Продукт — 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
Заголовок Httpserv.h

См. также:

Интерфейс IHttpRequest
Метод IHttpRequest::NegotiateClientCertificate