Hızlı Başlangıç: İstemci uygulaması başlatma (C++)

Bu hızlı başlangıçta, çalışma zamanında MIP C++ SDK'sı tarafından kullanılan istemci başlatma deseninin nasıl uygulandığı gösterilmektedir.

Dekont

Bu hızlı başlangıçta özetlenen adımlar, MIP Dosyası, İlke veya Koruma SDK'larını kullanan tüm istemci uygulamaları için gereklidir. Bu Hızlı Başlangıçta Dosya SDK'larının kullanımı gösteriliyor olsa da, bu desen İlke ve Koruma SDK'larını kullanan istemciler için de geçerlidir. Kalan Hızlı Başlangıçları seri olarak tamamlayın; her biri bir öncekine göre derlenir ve bu ilk hızlı başlangıç olur.

Ön koşullar

Henüz yapmadıysanız şunları yaptığınızdan emin olun:

  • Microsoft Information Protection (MIP) SDK kurulumu ve yapılandırmasındaki adımları tamamlayın. Bu "İstemci uygulaması başlatma" Hızlı Başlangıcı, doğru SDK kurulumuna ve yapılandırmasına dayanır.
  • Isteğe bağlı olarak:
    • Profil ve altyapı nesnelerini gözden geçirin. Profil ve altyapı nesneleri, MIP Dosya/İlke/Koruma SDK'larını kullanan istemciler için gerekli olan evrensel kavramlardır.
    • Kimlik doğrulaması ve onayın SDK ve istemci uygulaması tarafından nasıl uygulandığını öğrenmek için Kimlik doğrulama kavramlarını gözden geçirin.
    • Gözlemciler ve bunların nasıl uygulandığı hakkında daha fazla bilgi edinmek için Gözlemci kavramlarını gözden geçirin. MIP SDK'sı zaman uyumsuz olay bildirimleri uygulamak için gözlemci desenini kullanır.

Visual Studio çözümü ve projesi oluşturma

İlk olarak, diğer Hızlı Başlangıçların derlendiği ilk Visual Studio çözümünü ve projesini oluşturup yapılandıracağız.

  1. Visual Studio 2017'yi açın, Dosya menüsünü (Yeni, Proje) seçin. Yeni Proje iletişim kutusunda:

    • Sol bölmedeki Yüklü, Diğer Diller'in altında Visual C++ öğesini seçin.

    • Orta bölmede Windows Konsol Uygulaması'nı seçin

    • Alt bölmede proje Adı, Konum ve içeren Çözüm adını uygun şekilde güncelleştirin.

    • bitirdiğinizde, sağ alttaki Tamam düğmesine tıklayın.

      Visual Studio solution creation

  2. MIP Dosya SDK'sı için Nuget paketini projenize ekleyin:

    • Çözüm Gezgini proje düğümüne sağ tıklayın (doğrudan üst/çözüm düğümü altında) ve NuGet paketlerini yönet...:

    • NuGet Paket Yöneticisi sekmesi Düzenleyici Grubu sekmeleri alanında açıldığında:

      • Göz At'ı seçin.
      • Arama kutusuna "Microsoft.InformationProtection" yazın.
      • "Microsoft.InformationProtection.File" paketini seçin.
      • Önizleme değişiklikleri onay iletişim kutusu görüntülendiğinde "Yükle" seçeneğine ve ardından "Tamam"a tıklayın.

      Visual Studio add NuGet package

Dosya profilini ve altyapı nesnelerini izlemek için bir gözlemci sınıfı uygulama

