Integrierte Kerberos-Authentifizierung (OLE DB)

In diesem Beispiel wird gezeigt, wie die gegenseitige Kerberos-Authentifizierung mit OLE DB in SQL Server Native Client abgerufen wird. Dieses Beispiel funktioniert mit SQL Server 2008 oder höher.

Weitere Informationen über SPNs und Kerberos-Authentifizierung finden Sie unter Unterstützung von Dienstprinzipalnamen (SPN) in Clientverbindungen.

Beispiel

Sie müssen einen Server angeben. Ändern Sie in der CPP-Datei "MyServer" in den Namen eines Computers, auf dem sich eine Instanz von SQL Server 2008 (oder höher) befindet.

Sie müssen auch einen vom Kunden bereitgestellten SPN angeben. Ändern Sie in der CPP-Datei "CPSPN" in einen vom Kunden bereitgestellten SPN.

Stellen Sie sicher, dass die INCLUDE-Umgebungsvariable das Verzeichnis einschließt, das sqlncli.h enthält. Kompilieren Sie mit ole32.lib und 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();
}