Guia de início rápido: inicialização de aplicativo cliente para SDKs de proteção (C++)

Este quickstart mostra-lhe como implementar o padrão de inicialização do cliente que o SDK MIP C++ usa em tempo de execução.

Observação

Qualquer aplicação cliente que utilize os SDKs de Proteção MIP requer os passos deste início rápido. Conclua estes guias de introdução rápida sequencialmente após a inicialização da aplicação e a implementação das classes de delegado para autenticação e consentimento.

Pré-requisitos

Se ainda não o fez, certifique-se de:

Criar uma solução e um projeto do Visual Studio

Primeiro, crie e configure a solução inicial do Visual Studio e o projeto sobre o qual os outros quickstarts se baseiam.

  1. Abra o Visual Studio 2022 ou versão posterior, selecione o menu Ficheiro , Novo, Projeto. Na caixa de diálogo Novo projeto :

    • No painel esquerdo, em Instalado, Outros Idiomas, selecione Visual C++.

    • No painel central, selecione Aplicativo de Console do Windows.

    • No painel inferior, atualize o nome do projeto, o local e o nome da solução que o contém de acordo.

    • Quando terminar, selecione OK no canto inferior direito.

      Criação de soluções no Visual Studio.

  2. Adicione o pacote NuGet para o SDK de Proteção MIP ao seu projeto:

    • No Explorador de Soluções, clique com o botão direito no nó do projeto diretamente por baixo do nó superior da solução e depois selecione Gerir pacotes NuGet...:

    • Quando a guia Gestor de Pacotes NuGet é aberta na área de guias da secção Grupo de Editores:

      • Selecione Procurar.
      • Digite Microsoft.InformationProtection na caixa de pesquisa.
      • Selecione o Microsoft.InformationProtection.Protection pacote.
      • Selecione Instalar e depois selecione OK quando aparecer o diálogo de confirmação de Pré-visualização de alterações.

      O Visual Studio adiciona o pacote NuGet.

Implementar classes de observador para monitorizar o perfil de proteção e os objetos do motor