Şimdi SDK'nın mip::FileProfile::Observer sınıfını genişleterek Dosya profili gözlemci sınıfı için temel bir uygulama oluşturun. Gözlemci örneği oluşturulur ve daha sonra Dosya profili nesnesinin yüklenmesini izlemek ve altyapı nesnesini profile eklemek için kullanılır.

  1. Projenize, sizin için hem header/.h hem de application/.cpp dosyalarını oluşturan yeni bir sınıf ekleyin:

    • Çözüm Gezgini proje düğümüne yeniden sağ tıklayın, Ekle'yi ve ardından Sınıf'ı seçin.

    • Sınıf Ekle iletişim kutusunda:

      • Sınıf Adı alanına "profile_observer" girin. Hem .h dosyası hem de .cpp dosya alanlarının, girdiğiniz ada göre otomatik olarak doldurulduğunu fark edin.
      • İşiniz bittiğinde Tamam düğmesine tıklayın.

      Visual Studio add class

  2. sınıfı için .h ve .cpp dosyaları üretildikten sonra, her iki dosya da Düzenleyici Grubu sekmelerinde açılır. Şimdi her dosyayı yeni gözlemci sınıfınızı uygulayacak şekilde güncelleştirin:

    • Oluşturulan profile_observer sınıfı seçerek/silerek "profile_observer.h" dosyasını güncelleştirin. Önceki adım (#pragma, #include) tarafından oluşturulan önişlemci yönergelerini kaldırmayın . Ardından, var olan önişlemci yönergelerinden sonra aşağıdaki kaynağı kopyalayıp dosyaya yapıştırın:

      #include <memory>
      #include "mip/file/file_profile.h"
      
      class ProfileObserver final : public mip::FileProfile::Observer {
      public:
           ProfileObserver() { }
           void OnLoadSuccess(const std::shared_ptr<mip::FileProfile>& profile, const std::shared_ptr<void>& context) override;
           void OnLoadFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override;
           void OnAddEngineSuccess(const std::shared_ptr<mip::FileEngine>& engine, const std::shared_ptr<void>& context) override;
           void OnAddEngineFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override;
      };
      
    • Oluşturulan profile_observer sınıf uygulamasını seçerek/silerek "profile_observer.cpp" dosyasını güncelleştirin. Önceki adım (#pragma, #include) tarafından oluşturulan önişlemci yönergelerini kaldırmayın . Ardından, var olan önişlemci yönergelerinden sonra aşağıdaki kaynağı kopyalayıp dosyaya yapıştırın:

      #include <future>
      
      using std::promise;
      using std::shared_ptr;
      using std::static_pointer_cast;
      using mip::FileEngine;
      using mip::FileProfile;
      
      void ProfileObserver::OnLoadSuccess(const shared_ptr<FileProfile>& profile, const shared_ptr<void>& context) {
           auto promise = static_pointer_cast<std::promise<shared_ptr<FileProfile>>>(context);
           promise->set_value(profile);
      }
      
      void ProfileObserver::OnLoadFailure(const std::exception_ptr& error, const shared_ptr<void>& context) {
           auto promise = static_pointer_cast<std::promise<shared_ptr<FileProfile>>>(context);
           promise->set_exception(error);
      }
      
      void ProfileObserver::OnAddEngineSuccess(const shared_ptr<FileEngine>& engine, const shared_ptr<void>& context) {
           auto promise = static_pointer_cast<std::promise<shared_ptr<FileEngine>>>(context);
           promise->set_value(engine);
      }
      
      void ProfileObserver::OnAddEngineFailure(const std::exception_ptr& error, const shared_ptr<void>& context) {
           auto promise = static_pointer_cast<std::promise<shared_ptr<FileEngine>>>(context);
           promise->set_exception(error);
      }
      
  3. İsteğe bağlı olarak, devam etmeden önce başarılı bir şekilde derlendiğinden emin olmak için çözümünüzün test derlemesini/bağlantısını çalıştırmak için F6 (Derleme Çözümü) kullanın.

Kimlik doğrulama temsilcisi uygulama

MIP SDK' sı, istemci uygulamasıyla kimlik doğrulama çalışmasını paylaşmak için bir mekanizma sağlayan sınıf genişletilebilirliğini kullanarak kimlik doğrulamasını uygular. İstemcinin uygun bir OAuth2 erişim belirteci alması ve çalışma zamanında MIP SDK'sına sağlaması gerekir.

Şimdi SDK'nın mip::AuthDelegate sınıfını genişleterek ve saf sanal işlevi geçersiz kılarak/uygulayarak mip::AuthDelegate::AcquireOAuth2Token() kimlik doğrulama temsilcisi için bir uygulama oluşturun. Kimlik doğrulama temsilcisi örneği oluşturulur ve daha sonra Dosya profili ve Dosya altyapısı nesneleri tarafından kullanılır.

  1. Önceki bölümün 1. adımında kullandığımız Visual Studio "Sınıf Ekle" özelliğini kullanarak projenize başka bir sınıf ekleyin. Bu kez, Sınıf Adı alanına "auth_delegate" girin.

  2. Şimdi her dosyayı yeni kimlik doğrulama temsilcisi sınıfınızı uygulayacak şekilde güncelleştirin:

    • Oluşturulan auth_delegate tüm sınıf kodunu aşağıdaki kaynakla değiştirerek "auth_delegate.h" dosyasını güncelleştirin. Önceki adım tarafından oluşturulan önişlemci yönergelerini kaldırmayın (#pragma, #include):

      #include <string>
      #include "mip/common_types.h"
      
      class AuthDelegateImpl final : public mip::AuthDelegate {
      public:
           AuthDelegateImpl() = delete;        // Prevents default constructor
      
           AuthDelegateImpl(
             const std::string& appId)         // AppID for registered AAD app
             : mAppId(appId) {};
      
           bool AcquireOAuth2Token(            // Called by MIP SDK to get a token
             const mip::Identity& identity,    // Identity of the account to be authenticated, if known
             const OAuth2Challenge& challenge, // Authority (AAD tenant issuing token), and resource (API being accessed; "aud" claim).
             OAuth2Token& token) override;     // Token handed back to MIP SDK
      
      private:
           std::string mAppId;
           std::string mToken;
           std::string mAuthority;
           std::string mResource;
      };
      
    • Oluşturulan auth_delegate tüm sınıf uygulamasını aşağıdaki kaynakla değiştirerek "auth_delegate.cpp" dosyasını güncelleştirin. Önceki adım (#pragma, #include) tarafından oluşturulan önişlemci yönergelerini kaldırmayın .

      Önemli

      Aşağıdaki belirteç alma kodu üretim kullanımı için uygun değildir. Üretimde bu, aşağıdakiler kullanılarak dinamik olarak belirteç alan kodla değiştirilmelidir:

      • Microsoft Entra uygulama kaydınızda belirtilen appId ve yanıt/yeniden yönlendirme URI'si (yanıt/yeniden yönlendirme URI'sinin uygulama kaydınızla eşleşmesi gerekir )
      • Bağımsız değişkeninde SDK tarafından geçirilen yetkili ve kaynak URL'si challenge (kaynak URL'si uygulama kaydınızın API/izinleriyle eşleşmelidir )
      • Hesabın SDK tarafından geçirilen bağımsız değişkenle identity eşleştiği geçerli uygulama/kullanıcı kimlik bilgileri. OAuth2 "yerel" istemcileri kullanıcı kimlik bilgilerini istemeli ve "yetkilendirme kodu" akışını kullanmalıdır. OAuth2 "gizli istemcileri", "istemci kimlik bilgileri" akışıyla (hizmet gibi) kendi güvenli kimlik bilgilerini kullanabilir veya "yetkilendirme kodu" akışını (web uygulaması gibi) kullanarak kullanıcı kimlik bilgilerini isteyebilir.

      OAuth2 belirteci alma karmaşık bir protokoldür ve normalde bir kitaplık kullanılarak gerçekleştirilir. TokenAcquireOAuth2Token() gerektiğinde yalnızca MIP SDK'sı tarafından çağrılır.

      #include <iostream>
      using std::cout;
      using std::cin;
      using std::string;
      
      bool AuthDelegateImpl::AcquireOAuth2Token(const mip::Identity& identity, const OAuth2Challenge& challenge, OAuth2Token& token) 
      {
           // Acquire a token manually, reuse previous token if same authority/resource. In production, replace with token acquisition code.
           string authority = challenge.GetAuthority();
           string resource = challenge.GetResource();
           if (mToken == "" || (authority != mAuthority || resource != mResource))
           {
               cout << "\nRun the PowerShell script to generate an access token using the following values, then copy/paste it below:\n";
               cout << "Set $authority to: " + authority + "\n";
               cout << "Set $resourceUrl to: " + resource + "\n";
               cout << "Sign in with user account: " + identity.GetEmail() + "\n";
               cout << "Enter access token: ";
               cin >> mToken;
               mAuthority = authority;
               mResource = resource;
               system("pause");
           }
      
           // Pass access token back to MIP SDK
           token.SetAccessToken(mToken);
      
           // True = successful token acquisition; False = failure
           return true;
      }
      
  3. İsteğe bağlı olarak, devam etmeden önce başarılı bir şekilde derlendiğinden emin olmak için çözümünüzün test derlemesini/bağlantısını çalıştırmak için F6 (Derleme Çözümü) kullanın.

Şimdi SDK'nın mip::ConsentDelegate sınıfını genişleterek ve saf sanal işlevi geçersiz kılarak/uygulayarak mip::AuthDelegate::GetUserConsent() onay temsilcisi için bir uygulama oluşturun. Onay temsilcisi örneği oluşturulur ve daha sonra Dosya profili ve Dosya altyapısı nesneleri tarafından kullanılır.

  1. Daha önce kullandığımız Visual Studio "Sınıf Ekle" özelliğini kullanarak projenize başka bir sınıf ekleyin. Bu kez, Sınıf Adı alanına "consent_delegate" girin.

  2. Şimdi her dosyayı yeni onay temsilcisi sınıfınızı uygulayacak şekilde güncelleştirin:

    • Oluşturulan consent_delegate tüm sınıf kodunu aşağıdaki kaynakla değiştirerek "consent_delegate.h" dosyasını güncelleştirin. Önceki adım tarafından oluşturulan önişlemci yönergelerini kaldırmayın (#pragma, #include):

      #include "mip/common_types.h"
      #include <string>
      
      class ConsentDelegateImpl final : public mip::ConsentDelegate {
      public:
           ConsentDelegateImpl() = default;
           virtual mip::Consent GetUserConsent(const std::string& url) override;
      };
      
    • Oluşturulan consent_delegate tüm sınıf uygulamasını aşağıdaki kaynakla değiştirerek "consent_delegate.cpp" dosyasını güncelleştirin. Önceki adım (#pragma, #include) tarafından oluşturulan önişlemci yönergelerini kaldırmayın .

      #include <iostream>
      using mip::Consent;
      using std::string;
      
      Consent ConsentDelegateImpl::GetUserConsent(const string& url) 
      {
           // Accept the consent to connect to the url
           std::cout << "SDK will connect to: " << url << std::endl;
           return Consent::AcceptAlways;
      }
      
  3. İsteğe bağlı olarak, devam etmeden önce başarılı bir şekilde derlendiğinden emin olmak için çözümünüzün test derlemesini/bağlantısını çalıştırmak için F6 (Derleme Çözümü) kullanın.

Dosya profili ve altyapısı oluşturma

Belirtildiği gibi, MIP API'lerini kullanan SDK istemcileri için profil ve altyapı nesneleri gereklidir. Profil ve altyapı nesnelerinin örneğini oluşturacak kod ekleyerek bu Hızlı Başlangıcın kodlama bölümünü tamamlayın:

  1. Çözüm Gezgini, yönteminin uygulanmasını main() içeren projenizde .cpp dosyasını açın. Varsayılan olarak, proje oluşturma sırasında belirttiğiniz, onu içeren projeyle aynı ada sahiptir.

  2. oluşturulan uygulamasını main()kaldırın. Proje oluşturma sırasında Visual Studio tarafından oluşturulan önişlemci yönergelerini kaldırmayın (#pragma, #include). Önişlemci yönergelerinden sonra aşağıdaki kodu ekleyin:

#include "mip/mip_context.h"  
#include "auth_delegate.h"
#include "consent_delegate.h"
#include "profile_observer.h"

using std::promise;
using std::future;
using std::make_shared;
using std::shared_ptr;
using std::string;
using std::cout;
using mip::ApplicationInfo;
using mip::FileProfile;
using mip::FileEngine;

int main()
{
  // Construct/initialize objects required by the application's profile object
  // ApplicationInfo object (App ID, name, version)
  ApplicationInfo appInfo{"<application-id>",      
                          "<application-name>",
                          "<application-version>"};

  // Create MipConfiguration object.
  std::shared_ptr<mip::MipConfiguration> mipConfiguration = std::make_shared<mip::MipConfiguration>(appInfo,    
				                                                                                               "mip_data", 
                                                                                      			         mip::LogLevel::Trace, 
                                                                                                     false);


  std::shared_ptr<mip::MipContext> mMipContext = mip::MipContext::Create(mipConfiguration);

  auto profileObserver = make_shared<ProfileObserver>();                     // Observer object
  auto authDelegateImpl = make_shared<AuthDelegateImpl>("<application-id>"); // Authentication delegate object (App ID)                 
  auto consentDelegateImpl = make_shared<ConsentDelegateImpl>();             // Consent delegate object

  // Construct/initialize profile object
  FileProfile::Settings profileSettings(
                                mMipContext,
                                mip::CacheStorageType::OnDisk,
                                consentDelegateImpl,
                                profileObserver);

  // Set up promise/future connection for async profile operations; load profile asynchronously
  auto profilePromise = make_shared<promise<shared_ptr<FileProfile>>>();
  auto profileFuture = profilePromise->get_future();

  try
	  { 
		  mip::FileProfile::LoadAsync(profileSettings, profilePromise);
  }
	  catch (const std::exception& e)
	  {
		  cout << "An exception occurred... are the Settings and ApplicationInfo objects populated correctly?\n\n" << e.what() << "'\n";
			
		  system("pause");
		  return 1;
	  }
	  auto profile = profileFuture.get();

  // Construct/initialize engine object
  FileEngine::Settings engineSettings(
                                  mip::Identity("<engine-account>"), // Engine identity (account used for authentication)
                                  authDelegateImpl,		       // Token acquisition implementation
				    "<engine-state>",                  // User-defined engine state
                                  "en-US");                          // Locale (default = en-US)
                                  
  // Set the engineId for caching. 
  engineSettings.SetEngineId("<engine-account>");
  // Set up promise/future connection for async engine operations; add engine to profile asynchronously
  auto enginePromise = make_shared<promise<shared_ptr<FileEngine>>>();
  auto engineFuture = enginePromise->get_future();
  profile->AddEngineAsync(engineSettings, enginePromise);
  std::shared_ptr<FileEngine> engine; 
  try
  {
    engine = engineFuture.get();
  }
  catch (const std::exception& e)
  {
    cout << "An exception occurred... is the access token incorrect/expired?\n\n" << e.what() << "'\n";
     
    system("pause");
    return 1;
  }

  // Application shutdown. Null out profile and engine, call ReleaseAllResources();
  // Application may crash at shutdown if resources aren't properly released.
  // handler = nullptr; // This will be used in later quick starts.
  engine = nullptr;
  profile = nullptr;   
  mMipContext->ShutDown();
  mMipContext = nullptr;

  return 0;
  }
  1. Dize sabitlerini kullanarak, yeni yapıştırdığınız kaynak koddaki tüm yer tutucu değerleri değiştirin:

    Yer tutucu Değer Örnek
    <uygulama kimliği> "MIP SDK kurulumu ve yapılandırması" makalesinin 2. adımında kaydedilen uygulamaya atanan Microsoft Entra Uygulama Kimliği (GUID). 2 örneği değiştirin. "0edbblll-8773-44de-b87c-b8c6276d41eb"
    <uygulama adı> Uygulamanız için kullanıcı tanımlı kolay ad. Geçerli ASCII karakterleri içermelidir (';' hariç) ve ideal olarak Microsoft Entra kaydınızda kullandığınız uygulama adıyla eşleşmelidir. "AppInitialization"
    <uygulama sürümü> Uygulamanız için kullanıcı tanımlı sürüm bilgileri. Geçerli ASCII karakterleri içermelidir (';' hariç). "1.1.0.0"
    <altyapı hesabı> Altyapının kimliği için kullanılan hesap. Belirteç alma sırasında bir kullanıcı hesabıyla kimlik doğrulaması yaptığınızda bu değerle eşleşmesi gerekir. "user1@tenant.onmicrosoft.com"
    <altyapı durumu> Altyapıyla ilişkilendirilecek kullanıcı tanımlı durum. "My App State"
  2. Şimdi uygulamanın son derlemesini yapın ve hataları çözün. Kodunuz başarıyla derlenmelidir, ancak sonraki Hızlı Başlangıcı tamamlayana kadar henüz doğru çalışmayacaktır. Uygulamayı çalıştırırsanız aşağıdakine benzer bir çıkış görürsünüz. Sonraki Hızlı Başlangıç'ı tamamlayana kadar sağlayabilecek bir erişim belirtecine sahip olmayacaksınız.

Sonraki Adımlar

Başlatma kodunuz tamamlandıktan sonra, MIP Dosya SDK'larını yaşamaya başlayacağınız sonraki hızlı başlangıç için hazırsınız.