SDK Microsoft Information Protection — основные концепции обработки файлов

В пакете SDK mip::FileHandler для файлов MIP предоставляется все различные операции, которые можно использовать для чтения и записи меток или защиты в наборе типов файлов, для которых поддерживается встроенная поддержка.

Поддерживаемые типы файлов

  • Форматы файлов Office на основе OPC (Office 2010 и более поздних версий)
  • Устаревшие форматы файлов Office (Office 2007)
  • PDF
  • Поддержка универсального PFILE
  • Файлы, поддерживающие Adobe XMP

Функции обработчика файлов

mip::FileHandler предоставляет методы чтения, записи и удаления меток и сведений о защите. Полный список см. в справочнике по API.

В этой статье рассматриваются следующие методы:

  • GetLabelAsync()
  • SetLabel()
  • DeleteLabel()
  • RemoveProtection()
  • CommitAsync()

Требования

Для создания FileHandler для работы с определенным файлом требуется:

  • FileProfile
  • FileEngine добавлен в FileProfile
  • Класс, наследующий mip::FileHandler::Observer

Создание обработчика файла

Первым шагом, необходимым для управления любыми файлами в пакете SDK для файлов, является создание FileHandler объекта. Этот класс реализует все функциональные возможности, необходимые для получения, установки, обновления, удаления и фиксации изменений меток в файлах.

Создать FileHandler так же просто, как вызвать функцию CreateFileHandlerAsync объекта FileEngine, используя паттерн promise/future.

CreateFileHandlerAsyncпринимает три параметра: путь к файлу, который должен быть прочитан или изменен, mip::FileHandler::Observer для асинхронных уведомлений о событиях и обещание.FileHandler

Примечание: Класс mip::FileHandler::Observer должен быть реализован в производном классе, поскольку для CreateFileHandler требуется объект Observer.

auto createFileHandlerPromise = std::make_shared<std::promise<std::shared_ptr<mip::FileHandler>>>();
auto createFileHandlerFuture = createFileHandlerPromise->get_future();
fileEngine->CreateFileHandlerAsync(filePath, std::make_shared<FileHandlerObserver>(), createFileHandlerPromise);
auto fileHandler = createFileHandlerFuture.get();

После успешного FileHandler создания объекта можно выполнить операции с файлами (get/set/delete/commit).

Чтение метки

Требования к метаданным

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

  • Метка, считываемая, по-прежнему должна существовать в службе Microsoft 365. Если оно было удалено полностью, пакет SDK не сможет получить сведения об этой метки и возвратит ошибку.
  • Метаданные файла должны быть нетронутыми. Эти метаданные включают:
    • Атрибут1
    • Атрибут2

GetLabelAsync()

Создав обработчик, указывающий на определённый файл, мы возвращаемся к паттерну promise/future, чтобы асинхронно прочитать метку. Обещание предназначено для mip::ContentLabel объекта, содержащего всю информацию о примененной метки.

После создания объектов promise и future мы читаем метку, вызвав fileHandler->GetLabelAsync() и передав promise в качестве единственного параметра. Наконец, метка может храниться в объекте mip::ContentLabel, который мы получим из объекта future.

auto loadPromise = std::make_shared<std::promise<std::shared_ptr<mip::ContentLabel>>>();
auto loadFuture = loadPromise->get_future();
fileHandler->GetLabelAsync(loadPromise);
auto label = loadFuture.get();

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


Установка метки

Установка метки состоит из двух частей. Во-первых, создав обработчик, указывающий на файл, метку можно задать, вызвав FileHandler->SetLabel() некоторые параметры: mip::Label, mip::LabelingOptionsи mip::ProtectionOptions. Сначала необходимо преобразовать идентификатор метки в саму метку, а затем определить параметры разметки.

Преобразовать идентификатор метки в тип mip::Label

Первый параметр функции SetLabel — это mip::Label. Часто приложение работает с идентификаторами меток, а не метками. Идентификатор метки можно сопоставить с mip::Label, вызвав GetLabelById в обработчике файлов или обработчике политик:

mip::Label label = mEngine->GetLabelById(labelId);

Параметры маркировки

Второй параметр, необходимый для задания метки mip::LabelingOptions.

LabelingOptions указывает дополнительные сведения о метках, таких как AssignmentMethod и обоснование действия.

  • mip::AssignmentMethod — перечислитель, имеющий три значения: STANDARD, PRIVILEGEDили AUTO. Дополнительные сведения см. в справочнике mip::AssignmentMethod .
  • Обоснование необходимо только в том случае, если политика службы требует ее и при снижении существующей конфиденциальности файла.

В этом фрагменте кода демонстрируется создание объекта mip::LabelingOptions и задание обоснования понижения уровня и сообщения.

auto labelingOptions = mip::LabelingOptions(mip::AssignmentMethod::STANDARD);
labelingOptions.SetDowngradeJustification(true, "Because I made an educated decision based upon the contents of this file.");

Параметры защиты

