Példa: SSPI-hitelesítési kódolás használata BITS használatával

A biztonsági támogatási szolgáltatói felület (SSPI) hitelesítési és háttérbeli intelligens átviteli szolgáltatás (BITS) metódusával lekérheti a hitelesítő adatokat egy felhasználótól, kódolhatja a hitelesítő adatokat, és beállíthatja a kódolt hitelesítő adatokat egy BITS átviteli feladatban. Kódolásra van szükség a hitelesítő adatok szerkezetének sztringekké alakításához, amelyek átadhatók egy BITS-átviteli feladatnak.

További információ az SSPI-hitelesítésről és -módszerekről: SSPI.

Az alábbi eljárás hitelesítő adatokat kér a felhasználótól az Egyeztetés biztonsági csomag használatával. A program létrehoz egy hitelesítési identitásstruktúrát, és feltölti a struktúrát a felhasználó felhasználónevét, tartományát és jelszavát jelképező kódolt sztringekkel. Ezután a program létrehoz egy BITS letöltési feladatot, és beállítja a kódolt felhasználónevet és jelszót a feladat hitelesítő adataiként. A program felszabadítja a hitelesítési identitás struktúráját, miután már nincs rá szükség.

Ez a példa a Példa: Common Classescímű cikkben definiált fejlécet és implementációt használja.

SSPI-hitelesítési kódolás használata BITS átviteli feladatokkal

  1. A COM-paraméterek inicializálása a CCoInitializer függvény meghívásával. További információ a CCoInitializer függvényről: Példa: Common Classes.
  2. Az IBackgroundCopyManager, IBackgroundCopyJob, IBackgroundCopyJob2 interfészek mutatóinak lekérése. Ez a példa a CComPtr osztály használatával kezeli a COM-felület mutatóit.
  3. Hozzon létre egy CREDUI_INFO struktúrát, amely információkat tartalmaz a SspiPromptForCredentials függvénypárbeszédpanel megjelenésének testreszabásához. Ezután kérje meg a hitelesítő adatokat a felhasználótól. További információ: SspiPromptForCredentials függvény.
  4. A hitelesítő adatok struktúráját sztringekként kódolhatja, amelyek átadhatók egy BITS-átviteli feladatnak a SspiEncodeAuthIdentityAsStrings függvény használatával.
  5. Készítsen elő egy BG_AUTH_CREDENTIALS struktúrát.
  6. A COM-folyamat biztonságának inicializálása CoInitializeSecuritymeghívásával. A BITS legalább a megszemélyesítés megszemélyesítési szintjét igényli. A BITS E_ACCESSDENIED meghiúsul, ha a megfelelő megszemélyesítési szint nincs beállítva.
  7. Szerezze be a kezdeti lokátort a BITS-be a CoCreateInstance függvény meghívásával.
  8. Hozzon létre egy BITS-átviteli feladatot az IBackgroundCopyManager::CreateJob metódus meghívásával.
  9. Kérje le az IBackgroundCopyJob2 felület azonosítót, és hívja meg az IBackgroundCopyJob::QueryInterface metódust.
  10. Töltse ki a BG_AUTH_CREDENTIALS struktúrát a kódolt felhasználónévvel és jelszósztringekkel, és állítsa a hitelesítési sémát Egyeztetés (BG_AUTH_SCHEME_NEGOTIATE) értékre.
  11. Az IBackgroundCopyJob2 mutatóval kérheti a BITS-et. Ez a program a IBackgroundCopyJob2::SetCredentials metódust használja a BITS átviteli feladat hitelesítő adatainak beállításához.
  12. Fájlok hozzáadása, tulajdonságok módosítása vagy a BITS átviteli feladat folytatása.
  13. A BITS átviteli feladat befejezése után távolítsa el a feladatot az üzenetsorból IBackgroundCopyJob::Completemeghívásával.
  14. Végül szabadítsd fel a hitelesítési identitás struktúráját a SspiFreeAuthIdentity függvény meghívásával.

Az alábbi példakód bemutatja, hogyan használható az SSPI-hitelesítés kódolása BITS átviteli feladatokkal.

#define SECURITY_WIN32
#define _SEC_WINNT_AUTH_TYPES

#include <windows.h>
#include <ntsecapi.h>
#include <bits.h>
#include <sspi.h>
#include <wincred.h>
#include <iostream>
#include <atlbase.h>
#include "CommonCode.h"

