共用方式為


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 表示 ppClientCertInfopfClientCertNegotiated 參數為 Null。

備註

成功的 HRESULT 不保證找到用戶端憑證。 開發人員也必須確認 ppClientCertInfo 不是 Null。

pfClientCertNegotiated的值 true 不保證 ppClientCertInfo 不是 Null。

開發人員可以使用 GetClientCertificate 方法來擷取與目前要求相關聯的用戶端憑證。 呼叫 GetClientCertificate 方法之後, ppClientCertInfo 參數會包含結構的指標 HTTP_SSL_CLIENT_CERT_INFO ,如果有可用的憑證,則會包含用戶端憑證;如果沒有可用的憑證,則會包含用戶端憑證。

對於不需要用戶端憑證的 URL,您可以在呼叫 GetClientCertificate 嘗試手動載入用戶端憑證之前呼叫NegotiateClientCertificate方法。

範例

下列範例示範如何實作CHttpModule::OnBeginRequest方法,以取得HTTP_SSL_CLIENT_CERT_INFO結構的指標。

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 模組的詳細資訊,請參閱逐步解說 :使用機器碼建立Request-Level HTTP 模組

您可以選擇性地使用呼叫慣例編譯器代碼, __stdcall (/Gz) 而不是明確宣告每個函式的呼叫慣例。

規格需求

類型 描述
Client - Windows Vista 上的 IIS 7.0
- Windows 7 上的 IIS 7.5
- Windows 8 上的 IIS 8.0
- Windows 10上的 IIS 10.0
伺服器 - Windows Server 2008 上的 IIS 7.0
- Windows Server 2008 R2 上的 IIS 7.5
- Windows Server 2012 上的 IIS 8.0
- Windows Server 2012 R2 上的 IIS 8.5
- Windows Server 2016上的 IIS 10.0
產品 - 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 方法