Rychlý start: Inicializace klientské aplikace pro sady SDK ochrany (C++)

V tomto rychlém startu se dozvíte, jak implementovat model inicializace klienta používaný sadou MIP C++ SDK za běhu.

Poznámka:

Kroky popsané v tomto rychlém startu se vyžadují pro všechny klientské aplikace, které používají sady MIP Protection SDK. Tyto rychlé starty by se měly provádět sériově po inicializaci aplikace a implementaci třídy delegáta ověřování a delegáta souhlasu.

Požadavky

Pokud jste to ještě neudělali, nezapomeňte:

  • Dokončete kroky v nastavení a konfiguraci sady Microsoft Information Protection (MIP) SDK. Tento rychlý start "Inicializace klientské aplikace" spoléhá na správné nastavení a konfiguraci sady SDK.
  • Volitelně:
    • Zkontrolujte objekty profilu a modulu. Objekty profilu a engine jsou univerzální koncepty vyžadované klienty, kteří používají sady SDK MIP File/Policy/Protection.
    • Projděte si koncepty ověřování a zjistěte, jak jsou ověřování a souhlas implementovány sadou SDK a klientskou aplikací.
    • Podívejte se na koncepty pozorovatele, abyste se dozvěděli více o pozorovatelích a jejich implementaci. Sada MIP SDK používá vzor pozorovatele k implementaci asynchronních oznámení událostí.

Vytvoření řešení a projektu sady Visual Studio

Nejprve vytvoříme a nakonfigurujeme počáteční řešení a projekt sady Visual Studio, na kterém se sestaví další rychlé starty.

  1. Otevřete Visual Studio 2022 nebo novější, vyberte nabídku Soubor , Nový, Projekt. V dialogovém okně Nový projekt :

    • V levém podokně v části Nainstalováno, Další jazyky vyberte Visual C++.

    • V prostředním podokně vyberte Konzolová aplikace systému Windows.

    • V dolním podokně odpovídajícím způsobem aktualizujte název projektu, umístění a obsahující název řešení .

    • Po dokončení klikněte na tlačítko OK v pravém dolním rohu.

      Vytvoření řešení sady Visual Studio

  2. Do projektu přidejte balíček NuGet pro sadu MIP Protection SDK:

    • V Průzkumníku řešení klikněte pravým tlačítkem na uzel projektu (přímo pod horním uzlem nebo uzel řešení) a vyberte Spravovat balíčky NuGet...:

    • Po otevření karty Správce balíčků NuGet v oblasti karet skupiny editoru:

      • Vyberte Procházet.
      • Do vyhledávacího pole zadejte "Microsoft.InformationProtection".
      • Vyberte balíček Microsoft.InformationProtection.Protection.
      • Klikněte na Instalovat a po zobrazení potvrzovacího dialogového okna Náhled změn klikněte na OK.

      Přidat balíček NuGet do sady Visual Studio

Implementace tříd pozorovatele pro monitorování profilu ochrany a objektů modulu

