Udostępnij przez


Przykład: dodawanie tokenu pomocnika do zadania transferu usługi BITS

Zadanie transferu usługi inteligentnego transferu w tle (BITS) można skonfigurować przy użyciu dodatkowego tokenu zabezpieczającego. Zadanie transferu usługi BITS używa tego tokenu pomocniczego do uwierzytelniania i uzyskiwania dostępu do zasobów.

Aby uzyskać więcej informacji, zobacz tokeny pomocnika dla zadań transferu usługi BITS.

Poniższa procedura tworzy zadanie transferu usługi BITS w kontekście użytkownika lokalnego, pobiera poświadczenia drugiego użytkownika, tworzy token pomocnika z tymi poświadczeniami, a następnie ustawia token pomocnika w zadaniu transferu usługi BITS.

W tym przykładzie użyto nagłówka i implementacji zdefiniowanej w Przykład: Typowe klasy.

Aby dodać token pomocnika do zadania transferu usługi BITS

  1. Zainicjuj parametry MODELU COM, wywołując funkcję CCoInitializer. Aby uzyskać więcej informacji na temat funkcji CCoInitializer, zobacz Example: Common Classes.

  2. Pobierz wskaźnik do interfejsu IBackgroundCopyJob. W tym przykładzie użyto klasy CComPtr do zarządzania wskaźnikami interfejsu COM.

  3. Inicjowanie zabezpieczeń procesu COM przez wywołanie CoInitializeSecurity. Usługa BITS wymaga co najmniej poziomu personifikacji personifikacji. Usługa BITS kończy się niepowodzeniem z E_ACCESSDENIED, jeśli nie ustawiono poprawnego poziomu personifikacji.

  4. Pobierz wskaźnik do interfejsu IBackgroundCopyManager i uzyskaj początkowy lokalizator do usługi BITS, wywołując funkcję CoCreateInstance.

  5. Utwórz zadanie transferu usługi BITS, wywołując metodę IBackgroundCopyManager::CreateJob.

  6. Pobierz wskaźnik do interfejsu wywołania zwrotnego CNotifyInterface i wywołaj metodę IBackgroundCopyJob::SetNotifyInterface metodę, aby otrzymywać powiadomienia o zdarzeniach związanych z zadaniem. Aby uzyskać więcej informacji na temat CNotifyInterface, zobacz Example: Common Classes.

  7. Wywołaj metodę IBackgroundCopyJob::SetNotifyFlags, aby ustawić typy powiadomień do odbierania. W tym przykładzie ustawiono flagi BG_NOTIFY_JOB_TRANSFERRED i BG_NOTIFY_JOB_ERROR.

  8. Pobierz wskaźnik do interfejsu IBitsTokenOptions, wywołując metodę IBackgroundCopyJob::QueryInterface z odpowiednim identyfikatorem interfejsu.

  9. Spróbuj zalogować użytkownika tokenu pomocnika. Utwórz uchwyt personifikacji i wywołaj funkcję LogonUser, aby wypełnić uchwyt personifikacji. W przypadku pomyślnego wywołania funkcji impersonateLoggedOnUser . W przypadku niepowodzenia przykład wywołuje funkcję RevertToSelf, aby zakończyć personifikację zalogowanego użytkownika, zostanie zgłoszony błąd, a dojście zostanie zamknięte.

  10. Wywołaj metodę IBitsTokenOptions::SetHelperToken, aby personifikować token zalogowanego użytkownika. Jeśli ta metoda nie powiedzie się, przykład wywołuje funkcję RevertToSelf, aby zakończyć personifikację zalogowanego użytkownika, zostanie zgłoszony błąd i uchwyt zostanie zamknięty.

    Nuta

    W obsługiwanych wersjach systemu Windows przed systemem Windows 10 w wersji 1607 właściciel zadania musi mieć poświadczenia administracyjne, aby wywołać metodę IBitsTokenOptions::SetHelperToken.

    Począwszy od systemu Windows 10 w wersji 1607, właściciele zadań innych niż administratorzy mogą ustawiać tokeny pomocnika nieadministratora na własnych zadaniach usługi BITS. Właściciele zadań muszą nadal mieć poświadczenia administracyjne, aby ustawić tokeny pomocnika z uprawnieniami administratora.

     

  11. Wywołaj metodę IBitsTokenOptions::SetHelperTokenFlags, aby określić, do których zasobów mają uzyskać dostęp przy użyciu kontekstu zabezpieczeń tokenu pomocniczego.

  12. Po zakończeniu personifikacji przykład wywołuje funkcję RevertToSelf, aby zakończyć personifikację zalogowanego użytkownika, a dojście zostało zamknięte.

  13. Dodaj pliki do zadania transferu usługi BITS, wywołując IBackgroundCopyJob::AddFile.

  14. Po dodaniu pliku wywołaj IBackgroundCopyJob::Resume, aby wznowić zadanie.

  15. Skonfiguruj pętlę czasową, aby poczekać na komunikat zakończenia z interfejsu wywołania zwrotnego podczas przesyłania zadania. Pętla while używa funkcji GetTickCount w celu pobrania liczby milisekund, które upłynęły od rozpoczęcia przenoszenia zadania.

  16. Po zakończeniu zadania transferu usługi BITS usuń zadanie z kolejki, wywołując IBackgroundCopyJob::Complete.

