Início Rápido: definir e obter um rótulo de confidencialidade (C++)

Este Início Rápido mostra mais casos de uso dos SDKs de arquivo da PIM. Com um dos rótulos de confidencialidade listados no Início Rápido anterior, você usa um manipulador de arquivos para definir/obter o rótulo em um arquivo. A classe do manipulador de arquivos expõe várias operações para definir/obter rótulos ou proteção para tipos de arquivo com suporte.

Pré-requisitos

Conclua os seguintes pré-requisitos antes de continuar, caso ainda não tenha feito isso:

Implementar uma classe de observador para monitorar o objeto de manipulador de arquivos

Semelhante ao observador que você implementou (para o perfil e mecanismo Arquivo) no Início Rápido de inicialização de aplicativo, agora você implementa uma classe de observador para um objeto de manipulador de arquivos.

Crie uma implementação básica para um observador de manipulador de arquivos, estendendo a classe mip::FileHandler::Observer do SDK. O observador é instanciado e usado mais tarde, para monitorar as operações de manipulador de arquivos.

  1. Abra a solução do Visual Studio em que você trabalhou no artigo anterior "Início Rápido: listar rótulos de confidencialidade (C++)".

  2. 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, insira "filehandler_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.
  3. 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 "filehandler_observer.h", selecionando/excluindo a classe filehandler_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/file/file_engine.h"
      #include "mip/file/file_handler.h"
      
      class FileHandlerObserver final : public mip::FileHandler::Observer {
      public:
         FileHandlerObserver() { }
         // Observer implementation
         void OnCreateFileHandlerSuccess(const std::shared_ptr<mip::FileHandler>& fileHandler, const std::shared_ptr<void>& context) override;
         void OnCreateFileHandlerFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override;
         void OnCommitSuccess(bool committed, const std::shared_ptr<void>& context) override;
         void OnCommitFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override;		
      };
      
    • Atualize "filehandler_observer.cpp", selecionando/excluindo a implementação de classe filehandler_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:

      void FileHandlerObserver::OnCreateFileHandlerSuccess(const std::shared_ptr<mip::FileHandler>& fileHandler, const std::shared_ptr<void>& context) {
         auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::FileHandler>>>(context);
         promise->set_value(fileHandler);
      }
      
      void FileHandlerObserver::OnCreateFileHandlerFailure(const std::exception_ptr & error, const std::shared_ptr<void>& context) {
         auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::FileHandler>>>(context);
         promise->set_exception(error);
      }
      
      void FileHandlerObserver::OnCommitSuccess(bool committed, const std::shared_ptr<void>& context) {
         auto promise = std::static_pointer_cast<std::promise<bool>>(context);
         promise->set_value(committed);
      }
      
      void FileHandlerObserver::OnCommitFailure(const std::exception_ptr & error, const std::shared_ptr<void>& context) {
         auto promise = std::static_pointer_cast<std::promise<bool>>(context);
         promise->set_exception(error);
      }
      
  4. Opcionalmente, use F6 (Compilar solução) para executar um teste de compilação/link da sua solução, para garantir o sucesso da compilação antes de prosseguir.

Adicionar uma lógica para definir e obter um rótulo de confidencialidade