Teď vytvořte základní implementaci třídy pozorovatele profilu ochrany rozšířením třídy sdk mip::ProtectionProfile::Observer . Pozorovatel je vytvořena instance a později se použije ke sledování načítání objektu profilu ochrany a k přidání objektu enginu do profilu.

  1. Přidejte do projektu novou třídu, která za vás vygeneruje soubory header/.h i implementace/.cpp:

    • V Průzkumníku řešení znovu klikněte pravým tlačítkem myši na uzel projektu, vyberte Přidat a pak vyberte Třída.

    • V dialogovém okně Přidat třídu :

      • Do pole Název třídy zadejte "profile_observer". Všimněte si, že se automaticky vyplní pole souboru .h i .cpp na základě zadaného názvu.
      • Po dokončení klikněte na tlačítko OK .

      Přidání třídy v sadě Visual Studio

  2. Po vygenerování souborů .h a .cpp pro třídu se oba soubory otevřou na kartách Skupiny editoru. Teď aktualizujte každý soubor tak, aby implementovali novou třídu pozorovatele:

    • Aktualizujte "profile_observer.h" tak, že vyberete nebo odstraníte vygenerovanou profile_observer třídu. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#pragma, #include). Potom zkopírujte/vložte následující zdroj do souboru po všech existujících direktivách preprocesoru.

      #include <memory>
      #include "mip/protection/protection_profile.h"
      using std::exception_ptr;
      using std::shared_ptr;
      
      
      class ProtectionProfileObserver final : public mip::ProtectionProfile::Observer {
      public:
           ProtectionProfileObserver() { }
           void OnLoadSuccess(const std::shared_ptr<mip::ProtectionProfile>& profile, const std::shared_ptr<void>& context) override;
           void OnLoadFailure(const std::exception_ptr& Failure, const std::shared_ptr<void>& context) override;
           void OnAddEngineSuccess(const std::shared_ptr<mip::ProtectionEngine>& engine, const std::shared_ptr<void>& context) override;
           void OnAddEngineFailure(const std::exception_ptr& Failure, const std::shared_ptr<void>& context) override;
      };
      
    • Aktualizujte "profile_observer.cpp" výběrem nebo odstraněním vygenerované profile_observer implementace třídy. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#pragma, #include). Potom zkopírujte/vložte následující zdroj do souboru po všech existujících direktivách preprocesoru.

      #include <future>
      
      using std::promise;
      using std::shared_ptr;
      using std::static_pointer_cast;
      using mip::ProtectionEngine;
      using mip::ProtectionProfile;
      
      void ProtectionProfileObserver::OnLoadSuccess(const shared_ptr<ProtectionProfile>& profile, const shared_ptr<void>& context) {
           auto promise = static_pointer_cast<std::promise<shared_ptr<ProtectionProfile>>>(context);
           promise->set_value(profile);
      }
      
      void ProtectionProfileObserver::OnLoadFailure(const std::exception_ptr& error, const shared_ptr<void>& context) {
           auto promise = static_pointer_cast<std::promise<shared_ptr<ProtectionProfile>>>(context);
           promise->set_exception(error);
      }
      
      void ProtectionProfileObserver::OnAddEngineSuccess(const shared_ptr<ProtectionEngine>& engine, const shared_ptr<void>& context) {
           auto promise = static_pointer_cast<std::promise<shared_ptr<ProtectionEngine>>>(context);
           promise->set_value(engine);
      }
      
      void ProtectionProfileObserver::OnAddEngineFailure(const std::exception_ptr& error, const shared_ptr<void>& context) {
           auto promise = static_pointer_cast<std::promise<shared_ptr<ProtectionEngine>>>(context);
           promise->set_exception(error);
      }
      
  3. Postupujte podle kroků v 1. Přidejte do projektu novou třídu pozorovatele modulu ochrany – "engine_observer", která za vás vygeneruje soubory header/.h i implementace/.cpp.

  4. Po vygenerování souborů .h a .cpp pro třídu se oba soubory otevřou na kartách Skupiny editoru. Teď aktualizujte každý soubor tak, aby implementovali novou třídu pozorovatele:

    • Aktualizujte "engine_observer.h" tak, že vyberete nebo odstraníte vygenerovanou engine_observer třídu. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#pragma, #include). Potom zkopírujte/vložte následující zdroj do souboru po všech existujících direktivách preprocesoru.

      #include <memory>
      #include "mip/protection/protection_engine.h"
      using std::vector;
      using std::exception_ptr;
      using std::shared_ptr;
      
      class ProtectionEngineObserver final : public mip::ProtectionEngine::Observer {
        public:
        ProtectionEngineObserver() {}
        void OnGetTemplatesSuccess(const vector<std::shared_ptr<mip::TemplateDescriptor>>& templateDescriptors, const shared_ptr<void>& context) override;
        void OnGetTemplatesFailure(const exception_ptr& Failure, const shared_ptr<void>& context) override;
      
      };
      
    • Aktualizujte "engine_observer.cpp" výběrem nebo odstraněním vygenerované engine_observer implementace třídy. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#pragma, #include). Potom zkopírujte/vložte následující zdroj do souboru po všech existujících direktivách preprocesoru.

      #include "mip/protection/protection_profile.h"
      #include "engine_observer.h"
      
      using std::promise;
      void ProtectionEngineObserver::OnGetTemplatesSuccess(const vector<shared_ptr<mip::TemplateDescriptor>>& templateDescriptors,const shared_ptr<void>& context) {
          auto loadPromise = static_cast<promise<vector<shared_ptr<mip::TemplateDescriptor>>>*>(context.get());
          loadPromise->set_value(templateDescriptors);
        };
      
        void ProtectionEngineObserver::OnGetTemplatesFailure(const exception_ptr& Failure, const shared_ptr<void>& context) {
          auto loadPromise = static_cast<promise<shared_ptr<mip::ProtectionProfile>>*>(context.get());
          loadPromise->set_exception(Failure);
        };
      
  5. Volitelně můžete pomocí kombinace kláves Ctrl+Shift+B (sestavit řešení) spustit testovací kompilaci nebo propojení vašeho řešení, abyste měli jistotu, že se sestavení úspěšně sestaví, než budete pokračovat.

Sada MIP SDK implementuje ověřování pomocí rozšiřitelnosti tříd, který poskytuje mechanismus pro sdílení ověřování s klientskou aplikací. Klient musí získat vhodný přístupový token OAuth2 a předat jej sadě MIP SDK během jejího běhu.

Vytvořte implementaci ověřovacího delegáta rozšířením třídy sady SDK mip::AuthDelegate a přepsáním/implementací abstraktní čistě virtuální funkce mip::AuthDelegate::AcquireOAuth2Token(). Postupujte podle kroků popsaných v části Rychlý start inicializace aplikace sady File SDK. Delegát ověřování je instanciován a později použit objekty profilu ochrany a modulu ochrany.