Poniższy przykład kodu dodaje token pomocnika do zadania transferu usługi BITS.

#include <bits.h>
#include <bits4_0.h>
#include <stdio.h>
#include <tchar.h>
#include <lm.h>
#include <iostream>
#include <exception>
#include <string>
#include <atlbase.h>
#include <memory>
#include <new>
#include "CommonCode.h"


void HelperToken(const LPWSTR &remoteFile, const LPWSTR &localFile, const LPWSTR &domain, const LPWSTR &username, const LPWSTR &password)
{
// If CoInitializeEx fails, the exception is unhandled and the program terminates   
CCoInitializer coInitializer(COINIT_APARTMENTTHREADED);

CComPtr<IBackgroundCopyJob> pJob; 

    try
    {
        //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.
        CComPtr<IBackgroundCopyManager> pQueueMgr;
        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.
        wprintf(L"Creating Job...\n");

        GUID guidJob;
        hr = pQueueMgr->CreateJob(L"HelperTokenSample",
            BG_JOB_TYPE_DOWNLOAD,
            &guidJob,
            &pJob);


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

        // Set the File Completed call.
        CComPtr<CNotifyInterface> pNotify;    
        pNotify = new CNotifyInterface();
        hr = pJob->SetNotifyInterface(pNotify);
        if (FAILED(hr))
        {
            // Failed to SetNotifyInterface.
            throw MyException(hr, L"SetNotifyInterface");
        }
        hr = pJob->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED | 
            BG_NOTIFY_JOB_ERROR);

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

        //Retrieve the IBitsTokenOptions interface pointer from the BITS transfer job.
        CComPtr<IBitsTokenOptions> pTokenOptions;
        hr = pJob->QueryInterface(__uuidof(IBitsTokenOptions), (void** ) &pTokenOptions);

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

        // Log on user of the helper token.
        wprintf(L"Credentials for helper token %s\\%s %s\n", domain, username, password);

        HANDLE hImpersonation = INVALID_HANDLE_VALUE;
        if(LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hImpersonation))
        {
            // Impersonate the logged-on user.
            if(ImpersonateLoggedOnUser(hImpersonation))
            {
                // Configure the impersonated logged-on user's token as the helper token.
                hr = pTokenOptions->SetHelperToken();        
                if (FAILED(hr))
                {
                    //Failed to set helper token.
                    CloseHandle(hImpersonation);
                    RevertToSelf();
                    throw MyException(hr, L"SetHelperToken");
                }

                hr = pTokenOptions->SetHelperTokenFlags(BG_TOKEN_LOCAL_FILE);
                if (FAILED(hr))
                {
                    //Failed to set helper token flags.
                    CloseHandle(hImpersonation);
                    RevertToSelf();
                    throw MyException(hr, L"SetHelperTokenFlags");
                }

                RevertToSelf();
            }               
            CloseHandle(hImpersonation);
        }

        // Add a file.
        // Replace parameters with variables that contain valid paths.
        wprintf(L"Adding File to Job\n");
        hr = pJob->AddFile(remoteFile,localFile);

        if(FAILED(hr))
        {   
            //Failed to add file to job.
            throw MyException(hr, L"AddFile");
        }

        //Resume the job.
        wprintf(L"Resuming Job...\n");
        hr = pJob->Resume();
        if (FAILED(hr))
        {
            // Resume failed.                   
            throw MyException(hr, L"Resume");
        }    
    }
    catch(const std::bad_alloc &)
    {
        wprintf(L"Memory allocation failed");
        if (pJob)
        {
            pJob->Cancel();
        }

        return;
    }
    catch(const MyException &ex)
    {
        wprintf(L"Error 0x%x occurred during operation", ex.Error);
        if (pJob)
        {
            pJob->Cancel();
        }

        return;
    }

    wprintf(L"Transferring file and waiting for callback.\n");

    // Wait for QuitMessage from CallBack
    DWORD dwLimit = GetTickCount() + (15 * 60 * 1000);  // set 15 minute limit
    while (dwLimit > GetTickCount())
    {
        MSG msg;

        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
        { 
            // If it is a quit message, exit.
            if (msg.message == WM_QUIT) 
            {
                return;
            }

            // Otherwise, dispatch the message.
            DispatchMessage(&msg); 
        } // End of PeekMessage while loop
    }

    pJob->Cancel();
    return;
}

void _cdecl _tmain(int argc, LPWSTR* argv)
{   
    if (argc != 6)
    {
        wprintf(L"Usage:");
        wprintf(L"%s ", argv[0]);
        wprintf(L"[remote name] [local name] [helpertoken domain] [helpertoken userrname] [helpertoken password]\n");
        return;
    }

    HelperToken(argv[1],argv[2],argv[3],argv[4],argv[5]);

}

tokeny pomocnika dla zadań transferu usługi BITS

IBitsTokenOptions

przykład : typowe klasy