Aracılığıyla paylaş


Örnek: BITS ile SSPI Kimlik Doğrulama Kodlaması Kullanma

Güvenlik Desteği Sağlayıcısı Arabirimi (SSPI) Kimlik Doğrulaması ve Arka Plan Akıllı Aktarım Hizmeti (BITS) yöntemlerini kullanarak bir kullanıcıdan kimlik bilgilerini alabilir, kimlik bilgilerini kodlayabilir ve kodlanmış kimlik bilgilerini BITS aktarım işinde ayarlayabilirsiniz. Kimlik bilgileri yapısını BITS aktarım işine geçirilebilen dizelere dönüştürmek için kodlama gereklidir.

SSPI kimlik doğrulaması ve yöntemleri hakkında daha fazla bilgi için bkz. SSPI.

Aşağıdaki yordam, Negotiate güvenlik paketini kullanarak kullanıcıdan kimlik bilgilerini ister. Program bir kimlik doğrulama kimliği yapısı oluşturur ve yapıyı kullanıcının adını, etki alanını ve parolasını temsil eden kodlanmış dizelerle doldurur. Ardından program bir BITS indirme işi oluşturur ve kodlanmış kullanıcı adını ve parolasını işin kimlik bilgileri olarak ayarlar. Program, kimlik doğrulama kimliği yapısını artık gerekli olmadığında serbestleştirir.

Bu örnekte, Örneği: Ortak Sınıflariçinde tanımlanan üst bilgi ve uygulama kullanılır.

BITS aktarım işleri SSPI kimlik doğrulama kodlamasını kullanmak için

  1. CCoInitializer işlevini çağırarak COM parametrelerini başlatın. CCoInitializer işlevi hakkında daha fazla bilgi için bkz. Örnek: Ortak Sınıflar.
  2. IBackgroundCopyManager, IBackgroundCopyJob, IBackgroundCopyJob2 arabirimleri için işaretçiler alın. Bu örnekte COM arabirim işaretçilerini yönetmek için CComPtr Sınıf kullanılır.
  3. SspiPromptForCredentials İşleviiçin iletişim kutusunun görünümünü özelleştirmeye yönelik bilgiler içeren bir CREDUI_INFO yapısı oluşturun. Ardından kullanıcıdan kimlik bilgilerini iste. Daha fazla bilgi için bkz. SspiPromptForCredentials İşlevi.
  4. Kimlik bilgisi yapısını, SspiEncodeAuthIdentityAsStrings işlevi kullanılarak BITS aktarım işine geçirilebilen dizeler olarak kodlar.
  5. BG_AUTH_CREDENTIALS bir yapı hazırlayın.
  6. CoInitializeSecurityçağırarak COM işlem güvenliğini başlatın. BITS için en azından KIMLIĞE BÜRÜNme düzeyi gerekir. Doğru kimliğe bürünme düzeyi ayarlanmadıysa BITS E_ACCESSDENIED ile başarısız olur.
  7. CoCreateInstance işlevini çağırarak ILK bulucuyu BITS'e alın.
  8. IBackgroundCopyManager::CreateJob yöntemini çağırarak BIR BITS aktarım işi oluşturun.
  9. IBackgroundCopyJob2 arabiriminin tanımlayıcısını alın ve IBackgroundCopyJob::QueryInterface yöntemini çağırın.
  10. BG_AUTH_CREDENTIALS yapısını kodlanmış kullanıcı adı ve parola dizeleriyle doldurun ve kimlik doğrulama düzenini Negotiate (BG_AUTH_SCHEME_NEGOTIATE) olarak ayarlayın.
  11. BITS'e istekte bulunmak için IBackgroundCopyJob2 işaretçisini kullanın. Bu program, BITS aktarım işinin kimlik bilgilerini ayarlamak için IBackgroundCopyJob2::SetCredentials yöntemini kullanır.
  12. Dosya ekleyin, özellikleri değiştirin veya BITS aktarım işini sürdürin.
  13. BITS aktarım işi tamamlandıktan sonra, IBackgroundCopyJob::Completeçağırarak işi kuyruktan kaldırın.
  14. Son olarak, SspiFreeAuthIdentity işlevini çağırarak kimlik doğrulama kimliği yapısını boşaltın.

Aşağıdaki kod örneği, BITS aktarım işleri ile SSPI Kimlik Doğrulama Kodlaması'nın nasıl kullanılacağını gösterir.

#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

Örnek: Ortak Sınıflar