Некоторым приложениям может потребоваться выполнять операции от имени делегированной учетной записи пользователя. Класс mip::ProtectionSettings позволяет приложению определить делегированное удостоверение для каждого обработчика. Ранее делегирование осуществлялось классами движка. Это имело существенные недостатки с точки зрения накладных расходов приложения и количества обращений к сервису. Переместив делегированные пользовательские настройки в mip::ProtectionSettings и включив это в класс обработчика, мы устраняем эти накладные расходы, что повышает производительность приложений, выполняющих множество операций от имени разнородных наборов удостоверений пользователей.

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

mip::ProtectionSettings protectionSettings; 
protectionSettings.SetDelegatedUserEmail("alice@contoso.com");

Установка метки

Получив mip::Label по идентификатору, задайте параметры метки и, при необходимости, параметры защиты; теперь можно задать метку для обработчика.

Если вы не настроили параметры защиты, задайте метку, вызвав SetLabel для обработчика:

fileHandler->SetLabel(label, labelingOptions, mip::ProtectionSettings());

Если для выполнения делегированной операции требуется настройка защиты, выполните следующие действия:

fileHandler->SetLabel(label, labelingOptions, protectionSettings);

Теперь, когда метка для файла, на который ссылается обработчик, установлена, остается сделать еще один шаг, чтобы зафиксировать изменение и записать файл на диск или создать поток вывода.

Зафиксируйте изменения

Последним шагом в фиксации любых изменений в файле в пакете SDK MIP является фиксация изменения. Это достигается с помощью FileHandler->CommitAsync() функции.

Чтобы реализовать функцию обязательств, мы возвращаемся к обещанию или будущему, создавая обещание для bool. Функция CommitAsync() возвращает значение true, если операция завершилась успешно или false, если она завершилась ошибкой по какой-либо причине.

После создания promise и future вызывается CommitAsync(), и ему передаются два параметра: путь к выходному файлу (std::string) и promise. Наконец, результат получается путем получения значения future объекта.

auto commitPromise = std::make_shared<std::promise<bool>>();
auto commitFuture = commitPromise->get_future();
fileHandler->CommitAsync(outputFile, commitPromise);
auto wasCommitted = commitFuture.get();

Важно:FileHandler не будет обновлять или перезаписывать существующие файлы. Разработчик сам должен реализовать замену файла, который помечается.

Если записать метку в FileA.docx, будет создана копия файла, FileB.docx, с примененной меткой. Код должен быть записан для удаления и переименования FileA.docx и переименования FileB.docx.


Удаление метки

auto fileHandler = mEngine->CreateFileHandler(filePath, std::make_shared<FileHandlerObserverImpl>());
fileHandler->DeleteLabel(mip::AssignmentMethod::PRIVILEGED, "Label unnecessary.");
auto commitPromise = std::make_shared<std::promise<bool>>();
auto commitFuture = commitPromise->get_future();
fileHandler->CommitAsync(outputFile, commitPromise);

Снятие защиты

Приложение пакета SDK для файлов MIP должно проверить, имеет ли пользователь права на удаление защиты от доступа к файлу. Это можно сделать, выполнив проверку доступа перед удалением защиты.

Функция RemoveProtection() ведет себя так же, как SetLabel() и DeleteLabel(). Метод вызывается в существующем FileHandler объекте, после чего необходимо зафиксировать изменение.

Внимание

Как разработчик приложений, это ваша ответственность за выполнение этой проверки доступа. Неправильное выполнение проверки доступа может привести к утечке данных.

Пример C++ :

// Validate that the file referred to by the FileHandler is protected.
if (fileHandler->GetProtection() != nullptr)
{
    // Validate that user is allowed to remove protection.
    if (fileHandler->GetProtection()->AccessCheck(mip::rights::Export()) || fileHandler->GetProtection()->AccessCheck(mip::rights::Owner()))
    {
        auto commitPromise = std::make_shared<std::promise<bool>>();
        auto commitFuture = commitPromise->get_future();
        // Remove protection and commit changes to file.
        fileHandler->RemoveProtection();
        fileHandler->CommitAsync(outputFile, commitPromise);
        result = commitFuture.get();
    }
    else
    {
        // Throw an exception if the user doesn't have rights to remove protection.
        throw std::runtime_error("User doesn't have EXPORT or OWNER right.");
    }
}

Пример .NET:

if(handler.Protection != null)
{                
    // Validate that user has rights to remove protection from the file.                    
    if(handler.Protection.AccessCheck(Rights.Export) || handler.Protection.AccessCheck(Rights.Owner))
    {
        // If user has Extract right, remove protection and commit the change. Otherwise, throw exception. 
        handler.RemoveProtection();
        bool result = handler.CommitAsync(outputPath).GetAwaiter().GetResult();     
        return result;   
    }
    else
    {
        throw new Microsoft.InformationProtection.Exceptions.AccessDeniedException("User lacks EXPORT right.");
    }
}