Freigeben über


Beispiel: Verwenden der SSPI-Authentifizierungscodierung mit BITS

Sie können die Methoden SSPI-Authentifizierung (Security Support Provider Interface) und Intelligent Transfer Service (Background Intelligent Transfer Service, BITS) verwenden, um die Anmeldeinformationen von einem Benutzer abzurufen, die Anmeldeinformationen zu codieren und die codierten Anmeldeinformationen für einen BITS-Übertragungsauftrag festzulegen. Die Codierung ist erforderlich, um die Anmeldeinformationenstruktur in Zeichenfolgen zu konvertieren, die an einen BITS-Übertragungsauftrag übergeben werden können.

Weitere Informationen zur SSPI-Authentifizierung und -Methoden finden Sie unter SSPI-.

Im folgenden Verfahren werden die Anmeldeinformationen des Benutzers mithilfe des Aushandlungssicherheitspakets aufgefordert. Das Programm erstellt eine Authentifizierungsidentitätsstruktur und füllt die Struktur mit den codierten Zeichenfolgen auf, die den Benutzernamen, die Domäne und das Kennwort des Benutzers darstellen. Anschließend erstellt das Programm einen BITS-Downloadauftrag und legt den codierten Benutzernamen und das Kennwort als Anmeldeinformationen für den Auftrag fest. Das Programm gibt die Authentifizierungsidentitätsstruktur frei, nachdem sie nicht mehr benötigt wird.

In diesem Beispiel wird der in Beispiel definierte Header und die Implementierung verwendet: Allgemeine Klassen.

So verwenden Sie die SSPI-Authentifizierungscodierung mit BITS-Übertragungsaufträgen

  1. Initialisieren Sie COM-Parameter durch Aufrufen der CCoInitializer-Funktion. Weitere Informationen zur CCoInitializer-Funktion finden Sie unter Beispiel: Allgemeine Klassen.
  2. Rufen Sie Zeiger für die IBackgroundCopyManager, IBackgroundCopyJob, IBackgroundCopyJob2 Schnittstellen ab. In diesem Beispiel wird die CComPtr-Klasse zum Verwalten von COM-Schnittstellenzeigern verwendet.
  3. Erstellen Sie eine CREDUI_INFO Struktur, die Informationen zum Anpassen der Darstellung des Dialogfelds für die SspiPromptForCredentials-Funktionenthält. Fordern Sie dann die Anmeldeinformationen des Benutzers an. Weitere Informationen finden Sie im SspiPromptForCredentials Function.
  4. Codieren Sie die Anmeldeinformationsstruktur als Zeichenfolgen, die mithilfe der SspiEncodeAuthIdentityAsStrings- funktion an einen BITS-Übertragungsauftrag übergeben werden können.
  5. Bereiten Sie eine BG_AUTH_CREDENTIALS Struktur vor.
  6. Initialisieren Sie die COM-Prozesssicherheit, indem Sie CoInitializeSecurityaufrufen. BITS erfordert mindestens die Identitätswechselebene. BITS schlägt mit E_ACCESSDENIED fehl, wenn die richtige Identitätswechselebene nicht festgelegt ist.
  7. Rufen Sie den anfänglichen Locator für BITS ab, indem Sie die CoCreateInstance-Funktion aufrufen.
  8. Erstellen Sie einen BITS-Übertragungsauftrag, indem Sie die IBackgroundCopyManager::CreateJob-Methode aufrufen.
  9. Rufen Sie den Bezeichner für die IBackgroundCopyJob2--Schnittstelle ab, und rufen Sie die IBackgroundCopyJob::QueryInterface-Methode auf.
  10. Füllen Sie die BG_AUTH_CREDENTIALS Struktur mit den codierten Benutzernamen- und Kennwortzeichenfolgen auf, und legen Sie das Authentifizierungsschema auf "Aushandeln" (BG_AUTH_SCHEME_NEGOTIATE) fest.
  11. Verwenden Sie den IBackgroundCopyJob2- Zeiger, um Anforderungen an BITS zu stellen. Dieses Programm verwendet die IBackgroundCopyJob2::SetCredentials Methode, um die Anmeldeinformationen für den BITS-Übertragungsauftrag festzulegen.
  12. Fügen Sie Dateien hinzu, ändern Sie Eigenschaften, oder setzen Sie den BITS-Übertragungsauftrag fort.
  13. Nachdem der BITS-Übertragungsauftrag abgeschlossen ist, entfernen Sie den Auftrag aus der Warteschlange, indem Sie IBackgroundCopyJob::Completeaufrufen.
  14. Geben Sie schließlich die Authentifizierungsidentitätsstruktur frei, indem Sie die SspiFreeAuthIdentity--Funktion aufrufen.

Im folgenden Codebeispiel wird die Verwendung der SSPI-Authentifizierungscodierung mit BITS-Übertragungsaufträgen veranschaulicht.

#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-

Beispiel: Allgemeine Klassen