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

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

Hinweis

Jede Clientanwendung, die die MIP-Schutz-SDKs verwendet, erfordert die Schritte in dieser Schnellstartanleitung. Führen Sie diese Schnellstartanleitungen nacheinander nach der Initialisierung der Anwendung und der Implementierung der Klassen für den Authentifizierungsdelegaten und den Zustimmungsdelegaten aus.

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 für die 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

Erstellen und konfigurieren Sie zunächst die erste Visual Studio Lösung und projekt, auf der die anderen Schnellstarts aufbauen.

  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 Name, Speicherort und den darin enthaltenen Projektmappennamen des Projekts.

    • Wenn Sie fertig sind, wählen Sie in der unteren rechten Ecke "OK " aus.

      Visual Studio Lösungserstellung.

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

    • Klicken Sie in Projektmappen-Explorer mit der rechten Maustaste auf den Projektknoten direkt unter dem oberen Lösungsknoten, und wählen Sie dann "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 Microsoft.InformationProtection.Protection Paket aus.
      • Wählen Sie "Installieren" und dann "OK " aus, wenn das Bestätigungsdialogfeld "Vorschau" angezeigt wird.

      Visual Studio NuGet-Paket hinzufügen.

Implementieren von Observer-Klassen zum Überwachen des Protection-Profil- und -Engine-Objekte

Erstellen Sie nun eine grundlegende Implementierung für eine Protection-Profilbeobachterklasse, indem Sie die SDK-Klasse mip::ProtectionProfile::Observer erweitern. Das SDK instanziiert den Observer und verwendet ihn später, um das Laden des Objekts des Schutzprofils zu überwachen und das Engine-Objekt dem Profil hinzuzufügen.

  1. Fügen Sie Ihrem Projekt eine neue Klasse hinzu, die sowohl die Headerdateien (H) als auch implementierungsdateien (.cpp) für Sie generiert:

    • Klicken Sie in 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 " die Zeichenfolge profile_observerein. Beachten Sie, dass Visual Studio sowohl die H-Datei als auch .cpp Dateifelder basierend auf dem eingegebenen Namen automatisch auffüllt.
      • Wenn Sie fertig sind, wählen Sie OK aus.

      Visual Studio Klasse hinzufügen.

  2. Nach dem Generieren der .h- und .cpp-Dateien für die Klasse öffnet Visual Studio beide Dateien in Editorgruppen-Registerkarten. 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 und löschen. Entfernen Sie nicht die Präprozessordirektiven, die der vorherige Schritt generiert hat (#pragma, #include). Kopieren Sie dann die folgende Quelle, und fügen Sie sie 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 Klassenimplementierung von profile_observer auswählen und löschen. Entfernen Sie nicht die Präprozessordirektiven, die der vorherige Schritt generiert hat (#pragma, #include). Kopieren Sie dann die folgende Quelle, und fügen Sie sie 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. Wiederholen Sie Schritt 1, um Ihrem Projekt eine neue Klasse für den Beobachter der Protection-Engine, engine_observer, hinzuzufügen. Diese Klasse generiert sowohl die Headerdateien (H) als auch implementierungsdateien (.cpp) für Sie.

  4. Nach dem Generieren der .h- und .cpp-Dateien für die Klasse öffnet Visual Studio beide Dateien in Editorgruppen-Registerkarten. 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 und löschen. Entfernen Sie nicht die Präprozessordirektiven, die der vorherige Schritt generiert hat (#pragma, #include). Kopieren Sie dann die folgende Quelle, und fügen Sie sie 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 Klassenimplementierung von engine_observer auswählen und löschen. Entfernen Sie nicht die Präprozessordirektiven, die der vorherige Schritt generiert hat (#pragma, #include). Kopieren Sie dann die folgende Quelle, und fügen Sie sie 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<vector<shared_ptr<mip::TemplateDescriptor>>>*>(context.get());
          loadPromise->set_exception(Failure);
        };
      
  5. Verwenden Sie optional STRG+UMSCHALT+B (Projektmappe erstellen), um eine Testkompilierung und einen Link Ihrer Lösung auszuführen, um sicherzustellen, dass sie erfolgreich erstellt wurde, bevor Sie fortfahren.

Das MIP-SDK realisiert die Authentifizierung durch Klassen-Erweiterbarkeit und stellt damit einen Mechanismus bereit, um den Authentifizierungsaufwand mit der Clientanwendung zu teilen. Der Client muss ein geeignetes OAuth2-Zugriffstoken erwerben und es zur Laufzeit dem MIP SDK bereitstellen.

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 schritte aus, die im Schnellstart der Datei-SDK-Anwendungsinitialisierung beschrieben sind. Das Schutzprofil und die Schutzmodulobjekte instanziieren den Authentifizierungs-Delegaten und verwenden ihn später.

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 schritte aus, die im Schnellstart der Datei-SDK-Anwendungsinitialisierung beschrieben sind. Die Objekte „Protection profile“ und „Protection engine“ instanziieren den Consent-Delegaten und verwenden ihn später.

Ein Schutzprofil und eine Engine konstruieren

Wie erwähnt, erfordern SDK-Clients, die MIP-APIs verwenden, Profil- und Modulobjekte. Schließen Sie den Codierungsteil dieser Schnellstartanleitung ab, indem Sie Code hinzufügen, um die Profil- und Modulobjekte zu instanziieren:

  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_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. Ersetzen Sie alle Platzhalterwerte im Quellcode, den Sie mithilfe von Zeichenfolgenkonstanten eingefügt haben:

    Platzhalter Wert Example
    <application-id> Die Microsoft Entra Anwendungs-ID (GUID), die Der Anwendung zugewiesen ist, die Sie in Schritt 2 des MIP SDK-Setup- und Konfigurationsartikels registriert haben. Ersetzen Sie zwei Instanzen. "00001111-aaaa-2222-bbbb-3333cccc4444"
    <Anwendungsname> Ein benutzerdefinierter freundlicher Name für Ihre Anwendung. Sie muss gültige ASCII-Zeichen enthalten (mit Ausnahme von '; ') und entspricht idealerweise dem Anwendungsnamen, den Sie in Ihrer Microsoft Entra Registrierung verwendet haben. "AppInitialization"
    <Anwendungsversion> Benutzerdefinierte Versionsinformationen für Ihre Anwendung. Er 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 zur Verknüpfung mit der Engine. "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 erst ordnungsgemäß ausgeführt, wenn Sie die nächste Schnellstartanleitung abgeschlossen haben. Wenn Sie die Anwendung ausführen, wird die Ausgabe ähnlich wie folgt angezeigt. Die Anwendung erstellt das Schutzprofil und das Schutzmodul erfolgreich, löst jedoch nicht das Authentifizierungsmodul aus, und Sie verfügen erst über ein Zugriffstoken, nachdem Sie die nächste Schnellstartanleitung 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 Sie den Initialisierungscode abgeschlossen haben, können Sie mit dem nächsten Schnellstart fortfahren, in dem Sie erste Erfahrungen mit dem MIP Protection SDK sammeln.