Краткое руководство. Установка метки конфиденциальности и получение сведений о ней (C++)

В этом кратком руководстве описывается, как расширить возможности пакетов SDK для MIP. Используя одну из меток конфиденциальности из предыдущего руководства, вы установите на файле метку и получите сведения о ней с помощью обработчика файлов. Класс обработчика файлов предоставляет различные операции для установки меток на файлах поддерживаемых типов, получения сведений о метках и защиты файлов.

Необходимые компоненты

Прежде чем продолжить, выполните следующие предварительные требования:

Реализация класса наблюдателя для отслеживания объекта обработчика файлов

Как и в наблюдателе, который вы реализовали (для профиля файлов и подсистемы) в кратком руководстве по инициализации приложения, теперь вы реализуете класс наблюдателя для объектов обработчика файлов.

Создайте базовую реализацию для наблюдателя обработчика файлов, расширив класс пакета SDK mip::FileHandler::Observer. Для наблюдателя создается экземпляр, который используется позже для отслеживания операций обработчика файлов.

  1. Откройте решение Visual Studio, созданное при выполнении предыдущего краткого руководства по перечислению меток конфиденциальности (C++).

  2. Добавьте в проект новый класс, который создает файлы header/.h и implementation/.cpp:

    • В Обозревателе решений снова щелкните правой кнопкой мыши узел проекта, а затем выберите Добавить и Класс.
    • В диалоговом окне добавления класса:
      • В поле Имя класса введите filehandler_observer. Обратите внимание, что поля файлов .h и .cpp заполняются автоматически в зависимости от имени, которое вы вводите.
      • По завершении щелкните ОК.
  3. После создания файлов .h и .cpp для класса оба файла откроются на вкладках группы редакторов. Теперь обновите каждый файл, чтобы реализовать новый класс наблюдателя:

    • Обновите filehandler_observer.h, выбрав или удалив созданный класс filehandler_observer. Не удаляйте директивы препроцессора, созданные на предыдущем этапе (#pragma, #include). Затем скопируйте и вставьте в файл следующий исходный код после любых существующих директив препроцессора:

      #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;		
      };
      
    • Обновите filehandler_observer.cpp, выбрав или удалив созданную реализацию класса filehandler_observer. Не удаляйте директивы препроцессора, созданные на предыдущем этапе (#pragma, #include). Затем скопируйте и вставьте в файл следующий исходный код после любых существующих директив препроцессора:

      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. Вы можете нажать клавишу F6 (Выполнить сборку решения) для запуска тестовой компиляции решения или переходу по ссылке на него, чтобы убедиться, что его сборка успешно выполняется, прежде чем продолжить.

Добавление логики для установки метки конфиденциальности и получения сведений о ней

Добавьте логику для установки метки конфиденциальности и получения сведений о ней с помощью объекта обработчика файлов.

  1. В Обозревателе решений откройте файл .cpp в проекте, содержащем реализацию метода main(). По умолчанию он имеет то же имя, что и содержащий его проект, который вы указали при создании проекта.

  2. Добавьте следующие директивы #include и using под соответствующими имеющимися директивами в верхней части файла:

    #include "filehandler_observer.h" 
    #include "mip/file/file_handler.h" 
    
    using mip::FileHandler;
    
  3. Вставьте следующий код в конце тела метода main(), после system("pause"); и перед return 0; (где вы закончили работу в предыдущем руководстве):

    // 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. В конце main() найдите блок завершения работы приложения, созданный в первом руководстве, и раскомментируйте строку обработчика:

    // 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. Замените значения-заполнители в исходном коде следующим образом, используя строковые константы:

    Заполнитель Значение
    <input-file-path> Полный путь к тестовому входному файлу, например: "c:\\Test\\Test.docx".
    <content-identifier> Понятный идентификатор контента. Пример:
    • для файла подойдет путь\имя файла: "c:\Test\Test.docx"
    • для сообщения электронной почты — тема:отправитель: "RE: Audit design:user1@contoso.com"
    <label-id> Идентификатор метки конфиденциальности, скопированный из консоли выходных данных в предыдущем руководстве, например: "f42a3342-8706-4288-bd31-ebb85995028z".
    <output-file-path> Полный путь к выходному файлу, который является помеченной копией входного файла, например: "c:\\Test\\Test_labeled.docx".

Создание и тестирование приложения

Выполните сборку клиентского приложения и протестируйте его.

  1. Для создания клиентского приложения нажмите клавишу F6 (Сборка решения). Если ошибок сборки нет, нажмите клавишу F5 (Начать отладку), чтобы запустить приложение.

  2. Если проект успешно создан и запущен, приложение будет запрашивать маркер доступа каждый раз, когда пакет SDK вызывает метод AcquireOAuth2Token(). Как вы делали ранее в кратком руководстве "Перечисление меток конфиденциальности", запускайте скрипт PowerShell, когда необходим маркер. При этом используйте значения, предоставленные для $authority и $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 . . .
    

Что проверить, была ли установлена метка, вы можете открыть выходной файл и просмотреть параметры защиты информации, заданные для документа.

Примечание.

Если вы наклеиваете документ Office, но не выполнили вход с помощью учетной записи из клиента Microsoft Entra, где был получен маркер доступа (и метки конфиденциальности настроены), вам может потребоваться войти, прежде чем открыть документ с метками.