Agora crie uma implementação básica para uma classe de observador de perfil de proteção estendendo a classe do mip::ProtectionProfile::Observer SDK. O SDK instancia o observador e usa-o posteriormente para monitorizar o carregamento do objeto do perfil de proteção e adicionar o objeto motor ao perfil.

  1. Adicione uma nova classe ao seu projeto, que gera tanto o cabeçalho (.h) como os ficheiros de implementação (.cpp) para si:

    • No Explorador de Soluções, clique com o botão direito no nó do projeto novamente, selecione Adicionar e depois selecione Classe.

    • Na caixa de diálogo Adicionar classe :

      • No campo Nome da Classe , introduza profile_observer. Repare que Visual Studio preenche automaticamente tanto os campos do ficheiro .h como .cpp com base no nome que inserir.
      • Quando terminar, seleccione OK.

      Visual Studio adiciona classe.

  2. Depois de gerar os ficheiros .h e .cpp para a classe, Visual Studio abre ambos os ficheiros nos separadores do Grupo de Editores. Agora atualize cada arquivo para implementar sua nova classe de observador:

    • Atualize profile_observer.h selecionando e eliminando a classe gerada profile_observer . Não remova as diretivas do pré-processador que o passo anterior gerou (#pragma, #include). Depois, copie e cole a seguinte fonte no ficheiro após quaisquer diretivas do pré-processador existentes:

      #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;
      };
      
    • Atualize profile_observer.cpp selecionando e eliminando a implementação da classe gerada profile_observer . Não remova as diretivas do pré-processador que o passo anterior gerou (#pragma, #include). Depois, copie e cole a seguinte fonte no ficheiro após quaisquer diretivas do pré-processador existentes:

      #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. Repita o passo 1 para adicionar uma nova classe para o observador do motor de Protecção, engine_observer, ao seu projeto. Esta classe gera tanto o cabeçalho (.h) como os ficheiros de implementação (.cpp) para si.

  4. Depois de gerar os ficheiros .h e .cpp para a classe, Visual Studio abre ambos os ficheiros nos separadores do Grupo de Editores. Agora atualize cada arquivo para implementar sua nova classe de observador:

    • Atualize engine_observer.h selecionando e eliminando a classe gerada engine_observer . Não remova as diretivas do pré-processador que o passo anterior gerou (#pragma, #include). Depois, copie e cole a seguinte fonte no ficheiro após quaisquer diretivas do pré-processador existentes:

      #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;
      
      };
      
    • Atualize engine_observer.cpp selecionando e eliminando a implementação da classe gerada engine_observer . Não remova as diretivas do pré-processador que o passo anterior gerou (#pragma, #include). Depois, copie e cole a seguinte fonte no ficheiro após quaisquer diretivas do pré-processador existentes:

      #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. Opcionalmente, use Ctrl+Shift+B (Build Solution) para executar uma compilação e ligação de teste da solução, para verificar se é compilada com êxito antes de continuar.

O MIP SDK implementa a autenticação através da extensibilidade de classes, que fornece um mecanismo para partilhar o trabalho de autenticação com a aplicação cliente. O cliente deve adquirir um token de acesso OAuth2 adequado e fornecê-lo ao MIP SDK em tempo de execução.

Crie uma implementação para um delegado de autenticação estendendo a classe do mip::AuthDelegate SDK e substituindo/implementando a mip::AuthDelegate::AcquireOAuth2Token() função puramente virtual. Siga os passos detalhados na secção guia de iniciação rápida da inicialização da aplicação File SDK. O perfil de proteção e os objetos do motor de proteção instanciam e utilizam posteriormente o delegado de autenticação.

Agora crie uma implementação para um delegado de consentimento estendendo a classe do mip::ConsentDelegate SDK e substituindo/implementando a mip::AuthDelegate::GetUserConsent() função puramente virtual. Siga os passos detalhados na secção guia de iniciação rápida da inicialização da aplicação File SDK. O perfil de proteção e os objetos do motor de proteção instanciam o delegado de consentimento e utilizam-no mais tarde.

Construir um perfil de proteção e um motor

Como mencionado, os clientes SDK que usam APIs MIP requerem objetos de perfil e motor. Complete a parte de codificação deste quickstart adicionando código para instanciar os objetos do perfil e do motor:

  1. No Gerenciador de Soluções, abra o arquivo de .cpp em seu projeto que contém a main() implementação do método. Por padrão, tem o mesmo nome do projeto que o contém, que especificou durante a criação do projeto.

  2. Remova a implementação gerada do main(). Não remova diretivas de pré-processador geradas pelo Visual Studio durante a criação do projeto (#pragma, #include). Anexe o seguinte código após quaisquer diretivas de pré-processador:

#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. Substitua todos os valores provisórios no código-fonte que colou usando constantes de string:

    Marcador de posição Valor Exemplo
    <ID do aplicativo> O ID da aplicação Microsoft Entra (GUID) atribuído à aplicação que registou no passo #2 do artigo de configuração inicial e configuração do SDK MIP. Substitua 2 instâncias. "00001111-aaaa-2222-bbbb-3333cccc4444"
    <nome-aplicativo> Um nome amigável definido pelo usuário para seu aplicativo. Deve conter caracteres ASCII válidos (excluindo '; ') e, idealmente, corresponder ao nome da aplicação que utilizou no seu registo Microsoft Entra. "AppInitialization"
    <versão da aplicação> Informações de versão definidas pelo usuário para seu aplicativo. Deve conter caracteres ASCII válidos (excluindo ';'). "1.1.0.0"
    <conta do mecanismo> A conta usada para a identidade do mecanismo. Quando você se autentica com uma conta de usuário durante a aquisição do token, ela deve corresponder a esse valor. "user1@tenant.onmicrosoft.com"
    <estado do motor> Estado definido pelo utilizador para associar ao motor. "My App State"
  2. Agora faça uma compilação final do aplicativo e resolva quaisquer erros. O teu código deve compilar com sucesso, mas não corre corretamente até completares o próximo quickstart. Se você executar o aplicativo, verá uma saída semelhante à seguinte. A aplicação constrói com sucesso o perfil de Proteção e o motor de Proteção, mas não dispara o módulo de autenticação e não tens um token de acesso até completares o próximo quickstart.

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

Passos seguintes

Agora que o seu código de inicialização está completo, está pronto para o próximo quickstart, onde começa a experimentar o MIP Protection SDK.