Adicione uma lógica para definir e obter um rótulo de confidencialidade em um arquivo usando o objeto Mecanismo de arquivo.

  1. Usando o Gerenciador de Soluções, abra o arquivo .cpp no 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.

  2. Adicione as seguintes diretivas #include e using, abaixo das diretivas existentes correspondentes, na parte superior do arquivo:

    #include "filehandler_observer.h" 
    #include "mip/file/file_handler.h" 
    
    using mip::FileHandler;
    
  3. No final do corpo de main(), abaixo de system("pause"); e acima de return 0; (onde você parou no Início Rápido anterior), insira o seguinte código:

    // Set up async FileHandler for input file operations
    string inputFilePath = "<input-file-path>";
    string actualFilePath = "<content-identifier>";
    std::shared_ptr<FileHandler> handler;
    try
    {
         auto handlerPromise = std::make_shared<std::promise<std::shared_ptr<FileHandler>>>();
         auto handlerFuture = handlerPromise->get_future();
         engine->CreateFileHandlerAsync(
              inputFilePath,
              actualFilePath,                       
              true, 
              std::make_shared<FileHandlerObserver>(), 
              handlerPromise);
         handler = handlerFuture.get();
    }
    catch (const std::exception& e)
    {
         cout << "An exception occurred... did you specify a valid input file path?\n\n" << e.what() << "'\n";
         system("pause");
         return 1;
    }
    
    // Set a label on input file
    try
    {
         string labelId = "<label-id>";
         cout << "\nApplying Label ID " << labelId << " to " << filePathIn << endl;
         mip::LabelingOptions labelingOptions(mip::AssignmentMethod::PRIVILEGED);
         handler->SetLabel(engine->GetLabelById(labelId), labelingOptions, new ProtectionSettings());
    }
    catch (const std::exception& e)
    {
         cout << "An exception occurred... did you specify a valid label ID?\n\n" << e.what() << "'\n";
         system("pause");
         return 1; 
    }
    
    // Commit changes, save as a different/output file
    string filePathOut = "<output-file-path>";
    try
    {
     	cout << "Committing changes" << endl;
         auto commitPromise = std::make_shared<std::promise<bool>>();
         auto commitFuture = commitPromise->get_future();
         handler->CommitAsync(filePathOut, commitPromise);
     	if (commitFuture.get()) {
     		cout << "\nLabel committed to file: " << filePathOut << endl;
     	}
     	else {
     		cout << "Failed to label: " + filePathOut << endl;
     		return 1;
     	}
    }
    catch (const std::exception& e)
    {
         cout << "An exception occurred... did you specify a valid commit file path?\n\n" << e.what() << "'\n";
         system("pause");
         return 1;
    }
    system("pause");
    
    // Set up async FileHandler for output file operations
    actualFilePath = "<content-identifier>";
    try
    {
         auto handlerPromise = std::make_shared<std::promise<std::shared_ptr<FileHandler>>>();
         auto handlerFuture = handlerPromise->get_future();
         engine->CreateFileHandlerAsync(
              filePathOut,
              actualFilePath,
              true,
              std::make_shared<FileHandlerObserver>(),
              handlerPromise);
    
         handler = handlerFuture.get();
    }
    catch (const std::exception& e)
    {
         cout << "An exception occurred... did you specify a valid output file path?\n\n" << e.what() << "'\n";
         system("pause");
         return 1;
    }
    
    // Get the label from output file
    try
    {
         cout << "\nGetting the label committed to file: " << filePathOut << endl;
         auto label = handler->GetLabel();
         cout << "Name: " + label->GetLabel()->GetName() << endl;
         cout << "Id: " + label->GetLabel()->GetId() << endl;
    }
    catch (const std::exception& e)
    {
         cout << "An exception occurred... did you specify a valid label ID?\n\n" << e.what() << "'\n";
         system("pause");
         return 1;
    }
    system("pause");
    
  4. No fim do corpo main(), localize o bloco de desligamento do aplicativo criado no primeiro início rápido e remova a marca de comentário da linha do manipulador:

    // Application shutdown. Null out profile and engine, call ReleaseAllResources();
    // Application may crash at shutdown if resources aren't properly released.
    profile = nullptr;
    engine = nullptr;
    handler = nullptr;
    mipContext = nullptr;
    
  5. Substitua os valores de espaço reservado no código-fonte, como demonstrado a seguir, usando constantes de cadeia de caracteres:

    Espaço reservado Valor
    <input-file-path> O caminho completo para um arquivo de entrada de teste. Por exemplo: "c:\\Test\\Test.docx".
    <content-identifier> Um identificador legível por humanos para o conteúdo. Por exemplo:
    • para um arquivo, considere caminho\nome do arquivo: "c:\Test\Test.docx"
    • para um email, considere assunto:remetente: "RE: Audit design:user1@contoso.com"
    <label-id> Uma ID de rótulo de confidencialidade, copiada da saída do console no Início Rápido anterior. Por exemplo: "f42a3342-8706-4288-bd31-ebb85995028z".
    <output-file-path> O caminho completo para o arquivo de saída, que será uma cópia rotulada do arquivo de entrada. Por exemplo: "c:\\Test\\Test_labeled.docx".

Criar e testar o aplicativo

Crie e teste o aplicativo cliente.

  1. Use F6 (Compilar solução) para compilar o aplicativo cliente. Se não houver erros de build, use F5 (Iniciar depuração) para executar o aplicativo.

  2. Se o projeto for compilado e executado com êxito, o aplicativo solicitará um token de acesso cada vez que o SDK chamar seu método AcquireOAuth2Token(). Como você fez anteriormente no Início Rápido "Lista de rótulos de confidencialidade", execute o script do PowerShell para adquirir o token todas as vezes, usando os valores fornecidos para $authority e $resourceUrl.

    Run the PowerShell script to generate an access token using the following values, then copy/paste it below:
    
    Sensitivity labels for your organization:
    Non-Business : 87ba5c36-17cf-14793-bbc2-bd5b3a9f95cz
    Public : 83867195-f2b8-2ac2-b0b6-6bb73cb33afz
    General : f42a3342-8706-4288-bd31-ebb85995028z
    Confidential : 074e457c-5848-4542-9a6f-34a182080e7z
    Highly Confidential : f55c2dea-db0f-47cd-8520-a52e1590fb6z
    Press any key to continue . . .
    
    Applying Label ID 074e457c-5848-4542-9a6f-34a182080e7z to c:\Test\Test.docx
    Committing changes
    
    Label committed to file: c:\Test\Test_labeled.docx
    Press any key to continue . . .
    
    Getting the label committed to file: c:\Test\Test_labeled.docx
    Name: Confidential
    Id: 074e457c-5848-4542-9a6f-34a182080e7z
    Press any key to continue . . .
    

Você pode verificar a aplicação do rótulo abrindo o arquivo de saída e inspecionando visualmente as configurações de proteção de informações do documento.

Observação

Se você estiver rotulando um documento do Office, mas não estiver conectado usando uma conta de locatário do Microsoft Entra em que o token de acesso foi obtido (e rótulos de confidencialidade estiverem configurados), será solicitado que você faça locatário antes de abrir o documento rotulado.