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.

Annotazioni

Qualsiasi applicazione client che usa gli SDK di protezione MIP richiede la procedura descritta in questa guida introduttiva. Completare queste guide introduttive in sequenza dopo l'inizializzazione dell'applicazione e l'implementazione delle classi del delegato di autenticazione e del delegato di consenso.

Prerequisiti

Se non è già stato fatto, assicurarsi di:

Creare una soluzione e un progetto di Visual Studio

Prima di tutto, creare e configurare la soluzione iniziale Visual Studio e il progetto su cui si basano gli altri argomenti di avvio rapido.

  1. Aprire Visual Studio 2022 o versione successiva, 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, selezionare OK nell'angolo in basso a destra.

      Creazione di una soluzione di Visual Studio.

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

    • In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo del progetto direttamente sotto il nodo della soluzione superiore e quindi scegliere Gestisci pacchetti NuGet...:

    • Quando si apre la scheda Gestione pacchetti NuGet nell'area schede del Gruppo Editor:

      • Selezionare Sfoglia.
      • Immettere Microsoft.InformationProtection nella casella di ricerca.
      • Selezionare il Microsoft.InformationProtection.Protection pacchetto.
      • Selezionare Installa, quindi selezionare OK quando viene visualizzata la finestra di dialogo di conferma Anteprima delle modifiche.

      Visual Studio aggiungere il pacchetto NuGet.

Implementare classi di osservatore per tenere sotto controllo il profilo di protezione e gli oggetti del motore

Crea ora un'implementazione di base per una classe osservatore del profilo di protezione estendendo la classe mip::ProtectionProfile::Observer dell'SDK. L’SDK istanzia l’osservatore e lo usa successivamente per monitorare il caricamento dell’oggetto profilo di protezione e aggiungere l’oggetto engine al profilo.

  1. Aggiungere una nuova classe al progetto, che genera automaticamente sia i file di intestazione (h) che di implementazione (.cpp):

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

    • Nella finestra di dialogo Aggiungi classe :

      • Nel campo Nome classe immettere profile_observer. Si noti che Visual Studio compila automaticamente i campi file .h e file .cpp in base al nome inserito.
      • Al termine, selezionare OK.

      Visual Studio aggiungere una classe.

  2. Dopo aver generato i file con estensione h e .cpp per la classe , Visual Studio apre entrambi i file nelle schede Gruppo editor. Ora aggiorna ciascun file per implementare la tua nuova classe osservatore.

    • Aggiornare profile_observer.h selezionando ed eliminando la classe generata profile_observer . Non rimuovere le direttive del preprocessore generate dal passaggio precedente (#pragma, #include). Quindi, copia e incolla il codice sorgente seguente nel file dopo eventuali direttive del preprocessore già presenti:

      #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 ed eliminando l'implementazione della classe generata profile_observer . Non rimuovere le direttive del preprocessore generate dal passaggio precedente (#pragma, #include). Quindi, copia e incolla il codice sorgente seguente nel file dopo eventuali direttive del preprocessore già presenti:

      #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. Ripetere il passaggio 1 per aggiungere una nuova classe per l'osservatore del motore di protezione, engine_observer, al progetto. Questa classe genera automaticamente sia i file di intestazione (h) che di implementazione (.cpp).

  4. Dopo aver generato i file con estensione h e .cpp per la classe , Visual Studio apre entrambi i file nelle schede Gruppo editor. Ora aggiorna ciascun file per implementare la tua nuova classe osservatore.

    • Aggiornare engine_observer.h selezionando ed eliminando la classe generata engine_observer . Non rimuovere le direttive del preprocessore generate dal passaggio precedente (#pragma, #include). Quindi, copia e incolla il codice sorgente seguente nel file dopo eventuali direttive del preprocessore già presenti:

      #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 ed eliminando l'implementazione della classe generata engine_observer . Non rimuovere le direttive del preprocessore generate dal passaggio precedente (#pragma, #include). Quindi, copia e incolla il codice sorgente seguente nel file dopo eventuali direttive del preprocessore già presenti:

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

MIP SDK implementa l'autenticazione tramite 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 fornirlo all'SDK MIP in fase di esecuzione.

Crea un'implementazione di un delegato di autenticazione estendendo la classe mip::AuthDelegate dell'SDK e sovrascrivendo/implementando la funzione virtuale pura mip::AuthDelegate::AcquireOAuth2Token(). Seguire i passaggi descritti in Guida introduttiva all'inizializzazione dell'applicazione File SDK. Gli oggetti Protection profile e Protection engine creano un'istanza del delegato di autenticazione e la utilizzano successivamente.

Ora create un'implementazione di un delegato di consenso estendendo la classe dell’SDK mip::ConsentDelegate e sovrascrivendo/implementando la funzione virtuale pura mip::AuthDelegate::GetUserConsent(). Seguire i passaggi descritti in Guida introduttiva all'inizializzazione dell'applicazione File SDK. Gli oggetti del profilo di protezione e del motore di protezione istanziano e utilizzano successivamente il delegato per il consenso.

Creare un profilo e un motore di protezione

Come accennato, i client dell'SDK che usano le API MIP richiedono oggetti profilo e oggetti motore. Completa la parte di codifica di questa guida rapida aggiungendo il codice per istanziare gli oggetti profile ed engine:

  1. In Esplora soluzioni aprire il file .cpp nel progetto che contiene l'implementazione del main() metodo . Per impostazione predefinita, assume lo stesso nome del progetto che lo contiene, 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_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. Sostituisci tutti i valori segnaposto nel codice sorgente che hai incollato utilizzando costanti stringa:

    Placeholder Valore Esempio
    <application-id> L'ID applicazione Microsoft Entra (GUID) assegnato all'applicazione che hai registrato nel passaggio 2 dell'articolo configurazione e impostazione di MIP SDK. Sostituire 2 istanze. "00001111-aaaa-2222-bbbb-3333cccc4444"
    <nome dell'applicazione> Nome descrittivo definito dall'utente per l'applicazione. Deve contenere caratteri ASCII validi (escluso '; ') e idealmente corrisponde al nome dell'applicazione usato nella registrazione Microsoft Entra. "AppInitialization"
    <versione dell'applicazione> 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 viene 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 crea correttamente il profilo di protezione e il motore di protezione, ma non attiva il modulo di autenticazione e non si ottiene un token di accesso finché 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

Ora che il codice di inizializzazione è completo, sei pronto per la successiva guida introduttiva rapida, in cui inizierai a scoprire l'SDK MIP Protection.