Schnellstart: Clientanwendungsinitialisierung für Schutz-SDKs (C++)

In dieser Schnellstartanleitung erfahren Sie, wie Sie das Clientinitialisierungsmuster implementieren, das vom MIP C++-SDK zur Laufzeit verwendet wird.

Hinweis

Die in dieser Schnellstartanleitung beschriebenen Schritte sind für jede Clientanwendung erforderlich, die die MIP-Schutz-SDKs verwendet. Diese Schnellstarts sollten nach der Anwendungsinitialisierung und Implementierung von Authentifizierungsdelegat- und Zustimmungsdelegatklassen serialisiert werden.

Voraussetzungen

Falls noch nicht geschehen, stellen Sie sicher, dass Sie:

  • Führen Sie die Schritte im Microsoft Information Protection (MIP)-SDK-Setup und -Konfiguration aus. Diese Schnellstartanleitung "Clientanwendungsinitialisierung" basiert auf der richtigen SDK-Einrichtung und -Konfiguration.
  • Optional:
    • Überprüfen Sie Profil- und Modulobjekte. Die Profil- und Modulobjekte sind universelle Konzepte, die von Clients benötigt werden, die die MIP File/Policy/Protection SDKs verwenden.
    • Überprüfen Sie die Authentifizierungskonzepte , um zu erfahren, wie Authentifizierung und Zustimmung vom SDK und der Clientanwendung implementiert werden.
    • Überprüfen Sie die Beobachterkonzepte , um mehr über Beobachter zu erfahren und wie sie implementiert werden. Das MIP SDK verwendet das Beobachtermuster, um asynchrone Ereignisbenachrichtigungen zu implementieren.

Visual Studio-Lösung und Projekt erstellen

Zuerst erstellen und konfigurieren wir die erste Visual Studio-Projektmappe und das erste Projekt, auf dem die anderen Schnellstarts erstellt werden.

  1. Öffnen Sie Visual Studio 2022 oder höher, wählen Sie das Menü "Datei ", "Neu", "Projekt" aus. Im Dialogfeld "Neues Projekt ":

    • Wählen Sie im linken Bereich unter "Installiert", "Andere Sprachen" die Option "Visual C++" aus.

    • Wählen Sie im mittleren Bereich die Windows-Konsolenanwendung aus.

    • Aktualisieren Sie im unteren Bereich den Projektnamen, den Speicherort und den Lösungsnamen entsprechend.

    • Wenn Sie fertig sind, klicken Sie unten rechts auf die Schaltfläche "OK ".

      Erstellen von Visual Studio-Lösungen

  2. Fügen Sie das NuGet-Paket für das MIP Protection SDK zu Ihrem Projekt hinzu:

    • Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten (direkt unter dem oberen/Projektmappenknoten), und wählen Sie "NuGet-Pakete verwalten"...:

    • Wenn die Registerkarte "NuGet-Paket-Manager " im Bereich "Editorgruppe" geöffnet wird:

      • Tippen Sie auf Browse (Durchsuchen).
      • Geben Sie "Microsoft.InformationProtection" in das Suchfeld ein.
      • Wählen Sie das Paket "Microsoft.InformationProtection.Protection" aus.
      • Klicken Sie auf "Installieren" und dann auf "OK", wenn der Bestätigungsdialog "Änderungen anzeigen" angezeigt wird.

      Visual Studio: NuGet-Paket hinzufügen

Implementiere Beobachterklassen zur Überwachung des Schutzprofils und der Engine-Objekte.