Teď vytvořte implementaci pro delegáta souhlasu rozšířením třídy SDK mip::ConsentDelegate a přepsáním/implementací čistě virtuální funkce mip::AuthDelegate::GetUserConsent(). Postupujte podle kroků popsaných v části Rychlý start inicializace aplikace sady File SDK. Delegát souhlasu je vytvořen jako instance a následně použit objekty ochranného profilu a ochranného modulu.

Vytvoření profilu ochrany a motoru

Jak už bylo zmíněno, objekty profilu a modulu jsou vyžadovány pro klienty sady SDK pomocí rozhraní API MIP. Dokončete část kódu tohoto rychlého startu přidáním kódu pro vytvoření instance objektů profilu a modulu:

  1. V Průzkumníku řešení otevřete soubor .cpp v projektu, který obsahuje implementaci main() metody. V rámci výchozího nastavení se použije stejný název jako projekt, který ho obsahuje a který jste zadali při vytváření projektu.

  2. Odeberte vygenerovanou implementaci main(). Při vytváření projektu neodebívejte direktivy preprocesoru generované sadou Visual Studio (#pragma, #include). Za všechny direktivy preprocesoru připojte následující kód:

#include "mip/mip_init.h"
#include "mip/mip_context.h"  
#include "auth_delegate.h"
#include "consent_delegate.h"
#include "profile_observer.h"
#include"engine_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::ProtectionProfile;
using mip::ProtectionEngine;

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>"};

  std::shared_ptr<mip::MipConfiguration> mipConfiguration = std::make_shared<mip::MipConfiguration>(mAppInfo,
				                                                                                               "mip_data",
                                                                                      			         mip::LogLevel::Trace,
                                                                                                     false);

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

  auto profileObserver = make_shared<ProtectionProfileObserver>(); // 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
  ProtectionProfile::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<ProtectionProfile>>>();
  auto profileFuture = profilePromise->get_future();
  try
  {
    mip::ProtectionProfile::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
  ProtectionEngine::Settings engineSettings(       
     mip::Identity("<engine-account>"),         // Engine identity (account used for authentication)
     authDelegateImpl,                          // Reference to mip::AuthDelegate implementation
     "",                                        // ClientData field
     "en-US");                                  // Locale (default = en-US)

  // Set the engineId so it can be cached and reused. 
  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<ProtectionEngine>>>();
  auto engineFuture = enginePromise->get_future();
  profile->AddEngineAsync(engineSettings, enginePromise);
  std::shared_ptr<ProtectionEngine> 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.
  engine = nullptr;
  profile = nullptr;
  mipContext.Shutdown();
  mipContext = nullptr;

  return 0;
}
  1. Nahraďte všechny zástupné hodnoty ve zdrojovém kódu, které jste právě vložili, pomocí řetězcových konstant:

    Zástupný text Hodnota Příklad
    <ID aplikace> ID aplikace Microsoft Entra (GUID) přiřazené k aplikaci zaregistrované v kroku 2 článku "Nastavení a konfigurace sady MIP SDK"(setup-configure-mip.md). Nahraďte 2 instance. "0edbblll-8773-44de-b87c-b8c6276d41eb"
    <název aplikace> Uživatelsky definovaný popisný název aplikace. Musí obsahovat platné znaky ASCII (s výjimkou ;) a v ideálním případě se shoduje s názvem aplikace, který jste použili v registraci Microsoft Entra. "AppInitialization"
    <verze aplikace> Informace o verzi definované uživatelem pro vaši aplikaci Musí obsahovat platné znaky ASCII (s výjimkou ;). "1.1.0.0"
    <účet pro engine> Účet použitý pro identifikaci stroje. Při ověřování pomocí uživatelského účtu během získávání tokenů se musí shodovat s touto hodnotou. "user1@tenant.onmicrosoft.com"
    <stav motoru> Uživatelem definovaný stav, který se má přiřadit k enginu. "My App State"
  2. Teď proveďte finální sestavení aplikace a vyřešte případné chyby. Kód by se měl úspěšně sestavit, ale ještě se nespustí správně, dokud nedokončíte další rychlý start. Pokud spustíte aplikaci, zobrazí se výstup podobný následujícímu. Aplikace vytvoří profil ochrany a modul ochrany úspěšně, ale neaktivoval modul ověřování a ještě nebudete mít přístupový token, dokud nedokončíte další rychlý start.

     C:\MIP Sample Apps\ProtectionQS\Debug\ProtectionQS.exe (process 8252) exited with code 0.
     To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
     Press any key to close this window . . .
    

Další kroky

Teď, když je inicializační kód hotový, jste připraveni na další rychlý start, kde začnete používat sadu MIP Protection SDK.