void PromptForCredentials(PWSTR pwTargetName)
{
    HRESULT hr;
    
    // If CoInitializeEx fails, the exception is unhandled and the program terminates
    CCoInitializer coInitializer(COINIT_APARTMENTTHREADED);
    
    CComPtr<IBackgroundCopyManager> pQueueMgr;
    CComPtr<IBackgroundCopyJob> pJob;
    CComPtr<IBackgroundCopyJob2> pJob2;

    PSEC_WINNT_AUTH_IDENTITY_OPAQUE pAuthIdentityEx2 = NULL;
    DWORD dwFlags = 0;
    BOOL fSave = FALSE;
    BOOL bReturn = TRUE;

    CREDUI_INFO creduiInfo = { 0 };
    creduiInfo.cbSize = sizeof(creduiInfo);
    // Change the message text and caption to the actual text for your dialog.
    creduiInfo.pszMessageText = pwTargetName;
    creduiInfo.pszCaptionText = L"SSPIPFC title for the dialog box";

    try {
        // Prompt for credentials from user using Negotiate security package.
        DWORD dwRet = SspiPromptForCredentials(
            pwTargetName,
            &creduiInfo,
            0,
            L"Negotiate", 
            NULL,
            &pAuthIdentityEx2,
            &fSave,
            dwFlags
            );

        if (SEC_E_OK != dwRet) 
        {
            // Prompt for credentials failed.
            throw MyException(dwRet, L"SspiPromptForCredentials");
        }

        if (NULL != pAuthIdentityEx2) 
        {
            GUID guidJob;
            BG_AUTH_CREDENTIALS authCreds;

            PCWSTR pwUserName = NULL;
            PCWSTR pwDomainName = NULL;
            PCWSTR pwPassword = NULL;

            // Encode credential structure as strings that can
            // be passed to a BITS job.
            SECURITY_STATUS secStatus = SspiEncodeAuthIdentityAsStrings(
                pAuthIdentityEx2,
                &pwUserName,
                &pwDomainName,
                &pwPassword
                );

            if(SEC_E_OK != secStatus) 
            {
                // Encode authentication identity as strings.
                throw MyException(secStatus, L"SspiEncodeAuthIdentityAsStrings");   
            }

            // Show the encoded user name and domain name.
            wprintf(
                L"User Name: %s\nDomain Name: %s",
                pwUserName,
                pwDomainName
                );

            //The impersonation level must be at least RPC_C_IMP_LEVEL_IMPERSONATE.
            HRESULT hr = CoInitializeSecurity(
                NULL,
                -1,
                NULL,
                NULL,
                RPC_C_AUTHN_LEVEL_CONNECT,
                RPC_C_IMP_LEVEL_IMPERSONATE,
                NULL,
                EOAC_DYNAMIC_CLOAKING,
                0
                );
            
            if (FAILED(hr))
            {
                throw MyException(hr, L"CoInitializeSecurity");
            }

            // Connect to BITS.
            hr = CoCreateInstance(__uuidof(BackgroundCopyManager), NULL,
                CLSCTX_LOCAL_SERVER,
                __uuidof(IBackgroundCopyManager),
                (void**) &pQueueMgr);

            if (FAILED(hr))
            {
                // Failed to connect.
                throw MyException(hr, L"CoCreateInstance");
            }

            // Create a job.
            hr = pQueueMgr->CreateJob(
                L"EncodeSample", 
                BG_JOB_TYPE_DOWNLOAD, 
                &guidJob, 
                &pJob
                );

            if(FAILED(hr))
            {   
                // Failed to create a BITS job.
                throw MyException(hr, L"CreateJob");
            }

            // Get IBackgroundCopyJob2 interface.
            hr = pJob->QueryInterface(__uuidof(IBackgroundCopyJob2), (void**)&pJob2);
            if (FAILED(hr)) 
            {
                // Failed to get a reference to the IBackgroundCopyJob2 interface.
                throw MyException(hr, L"QueryInterface(IBackgroundCopyJob2)");
            }

            // Create a BITS authentication structure from the encoded strings.
            authCreds.Target = BG_AUTH_TARGET_SERVER;
            authCreds.Scheme = BG_AUTH_SCHEME_NEGOTIATE;
            authCreds.Credentials.Basic.UserName = (LPWSTR)pwUserName;
            authCreds.Credentials.Basic.Password = (LPWSTR)pwPassword;

            // Set the credentials for the job.
            hr = pJob2->SetCredentials(&authCreds);
            if (FAILED(hr)) 
            {
                // Failed to set credentials.
                throw MyException(hr, L"SetCredentials");
            }

            // Modify the job's property values.
            // Add files to the job.
            // Activate (resume) the job in the transfer queue.

            // Remove the job from the transfer queue.
            hr = pJob->Complete();
            if (FAILED(hr)) 
            {
                // Failed to complete the job.
                throw MyException(hr, L"Complete");
            }
        }
    }
    catch(std::bad_alloc &)
    {
        wprintf(L"Memory allocation failed");
        if (pJob != NULL)
        {
            pJob->Cancel();
        }
    }
    catch(MyException &ex)
    {
        wprintf(L"Error %x occurred during operation", ex.Error);
        if (pJob != NULL)
        {
            pJob->Cancel();
        }
    }

    // Free the auth identity structure.
    if (NULL != pAuthIdentityEx2)
    {
        SspiFreeAuthIdentity(pAuthIdentityEx2);
        pAuthIdentityEx2 = NULL;
    }

    return;
}

void _cdecl _tmain(int argc, LPWSTR* argv)
{
    PromptForCredentials(L"Target");
}

SSPI-

IBackgroundCopyManager

IBackgroundCopyJob

IBackgroundCopyJob2

Példa: Gyakori osztályok