Compartilhar via


Início Rápido: Inicialização do aplicativo cliente para SDKs de Proteção (C++)

Este início rápido mostra como implementar o padrão de inicialização do cliente, usado pelo SDK do MIP C++ em runtime.

Observação

As etapas descritas neste início rápido são necessárias para qualquer aplicativo cliente que use os SDKs de Proteção MIP. Esses inícios rápidos devem ser feitos em ordem após a Inicialização do Aplicativo e a implementação das classes Representante de Autenticação e Representante de Consentimento.

Pré-requisitos

Caso ainda não tenha feito isso, certifique-se de:

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

Primeiro, criamos e configuramos a solução e o projeto iniciais do Visual Studio, nos quais os outros Inícios Rápidos são compilados.

  1. Abra o Visual Studio 2019 ou posterior, selecione o menu Arquivo , Novo, Projeto. Na caixa de diálogo Novo Projeto :

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

    • No painel central, selecione Aplicativo do Console do Windows

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

    • Quando terminar, clique no botão OK no canto inferior direito.

      Criação de solução do Visual Studio

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

    • No Gerenciador de Soluções, clique com o botão direito do mouse no nó do projeto (diretamente no nó superior/solução) e selecione Gerenciar pacotes NuGet...:

    • Quando a guia Gerenciador de Pacotes NuGet é aberta na área de guias Grupo do Editor:

      • Selecione Procurar.
      • Insira "Microsoft.InformationProtection" na caixa de pesquisa.
      • Selecione o pacote "Microsoft.InformationProtection.Protection".
      • Clique em "Instalar" e, em seguida, clique em "OK" quando a caixa de diálogo de confirmação Visualizar alterações for exibida.

      Adicionar pacote NuGet do Visual Studio

Implementar classes observadoras para monitorar os objetos de proteção Perfil e Mecanismo

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. Uma instância da classe observadora é criada e usada posteriormente para monitorar o carregamento do objeto Perfil de proteção e adicionar o objeto Mecanismo ao perfil.

  1. Adicione uma nova classe ao projeto, que gera os arquivos de cabeçalho/.h e implementação/.cpp para você:

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

    • Na caixa de diálogo Adicionar Classe :

      • No campo Nome da Classe , insira "profile_observer". Observe que o arquivo .h e os campos de arquivo .cpp são preenchidos automaticamente, com base no nome inserido.
      • Quando terminar, clique no botão OK .

      Classe de adição do Visual Studio

  2. Depois de gerar os arquivos .h e .cpp para a classe, ambos os arquivos são abertos nas guias Grupo de Editores. Agora atualize cada arquivo para implementar sua nova classe de observador:

    • Atualize "profile_observer.h", selecionando/excluindo a classe gerada profile_observer . Não remova as diretivas de pré-processador geradas pela etapa anterior (#pragma, #include). Em seguida, copie/cole a seguinte fonte no arquivo, depois de quaisquer diretivas de 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/excluindo a implementação de classe gerada profile_observer . Não remova as diretivas de pré-processador geradas pela etapa anterior (#pragma, #include). Em seguida, copie/cole a seguinte fonte no arquivo, depois de quaisquer diretivas de 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. Seguindo etapas em 1. Adicione uma nova classe ao observador do mecanismo de Proteção – "engine_observer" ao seu projeto, o que vai gerar os arquivos header/.h e implementation/.cpp para você.

  4. Depois de gerar os arquivos .h e .cpp para a classe, ambos os arquivos são abertos nas guias Grupo de Editores. Agora atualize cada arquivo para implementar sua nova classe de observador:

    • Atualize "engine_observer.h", selecionando/excluindo a classe gerada engine_observer . Não remova as diretivas de pré-processador geradas pela etapa anterior (#pragma, #include). Em seguida, copie/cole a seguinte fonte no arquivo, depois de quaisquer diretivas de 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/excluindo a implementação de classe gerada engine_observer . Não remova as diretivas de pré-processador geradas pela etapa anterior (#pragma, #include). Em seguida, copie/cole a seguinte fonte no arquivo, depois de quaisquer diretivas de 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<shared_ptr<mip::ProtectionProfile>>*>(context.get());
          loadPromise->set_exception(Failure);
        };
      
  5. Opcionalmente, use Ctrl+Shift+B (Build Solution) para executar uma compilação/link de teste da solução, para garantir que ela seja compilada com êxito antes de continuar.

O SDK do MIP implementa a autenticação usando extensibilidade de classe, que fornece um mecanismo para compartilhar o trabalho de autenticação com o aplicativo cliente. O cliente deve adquirir um token de acesso OAuth2 adequado e fornecer ao SDK do MIP em runtime.

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 virtual pura. Siga as etapas detalhadas no Início Rápido de Inicialização de Aplicativo do SDK de Arquivo. É criada uma instância para o representante de autenticação ser usado posteriormente pelos objetos Mecanismo e Perfil de Proteçã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 virtual pura. Siga as etapas detalhadas no Início Rápido de Inicialização de Aplicativo do SDK de Arquivo. O representante de consentimento é instanciado e usado posteriormente pelos objetos Mecanismo e Perfil de Proteção.

Criar um perfil e um mecanismo de Proteção

Conforme mencionado, os objetos de perfil e mecanismo são necessários para clientes do SDK usando APIs de MIP. Conclua a parte de codificação deste Início Rápido adicionando código para instanciar os objetos de perfil e mecanismo:

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

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

#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. Substitua todos os valores de espaço reservado existentes no código-fonte que você acabou de colar usando constantes de cadeia de caracteres:

    Espaço reservado Valor Exemplo
    <application-id> O Microsoft Entra Application ID (GUID) atribuído ao aplicativo registrado na etapa 2 do artigo "Instalação e configuração do SDK do MIP" (setup-configure-mip.md). Substitua duas instâncias. "0edbblll-8773-44de-b87c-b8c6276d41eb"
    <nome do aplicativo> Um nome amigável definido pelo usuário para seu aplicativo. Deve conter caracteres ASCII válidos (excluindo ';') e, idealmente, corresponde ao nome do aplicativo usado no registro do Microsoft Entra. "AppInitialization"
    <versão do aplicativo> Informações de versão definidas pelo usuário para seu aplicativo. Deve conter caracteres ASCII válidos (excluindo ';'). "1.1.0.0"
    <engine-account> Conta usada para a identidade do mecanismo. Quando você se autentica com uma conta de usuário durante a aquisição do token, ele deve corresponder a esse valor. "user1@tenant.onmicrosoft.com"
    <estado do mecanismo> Estado definido pelo usuário a ser associado ao mecanismo. "My App State"
  2. Agora, faça um build final do aplicativo e resolva quaisquer erros. Seu código deve ser compilado com êxito, mas ainda não será executado corretamente até que você conclua o próximo Início Rápido. Se você executar o aplicativo, verá uma saída semelhante à seguinte. O aplicativo construiria o perfil de proteção e o mecanismo de proteção com êxito, mas não teria disparado o módulo de autenticação e você ainda não terá um token de acesso, até concluir o próximo Início Rápido.

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

Próximas etapas

Agora que o código de inicialização está concluído, você está pronto para o próximo início rápido, no qual começará a experimentar o SDK da Proteção MIP.