擷取與要求相關聯的用戶端憑證。
語法
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。
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 |