통합 Kerberos 인증(OLE DB)
적용 대상: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)
이 샘플에서는 OLE DB Driver for SQL Server에서 OLE DB를 사용하여 상호 Kerberos 인증을 가져오는 방법을 보여 줍니다. 이 샘플은 SQL Server 2008(10.0.x) 이상 버전에서 작동합니다.
SPN 및 Kerberos 인증에 대한 자세한 내용은 클라이언트 연결의 SPN(서비스 보안 주체 이름) 지원을 참조하세요.
예제
서버를 지정해야 합니다. .cpp 파일에서 "MyServer"를 SQL Server 2008(10.0.x) 이상 버전의 인스턴스가 있는 컴퓨터 이름으로 변경합니다.
고객이 제공한 SPN도 지정해야 합니다. .cpp 파일에서 "CPSPN"을 고객이 제공한 SPN으로 변경합니다.
INCLUDE 환경 변수에 msoledbsql.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 <msoledbsql.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 SAFERELEASE(p) \
do\
{\
if ((p) != nullptr)\
{\
p->Release(); \
p = nullptr; \
} \
} while (0)
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
IDBInitialize* pInitialize = nullptr;
IDBProperties* pProperties = nullptr;
DBPROP rgDBProp[1] = {};
LPCWSTR lpwszProviderString = L"Server=MyServer;" // server with SQL Server 2008 (or later)
L"Trusted_Connection=Yes;"
L"Encrypt=Mandatory;"
L"ServerSPN=CP_SPN;"; // customer-provided SPN
DBPROPSET* prgPropertySets = nullptr;
ULONG cPropertySets = 0;
CHECKHR(CoInitialize(nullptr));
CHECKHR(CoCreateInstance(CLSID_MSOLEDBSQL, nullptr, 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
DBPROPSET PropertySet[1] = {};
PropertySet[0].rgProperties = &rgDBProp[0];
PropertySet[0].cProperties = 1;
PropertySet[0].guidPropertySet = DBPROPSET_DBINIT;
// set properties and connect to server
CHECKHR(pProperties->SetProperties(sizeof(PropertySet)/sizeof(DBPROPSET), PropertySet));
}
CHECKHR(pProperties->QueryInterface<IDBInitialize>(&pInitialize));
CHECKHR(pInitialize->Initialize());
{ // get properties
DBPROPIDSET rgDBPropIDSet[1] = {};
DBPROPID rgDBPropID[2] = {};
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", V_BSTR(&(prgPropertySets[0].rgProperties[0].vValue)));
wprintf(L"Mutually authenticated: %s\r\n",
(V_BOOL(&(prgPropertySets[0].rgProperties[1].vValue)) == VARIANT_TRUE) ? L"yes" : L"no");
CleanUp:
SAFERELEASE(pProperties);
SAFERELEASE(pInitialize);
if (prgPropertySets)
{
for (ULONG iPropSet = 0; iPropSet < cPropertySets; ++iPropSet)
{
for (ULONG iProp = 0; iProp < prgPropertySets[iPropSet].cProperties; ++iProp)
{
VariantClear(&prgPropertySets[iPropSet].rgProperties[iProp].vValue);
}
}
}
VariantClear(&(rgDBProp[0].vValue));
CoUninitialize();
}