Guida introduttiva: Inizializzazione dell'applicazione client per gli SDK di protezione (C++)

Questa guida introduttiva illustra come implementare il modello di inizializzazione client, usato da MIP C++ SDK in fase di esecuzione.

Nota

I passaggi descritti in questa guida introduttiva sono necessari per qualsiasi applicazione client che usa gli SDK di protezione MIP. Queste guide di avvio rapido devono essere eseguite in modo seriale dopo l'inizializzazione dell'applicazione e l'implementazione delle classi delegate di autenticazione e del delegato di consenso.

Prerequisiti

Se non è già stato fatto, assicurarsi di:

  • Completare i passaggi della configurazione e della configurazione di Microsoft Information Protection SDK (MIP). Questa guida introduttiva all'inizializzazione dell'applicazione client si basa sull'installazione e la configurazione appropriate dell'SDK.
  • Facoltativamente:
    • Esaminare gli oggetti profilo e motore. I profili e gli oggetti motore sono concetti universali, richiesti dai client che usano gli SDK di protezione/file/criteri MIP.
    • Vedere Concetti relativi all'autenticazione per informazioni sull'implementazione dell'autenticazione e del consenso da parte dell'SDK e dell'applicazione client.
    • Esaminare i concetti di Observer per altre informazioni sugli osservatori e su come vengono implementati. MIP SDK usa il modello observer per implementare le notifiche degli eventi asincrone.

Creare una soluzione e un progetto di Visual Studio

Prima di tutto si crea e si configura la soluzione e il progetto iniziale di Visual Studio, in cui vengono compilate le altre guide introduttive.

  1. Aprire Visual Studio 2017, selezionare il menu File , Nuovo, Progetto. Nella finestra di dialogo Nuovo progetto :

    • Nel riquadro sinistro, in Installato, Altri linguaggi selezionare Visual C++.

    • Nel riquadro centrale selezionare Applicazione console di Windows

    • Nel riquadro inferiore aggiornare di conseguenza il nome del progetto, il percorso e il nome della soluzione che lo contiene.

    • Al termine, fare clic sul pulsante OK in basso a destra.

      Visual Studio solution creation

  2. Aggiungere il pacchetto Nuget per MIP Protection SDK al progetto:

    • Nella Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo del progetto (direttamente sotto il nodo superiore/soluzione) e selezionare Gestisci pacchetti NuGet...:

    • Quando si apre la scheda Gestione pacchetti NuGet nell'area Schede Gruppo editor:

      • Selezionare Sfoglia.
      • Immettere "Microsoft.InformationProtection" nella casella di ricerca.
      • Selezionare il pacchetto "Microsoft.InformationProtection.Protection".
      • Fare clic su "Installa", quindi su "OK" quando viene visualizzata la finestra di dialogo di conferma delle modifiche dell'anteprima.

      Visual Studio add NuGet package

Implementare classi observer per monitorare il profilo di protezione e gli oggetti motore

Creare ora un'implementazione di base per una classe observer del profilo protezione estendendo la classe dell'SDK mip::ProtectionProfile::Observer . L'osservatore viene creata e usata in un secondo momento per monitorare il caricamento dell'oggetto profilo protezione e l'aggiunta dell'oggetto motore al profilo.

  1. Aggiungere una nuova classe al progetto, che genera automaticamente i file header/.h e implementation/.cpp:

    • Nel Esplora soluzioni fare di nuovo clic con il pulsante destro del mouse sul nodo del progetto, selezionare Aggiungi e quindi selezionare Classe.

    • Nella finestra di dialogo Aggiungi classe :

      • Nel campo Nome classe immettere "profile_observer". Si noti che i campi del file con estensione h e cpp vengono popolati automaticamente in base al nome immesso.
      • Al termine, fare clic sul pulsante OK .

      Visual Studio add class

  2. Dopo aver generato i file con estensione h e cpp per la classe , entrambi i file vengono aperti nelle schede Gruppo editor. Aggiornare ora ogni file per implementare la nuova classe observer:

    • Aggiornare "profile_observer.h" selezionando/eliminando la classe generata profile_observer . Non rimuovere le direttive del preprocessore generate dal passaggio precedente (#pragma, #include). Copiare/incollare quindi l'origine seguente nel file, dopo eventuali direttive del preprocessore esistenti:

      #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;
      };
      
    • Aggiornare "profile_observer.cpp" selezionando/eliminando l'implementazione della classe generata profile_observer . Non rimuovere le direttive del preprocessore generate dal passaggio precedente (#pragma, #include). Copiare/incollare quindi l'origine seguente nel file, dopo eventuali direttive del preprocessore esistenti:

      #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. Seguire i passaggi descritti in 1. aggiungere una nuova classe per l'osservatore del motore di protezione : "engine_observer" al progetto, che genera automaticamente sia i file header/.h che implementation/.cpp.

  4. Dopo aver generato i file con estensione h e cpp per la classe , entrambi i file vengono aperti nelle schede Gruppo editor. Aggiornare ora ogni file per implementare la nuova classe observer:

    • Aggiornare "engine_observer.h" selezionando/eliminando la classe generata engine_observer . Non rimuovere le direttive del preprocessore generate dal passaggio precedente (#pragma, #include). Copiare/incollare quindi l'origine seguente nel file, dopo eventuali direttive del preprocessore esistenti:

      #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;
      
      };
      
    • Aggiornare "engine_observer.cpp" selezionando/eliminando l'implementazione della classe generata engine_observer . Non rimuovere le direttive del preprocessore generate dal passaggio precedente (#pragma, #include). Copiare/incollare quindi l'origine seguente nel file, dopo eventuali direttive del preprocessore esistenti:

      #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. Facoltativamente, usare CTRL+MAIUSC+B (Compila soluzione) per eseguire una compilazione/collegamento di test della soluzione per assicurarsi che venga compilata correttamente prima di continuare.

