Início rápido: inicialização de aplicativo cliente para SDKs de Proteção (C++)
Esse início rápido mostra como implementar o padrão de inicialização do cliente usado pelo SDK C++ da PIM no runtime.
Observação
As etapas descritas neste início rápido são necessárias para todos os aplicativos clientes que usam os SDKs de Proteção da PIM. 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, faça o seguinte:
- Conclua as etapas em Instalação e configuração do SDK da PIM (Proteção de Informações da Microsoft). Este início rápido "Inicialização do aplicativo cliente" se baseia na instalação e configuração adequadas do SDK.
- Se desejar:
- Examine o Perfil e os objetos do mecanismo. O perfil e os objetos do mecanismo são conceitos universais, exigidos por clientes que usam os SDKs de Arquivo, Políticas e Proteção da PIM.
- Examine os Conceitos de autenticação para saber como a autenticação e o consentimento são implementados pelo SDK e pelo aplicativo cliente.
- Examine os Conceitos do observador para saber mais sobre os observadores e como eles são implementados. O SDK da PIM usa o padrão do observador para implementar notificações de eventos assíncronos.
Criar uma solução e um projeto do Visual Studio
Primeiro, criamos e configuramos a solução e o projeto iniciais do Visual Studio, que serão a base dos outros inícios rápidos.
Abra o Visual Studio 2017, selecione o menu Arquivo, Novo, Projeto. Na caixa de diálogo Novo Projeto:
No painel esquerdo, em Instalado, Outras Linguagens, selecione Visual C++.
No painel central, selecione Aplicativo de Console do Windows
No painel inferior, atualize corretamente o Nome e a Localização do projeto e o Nome da solução que o contém.
Ao terminar, clique no botão OK, no canto inferior direito.
Adicione o pacote Nuget ao SDK de Proteção da PIM do seu projeto:
No Gerenciador de Soluções, clique com o botão direito do mouse sobre o nó do projeto (logo abaixo do nó superior/da solução) e selecione Gerenciar pacotes NuGet...:
Quando a guia Gerenciador de Pacotes NuGet for aberta na área de guias do Grupo do Editor:
- Selecione Procurar.
- Insira "Microsoft.InformationProtection" na caixa de pesquisa.
- Selecione o pacote "Microsoft.InformationProtection.Protection".
- Clique em "Instalar", depois clique em "OK" quando a caixa de diálogo de confirmação Visualizar alterações for exibida.
Implementar classes observadoras para monitorar os objetos de proteção Perfil e Mecanismo
Agora crie uma implementação básica de uma classe observadora com Perfil de proteção, estendendo a classe mip::ProtectionProfile::Observer
do 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.
Adicione uma nova classe ao projeto, que gera os arquivos header/.h e implementation/.cpp para você:
No Gerenciador de Soluções, clique com o botão direito do mouse sobre o nó do projeto novamente, selecione Adicionar e, em seguida, Classe.
Na caixa de diálogo Adicionar Classe:
- No campo Nome de Classe, digite "profile_observer". Observe que os campos Arquivo .h e Arquivo .cpp serão preenchidos automaticamente, de acordo com o nome que você inserir.
- Ao terminar, clique no botão OK.
Após gerar os arquivos .h e .cpp para a classe, os dois arquivos serão abertos nas guias de Grupo do Editor. Agora, atualize cada arquivo para implementar sua nova classe observer:
Atualize "profile_observer.h", selecionando/excluindo a classe
profile_observer
gerada. Não remova as diretivas de pré-processador geradas pela etapa anterior (#pragma, #include). Copie a seguinte fonte e cole-a no arquivo após cada diretiva de pré-processador existente:#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 da classe
profile_observer
gerada. Não remova as diretivas de pré-processador geradas pela etapa anterior (#pragma, #include). Copie a seguinte fonte e cole-a no arquivo após cada diretiva de pré-processador existente:#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); }
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ê.
Após gerar os arquivos .h e .cpp para a classe, os dois arquivos serão abertos nas guias de Grupo do Editor. Agora, atualize cada arquivo para implementar sua nova classe observer:
Atualize "engine_observer.h", selecionando/excluindo a classe
engine_observer
gerada. Não remova as diretivas de pré-processador geradas pela etapa anterior (#pragma, #include). Copie a seguinte fonte e cole-a no arquivo após cada diretiva de pré-processador existente:#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 da classe
engine_observer
gerada. Não remova as diretivas de pré-processador geradas pela etapa anterior (#pragma, #include). Copie a seguinte fonte e cole-a no arquivo após cada diretiva de pré-processador existente:#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); };
Opcionalmente, use Ctrl+Shift+B (Compilar solução) para executar um teste de compilação ou de link da solução, para garantir o êxito da compilação antes de continuar.
Implementar um representante de autenticação e um representante de consentimento
O SDK da PIM implementa a autenticação usando a extensibilidade de classe, que oferece um mecanismo para compartilhar o trabalho de autenticação com o aplicativo cliente. O cliente precisa adquirir um token de acesso OAuth2 adequado e fornecê-lo ao SDK da PIM no runtime.
Agora crie uma implementação para um representante de autenticação, estendendo a classe mip::AuthDelegate
do SDK e substituindo/implementando a função virtual pura mip::AuthDelegate::AcquireOAuth2Token()
. Siga as etapas detalhadas em Início rápido da inicialização do 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.
Implementar um representante de consentimento
Agora crie uma implementação para um representante de consentimento, estendendo a classe mip::ConsentDelegate
do SDK e substituindo/implementando a função virtual pura mip::AuthDelegate::GetUserConsent()
. Siga as etapas detalhadas em Início rápido da inicialização do 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
Como já foi mencionado, os objetos Perfil e Mecanismo são necessários para os clientes do SDK que usam as APIs da PIM. Conclua a parte de codificação deste início rápido adicionando código para criar uma instância para os objetos Perfil e Mecanismo:
No Gerenciador de Soluções, abra o arquivo .cpp do projeto que contém a implementação do método
main()
. Ele usa como padrão o mesmo nome que o projeto em que está contido, que você especificou durante a criação do projeto.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 qualquer diretiva 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;
}
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> A GUID (ID do Aplicativo) do Microsoft Entra atribuída ao aplicativo registrado na etapa 2 do artigo "Configuração e instalação do SDK da PIM" (setup-configure-mip.md). Substitua duas instâncias. "0edbblll-8773-44de-b87c-b8c6276d41eb"
<application-name> Um nome amigável definido pelo usuário para o seu aplicativo. Ele precisa conter caracteres ASCII válidos (sem ';') e preferencialmente corresponder ao nome de aplicativo usado no registro do Microsoft Entra. "AppInitialization"
<application-version> Informações de versão do aplicativo definidas pelo usuário. Deve conter caracteres ASCII válidos (sem ';'). "1.1.0.0"
<engine-account> Conta usada para a identidade do mecanismo. Quando você faz a autenticação com uma conta de usuário durante a aquisição do token, ela deve corresponder a esse valor. "user1@tenant.onmicrosoft.com"
<engine-state> Estado definido pelo usuário a ser associado ao mecanismo. "My App State"
Agora, faça uma compilação final do aplicativo e resolva todos os erros. O código deve ser compilado com sucesso, 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 conforme a seguir. O aplicativo construiria o perfil de Proteção e o mecanismo de Proteção com sucesso, 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 guia de início rápido, em que começará a experimentar os SDKs de Proteção da PIM.