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

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

Poznámka:

Každá klientská aplikace, která používá sady MIP Protection SDK, vyžaduje kroky v tomto rychlém startu. Dokončete tyto rychlé starty sériově po inicializaci aplikace a implementaci delegáta ověřování a tříd 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řte a nakonfigurujte počáteční Visual Studio řešení a projekt, na kterých ostatní rychlé starty vycházejí.

  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 konzolovou aplikaci 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í vyberte v pravém dolním rohu ok .

      Vytvoření řešení v aplikaci Visual Studio.

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

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

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

      • Vyberte Procházet.
      • Zadejte Microsoft.InformationProtection do vyhledávacího pole.
      • Microsoft.InformationProtection.Protection Vyberte balíček.
      • Vyberte Nainstalovat a potom vyberte OK, když se zobrazí potvrzovací dialog Náhled změn.

      Visual Studio – přidat balíček NuGet.

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 sady SDK mip::ProtectionProfile::Observer . Sada SDK vytvoří instanci pozorovatele a později ji použije k monitorování načítání objektu profilu ochrany a přidání objektu modulu do profilu.

  1. Přidejte do projektu novou třídu, která za vás vygeneruje soubory hlavičky (.h) i implementace (.cpp):

    • V Průzkumník ř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 Visual Studio automaticky vyplní pole souboru .h i .cpp na základě zadaného názvu.
      • Po dokončení vyberte OK.

      Visual Studio – přidání třídy.

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

    • Aktualizujte profile_observer.h výběrem a odstraněním vygenerované profile_observer třídy. Neodebíjejte direktivy preprocesoru, které vygeneroval předchozí krok (#pragma, #include). Potom zkopírujte a vložte následující zdrojový kód do souboru za případné stávající direktivy 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 tak, že vyberete a odstraníte vygenerovanou implementaci třídy profile_observer. Neodebíjejte direktivy preprocesoru, které vygeneroval předchozí krok (#pragma, #include). Potom zkopírujte a vložte následující zdrojový kód do souboru za případné stávající direktivy 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. Opakováním kroku 1 přidejte do projektu novou třídu pozorovatele engine_observermodulu ochrany. Tato třída vygeneruje soubory hlavičky (.h) i implementace (.cpp) za vás.

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

    • Aktualizujte engine_observer.h výběrem a odstraněním vygenerované engine_observer třídy. Neodebíjejte direktivy preprocesoru, které vygeneroval předchozí krok (#pragma, #include). Potom zkopírujte a vložte následující zdrojový kód do souboru za případné stávající direktivy 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 tak, že vyberete a odstraníte vygenerovanou implementaci třídy engine_observer. Neodebíjejte direktivy preprocesoru, které vygeneroval předchozí krok (#pragma, #include). Potom zkopírujte a vložte následující zdrojový kód do souboru za případné stávající direktivy 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<vector<shared_ptr<mip::TemplateDescriptor>>>*>(context.get());
          loadPromise->set_exception(Failure);
        };
      
  5. Volitelně můžete pomocí kombinace kláves Ctrl+Shift+B (sestavit řešení) spustit testovací kompilaci a propojit řešení a ověřit, že se sestavení úspěšně sestaví, než budete pokračovat.

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

Vytvořte implementaci delegáta pro ověřování rozšířením třídy mip::AuthDelegate ze sady SDK a přepsáním nebo implementací čistě virtuální funkce mip::AuthDelegate::AcquireOAuth2Token(). Postupujte podle kroků popsaných v rychlém startu inicializace aplikace File SDK. Profil Protection a objekty modulu Protection engine vytvoří instanci delegáta pro ověřování a později jej použijí.

Nyní vytvořte implementaci delegáta souhlasu rozšířením třídy mip::ConsentDelegate ze sady SDK a přepsáním nebo implementací čistě virtuální funkce mip::AuthDelegate::GetUserConsent(). Postupujte podle kroků popsaných v rychlém startu inicializace aplikace File SDK. Profil ochrany a objekty jádra ochrany vytvářejí instanci delegáta souhlasu a později jej používají.

Vytvoření profilu ochrany a motoru

Jak už bylo zmíněno, klienti sady SDK, kteří používají rozhraní API MIP, vyžadují objekty profilu a modulu. 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_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>(appInfo,
				                                                                                               "mip_data",
                                                                                      			         mip::LogLevel::Trace,
                                                                                                     false,
                                                                                                     mip::CacheStorageType::OnDisk);

  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;
  mMipContext->ShutDown();
  mMipContext = nullptr;

  return 0;
}
  1. Nahraďte všechny zástupné hodnoty ve zdrojovém kódu, které jste 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, kterou jste zaregistrovali v kroku č. 2 článku Instalace a konfigurace sady MIP SDK. Nahraďte 2 instance. "00001111-aaaa-2222-bbbb-3333cccc4444"
    <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ě odpovídá názvu aplikace, který jste použili při 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řidružit k modulu. "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 nespustí se 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 neaktivuje modul ověřování a nemáte 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.