MIP SDK implementa l'autenticazione usando l'estendibilità della classe, che fornisce un meccanismo per condividere l'autenticazione con l'applicazione client. Il client deve acquisire un token di accesso OAuth2 appropriato e fornire all'SDK MIP in fase di esecuzione.

Creare un'implementazione per un delegato di autenticazione estendendo la classe dell'SDK mip::AuthDelegate ed eseguendo l'override/implementazione della mip::AuthDelegate::AcquireOAuth2Token() funzione virtuale pura. Seguire i passaggi descritti in Guida introduttiva all'inizializzazione dell'applicazione File SDK. Il delegato di autenticazione viene creata un'istanza e usata successivamente dagli oggetti del motore protezione e del profilo protezione.

Creare ora un'implementazione per un delegato di consenso estendendo la classe dell'SDK mip::ConsentDelegate ed eseguendo l'override/implementazione della mip::AuthDelegate::GetUserConsent() funzione virtuale pura. Seguire i passaggi descritti in Guida introduttiva all'inizializzazione dell'applicazione File SDK. Il delegato di consenso viene creata un'istanza e usata in un secondo momento dagli oggetti profilo protezione e motore protezione.

Creare un profilo e un motore di protezione

Come accennato, gli oggetti profilo e motore sono necessari per i client SDK che usano le API MIP. Completare la parte di scrittura del codice di questa guida introduttiva aggiungendo codice per creare un'istanza degli oggetti profilo e motore:

  1. Da Esplora soluzioni aprire il file con estensione cpp nel progetto che contiene l'implementazione del main() metodo . Per impostazione predefinita, il nome del progetto che lo contiene è stato specificato durante la creazione del progetto.

  2. Rimuovere l'implementazione generata di main(). Non rimuovere le direttive del preprocessore generate da Visual Studio durante la creazione del progetto (#pragma, #include). Aggiungere il codice seguente dopo qualsiasi direttiva del preprocessore:

#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. Sostituire tutti i valori segnaposto nel codice sorgente appena incollato, usando costanti stringa:

    Segnaposto Valore Esempio
    <application-id> ID applicazione Microsoft Entra (GUID) assegnato all'applicazione registrata nel passaggio 2 dell'articolo "Configurazione e configurazione di MIP SDK" (setup-configure-mip.md). Sostituire 2 istanze. "0edbblll-8773-44de-b87c-b8c6276d41eb"
    <application-name> Nome descrittivo definito dall'utente per l'applicazione. Deve contenere caratteri ASCII validi (esclusi ';') e idealmente corrisponde al nome dell'applicazione usato nella registrazione di Microsoft Entra. "AppInitialization"
    <application-version> Informazioni sulla versione definite dall'utente per l'applicazione. Deve contenere caratteri ASCII validi (escluso ';'). "1.1.0.0"
    <engine-account> Account usato per l'identità del motore. Quando si esegue l'autenticazione con un account utente durante l'acquisizione del token, deve corrispondere a questo valore. "user1@tenant.onmicrosoft.com"
    <stato del motore> Stato definito dall'utente da associare al motore. "My App State"
  2. A questo punto, eseguire una compilazione finale dell'applicazione e risolvere eventuali errori. Il codice dovrebbe essere compilato correttamente, ma non verrà ancora eseguito correttamente fino a quando non si completa la guida introduttiva successiva. Se si esegue l'applicazione, viene visualizzato un output simile al seguente. L'applicazione costruisce correttamente il profilo di protezione e il motore di protezione, ma non avrebbe attivato il modulo di autenticazione e non si avrà ancora un token di accesso, fino a quando non si completa la guida introduttiva successiva.

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

Passaggi successivi

Dopo aver completato il codice di inizializzazione, si è pronti per la guida introduttiva successiva, in cui si inizierà a usare MIP Protection SDK.