Erstellen Sie nun eine grundlegende Implementierung für eine Protection-Profilbeobachterklasse, indem Sie die SDK-Klasse mip::ProtectionProfile::Observer erweitern. Der Beobachter wird instanziiert und später verwendet, um das Laden des Schutzprofilobjekts zu überwachen. Danach wird das Engine-Objekt zum Profil hinzugefügt.

  1. Fügen Sie Ihrem Projekt eine neue Klasse hinzu, die sowohl die Header/.h- als auch die Implementierungs-/.cpp dateien für Sie generiert:

    • Klicken Sie im Projektmappen-Explorer erneut mit der rechten Maustaste auf den Projektknoten, wählen Sie "Hinzufügen" und dann "Klasse" aus.

    • Im Dialogfeld "Klasse hinzufügen ":

      • Geben Sie im Feld "Klassenname " "profile_observer" ein. Beachten Sie, dass sowohl die H-Datei als auch .cpp Dateifelder basierend auf dem eingegebenen Namen automatisch ausgefüllt werden.
      • Klicken Sie abschließend auf die Schaltfläche "OK ".

      Visual Studio-Klasse hinzufügen

  2. Nach dem Generieren der .h- und .cpp-Dateien für die Klasse werden beide Dateien in Editorgruppentabs geöffnet. Aktualisieren Sie nun jede Datei, um Ihre neue Beobachterklasse zu implementieren:

    • Aktualisieren Sie "profile_observer.h", indem Sie die generierte profile_observer Klasse auswählen/löschen. Entfernen Sie die vom vorherigen Schritt generierten Präprozessordirektiven nicht (#pragma, #include). Kopieren/fügen Sie dann die folgende Quelle nach vorhandenen Präprozessordirektiven in die Datei ein:

      #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;
      };
      
    • Aktualisieren Sie "profile_observer.cpp", indem Sie die generierte profile_observer Klassenimplementierung auswählen/löschen. Entfernen Sie die vom vorherigen Schritt generierten Präprozessordirektiven nicht (#pragma, #include). Kopieren/fügen Sie dann die folgende Quelle nach vorhandenen Präprozessordirektiven in die Datei ein:

      #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. Führen Sie die Schritte unter Punkt 1 aus. Fügen Sie ihrem Projekt eine neue Klasse für den Schutzmodulbeobachter "engine_observer" hinzu, die sowohl die Header-/.h- als auch die Implementierungs-/.cpp dateien für Sie generiert.

  4. Nach dem Generieren der .h- und .cpp-Dateien für die Klasse werden beide Dateien in Editorgruppen-Registern geöffnet. Aktualisieren Sie nun jede Datei, um Ihre neue Beobachterklasse zu implementieren:

    • Aktualisieren Sie "engine_observer.h", indem Sie die generierte engine_observer Klasse auswählen/löschen. Entfernen Sie die vom vorherigen Schritt generierten Präprozessordirektiven nicht (#pragma, #include). Kopieren/fügen Sie dann die folgende Quelle nach vorhandenen Präprozessordirektiven in die Datei ein:

      #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;
      
      };
      
    • Aktualisieren Sie "engine_observer.cpp", indem Sie die generierte engine_observer Klassenimplementierung auswählen/löschen. Entfernen Sie die vom vorherigen Schritt generierten Präprozessordirektiven nicht (#pragma, #include). Kopieren/fügen Sie dann die folgende Quelle nach vorhandenen Präprozessordirektiven in die Datei ein:

      #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. Verwenden Sie optional STRG+UMSCHALT+B (Projektmappe erstellen), um eine Testkompilierung/Verknüpfung Ihrer Lösung auszuführen, um sicherzustellen, dass sie erfolgreich erstellt wird, bevor Sie fortfahren.

Das MIP SDK implementiert die Authentifizierung durch Erweiterung der Klassen, was einen Mechanismus bereitstellt, um die Authentifizierungsprozesse mit der Clientanwendung zu teilen. Der Client muss ein geeignetes OAuth2-Zugriffstoken erwerben und es zur Laufzeit dem MIP SDK übergeben.

Erstellen Sie eine Implementierung für einen Authentifizierungsdelegat, indem Sie die Klasse des mip::AuthDelegate SDK erweitern und die mip::AuthDelegate::AcquireOAuth2Token() reine virtuelle Funktion außer Kraft setzen/implementieren. Führen Sie die unter File SDK Application Initialization Quickstart beschriebenen Schritte aus. Der Authentifizierungsdelegat wird instanziiert und später von den Schutzprofil- und Schutzmodulobjekten verwendet.

Erstellen Sie nun eine Implementierung für einen Zustimmungsdelegat, indem Sie die Klasse des mip::ConsentDelegate SDK erweitern und die mip::AuthDelegate::GetUserConsent() reine virtuelle Funktion außer Kraft setzen/implementieren. Führen Sie die unter File SDK Application Initialization Quickstart beschriebenen Schritte aus. Der Zustimmungsdelegat wird instanziiert und später von den Schutzprofil- und Schutzmodulobjekten verwendet.

Ein Schutzprofil und eine Engine konstruieren

Wie erwähnt, sind Profil- und Modulobjekte für SDK-Clients mit MIP-APIs erforderlich. Schließen Sie den Codierungsteil dieser Schnellstartanleitung ab, indem Sie Code zum Instanziieren der Profil- und Modulobjekte hinzufügen:

  1. Öffnen Sie im Projektmappen-Explorer die datei .cpp in Ihrem Projekt, die die Implementierung der main() Methode enthält. Standardmäßig wird derselbe Name wie das Projekt verwendet, das es enthält, das Sie während der Projekterstellung angegeben haben.

  2. Entfernen Sie die generierte Implementierung von main(). Entfernen Sie während der Projekterstellung (#pragma, #include) von Visual Studio generierte Präprozessordirektiven nicht. Fügen Sie den folgenden Code nach allen Präprozessordirektiven an:

#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. Ersetzen Sie alle Platzhalterwerte im soeben eingefügten Quellcode durch Zeichenfolgenkonstanten:

    Platzhalter Wert Example
    <application-id> Die Microsoft Entra-Anwendungs-ID (GUID), die der Anwendung zugewiesen ist, die in Schritt 2 des Artikels "MIP SDK-Setup und -Konfiguration" (setup-configure-mip.md) registriert ist. Ersetzen Sie zwei Instanzen. "0edbblll-8773-44de-b87c-b8c6276d41eb"
    <Anwendungsname> Ein benutzerdefinierter freundlicher Name für Ihre Anwendung. Muss gültige ASCII-Zeichen (mit Ausnahme von ';') enthalten und entspricht idealerweise dem Anwendungsnamen, den Sie in Ihrer Microsoft Entra-Registrierung verwendet haben. "AppInitialization"
    <Anwendungsversion> Benutzerdefinierte Versionsinformationen für Ihre Anwendung. Muss gültige ASCII-Zeichen enthalten (mit Ausnahme von ';'). "1.1.0.0"
    <Engine-Konto> Das Konto, das für die Identität der Engine verwendet wird. Wenn Sie sich während des Tokenerwerbs mit einem Benutzerkonto authentifizieren, muss er diesem Wert entsprechen. "user1@tenant.onmicrosoft.com"
    <Modulzustand> Benutzerdefinierter Zustand, der mit der Engine verknüpft werden soll. "My App State"
  2. Führen Sie nun einen endgültigen Build der Anwendung aus, und beheben Sie alle Fehler. Ihr Code sollte erfolgreich erstellt werden, wird aber noch nicht ordnungsgemäß ausgeführt, bis Sie die nächste Schnellstartanleitung abgeschlossen haben. Wenn Sie die Anwendung ausführen, wird die Ausgabe ähnlich wie folgt angezeigt. Die Anwendung würde das Schutzprofil und die Schutz-Engine erfolgreich erstellen, aber das Authentifizierungsmodul nicht ausgelöst haben, und Sie würden noch kein Zugriffstoken haben, bis Sie den nächsten Quickstart abgeschlossen haben.

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

Nächste Schritte

Nachdem der Initialisierungscode abgeschlossen ist, sind Sie bereit für den nächsten Schnellstart, bei dem Sie erste Erfahrungen mit dem MIP Protection SDK sammeln.