整合式 Kerberos 驗證 (Native Client OLE DB Provider)
適用於: SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics Platform System (PDW)
此範例示範如何在 SQL Server Native Client 中使用 OLE DB 取得相互 Kerberos 驗證。 此範例適用於 SQL Server 2008 (10.0.x) 或更新版本。
如需 SPN 和 Kerberos 驗證的詳細資訊,請參閱 Client Connections 中的服務主體名稱 (SPN) 支援。
範例
您必須指定一個伺服器。 在.cpp檔案中,將 “MyServer” 變更為具有 SQL Server 2008 實例的計算機名稱(10.0.x) (或更新版本)。
您也必須指定一個客戶提供的 SPN。 在 .cpp 檔案中,將 "CPSPN" 變更為客戶提供的 SPN。
請確定您的 INCLUDE 環境變數包含包含 sqlncli.h 的目錄。 使用 ole32.lib oleaut32.lib 編譯。
// compile with: ole32.lib oleaut32.lib
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <tchar.h>
#include <sqlncli.h>
#define CHECKHR(stmt) \
do { \
hr = (stmt); \
if (FAILED(hr)) { \
printf("CHECK_HR " #stmt " failed at (%hs, %d), hr=0x%08X\r\n", __FILE__, __LINE__, hr); \
goto CleanUp; \
} \
} while(0)
#define CHECKVB(stmt) \
do { \
if ((stmt)!= VARIANT_TRUE) { \
printf("CHECK_VB " #stmt " failed at (%hs, %d)\r\n", __FILE__, __LINE__); \
goto CleanUp; \
} \
} while(0)
#define CHECKBOOL(stmt) \
do { \
if (!(stmt)) { \
printf("CHECK_BOOL " #stmt " failed at (%hs, %d)\r\n", __FILE__, __LINE__); \
goto CleanUp; \
} \
} while(0)
#define CHECKNULL(stmt) \
do { \
if ((stmt) == NULL) { \
printf("CHECK_NULL " #stmt " failed at (%hs, %d)\r\n", __FILE__, __LINE__); \
goto CleanUp; \
} \
} while(0)
#define SAFERELEASE(p) \
do { \
if ((p)!= NULL) { \
p->Release(); \
p = NULL; \
} \
} while(0)
#define SAFE_SYSFREESTRING(p) \
do { \
if ((p)!= NULL) { \
::SysFreeString(p); \
p = NULL; \
} \
} while(0)
int _tmain(int argc, _TCHAR* argv[]) {
HRESULT hr = S_OK;
IDBInitialize* pInitialize = NULL;
IDBProperties* pProperties = NULL;
DBPROPSET PropertySet[1];
DBPROP rgdbprop[1];
LPCWSTR lpwszProviderString = L"Server=MyServer;" // server with SQL Server 2008 (or later)
L"Trusted_Connection=Yes;"
L"ServerSPN=CP_SPN;"; // customer-provided SPN
DBPROPID rgdbPropID[2];
DBPROPIDSET rgdbPropIDSet[1];
ULONG cPropertySets;
DBPROPSET *prgPropertySets;
CHECKHR(CoInitialize(NULL));
CHECKHR(CoCreateInstance(CLSID_SQLNCLI11, NULL, CLSCTX_INPROC_SERVER, __uuidof(IDBProperties), reinterpret_cast<void **>(&pProperties)));
// set provider string
rgdbprop[0].dwPropertyID = DBPROP_INIT_PROVIDERSTRING;
rgdbprop[0].dwOptions = DBPROPOPTIONS_REQUIRED;
rgdbprop[0].colid = DB_NULLID;
VariantInit(&(rgdbprop[0].vValue));
V_VT(&(rgdbprop[0].vValue)) = VT_BSTR;
V_BSTR(&(rgdbprop[0].vValue)) = SysAllocString(lpwszProviderString);
// set the property to the property set
PropertySet[0].rgProperties = &rgdbprop[0];
PropertySet[0].cProperties = 1;
PropertySet[0].guidPropertySet = DBPROPSET_DBINIT;
// set properties and connect to server
CHECKHR(pProperties->SetProperties(1, PropertySet));
CHECKHR(pProperties->QueryInterface(__uuidof(pInitialize), (void **)&pInitialize));
CHECKHR(pInitialize->Initialize());
// get properties
rgdbPropID[0] = SSPROP_INTEGRATEDAUTHENTICATIONMETHOD;
rgdbPropID[1] = SSPROP_MUTUALLYAUTHENTICATED;
rgdbPropIDSet[0].rgPropertyIDs = &rgdbPropID[0];
rgdbPropIDSet[0].cPropertyIDs = 2;
rgdbPropIDSet[0].guidPropertySet = DBPROPSET_SQLSERVERDATASOURCEINFO;
CHECKHR(pProperties->GetProperties(1, rgdbPropIDSet, &cPropertySets, &prgPropertySets));
wprintf(L"Authentication method: %s\r\n", (LPWSTR)V_BSTR(&(prgPropertySets[0].rgProperties[0].vValue)));
wprintf(L"Mutually authenticated: %s\r\n", (VT_BOOL == V_VT(&(prgPropertySets[0].rgProperties[1].vValue)))?L"yes":L"no");
CleanUp:
SAFERELEASE(pProperties);
SAFERELEASE(pInitialize);
VariantClear(&(rgdbprop[0].vValue));
CoUninitialize();
}