Microsoft 信息保护 SDK - 文件处理程序概念

在 MIP 文件 SDK 中,mip::FileHandler 提供了针对内置支持的文件类型读取和写入标签或保护信息的操作。

支持的文件类型

  • 基于 OPC 的 Office 文件格式(Office 2010 及更高版本)
  • 旧版 Office 文件格式 (Office 2007)
  • PDF
  • 通用 PFILE 支持
  • 支持 Adobe XMP 的文件

文件处理程序函数

mip::FileHandler 公开用于读取、写入和移除标签和保护信息的方法。 有关完整列表,请参阅 API 参考。

本文介绍以下方法:

  • GetLabel()
  • SetLabel()
  • DeleteLabel()
  • RemoveProtection()
  • CommitAsync()

要求

若要创建一个用于处理特定文件的 FileHandler,请提供:

  • 执行 FileProfile 操作
  • 添加到 FileEngine 的 FileProfile
  • 一个继承 mip::FileHandler::Observer 的类

创建文件处理程序

管理文件 SDK 中的文件的第一步是创建对象 FileHandler 。 此类包括获取、设置、更新、删除和提交文件标签更改所需的功能。

通过使用 promise/future 模式调用 FileEngine 的 CreateFileHandlerAsync 函数来创建 FileHandler。

CreateFileHandlerAsync 接受以下参数:要读取或修改的文件的路径、用于审核报告的路径、启用审核发现的标志、 mip::FileHandler::Observer 异步事件通知的路径以及承诺 FileHandler。

Note

因为 CreateFileHandler 需要 Observer 对象,所以请在派生类中实现 mip::FileHandler::Observer 类。

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

创建 FileHandler 对象后,可以执行文件操作(get/set/delete/commit)。

阅读标签

元数据要求

从文件成功读取元数据并将其转换为应用程序可以使用的内容有几个要求。

  • 要读取的标签必须仍存在于 Microsoft 365 服务中。 如果有人删除了标签,则 SDK 无法获取有关该标签的信息并返回错误。
  • 文件元数据必须完好。 此元数据包括:
    • 属性1
    • 属性2

GetLabel()

创建指向特定文件的处理程序后,通过调用 fileHandler->GetLabel()以同步方式读取标签。 该方法返回一个 mip::ContentLabel 对象,该对象包含有关应用标签的所有信息。

auto label = fileHandler->GetLabel();

可以从对象中读取标签数据 label ,并将其传递给应用程序中的任何其他组件或功能。


设置标签

设置标签是一个由两部分构成的过程。 创建指向有问题的文件的处理程序后,使用一些参数进行调用 FileHandler->SetLabel() 来设置标签: mip::Label、 mip::LabelingOptions和 mip::ProtectionOptions。 首先,将标签 ID 解析为标签,然后定义标签选项。

将标签 ID 解析为 mip::Label

SetLabel 函数的第一个参数是 mip::Label。 应用程序通常使用标签标识符而不是标签。 通过在文件或策略引擎上调用 GetLabelById,将标签标识符解析为mip::Label:

std::shared_ptr<mip::Label> label = engine->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");

设置标签

使用 ID 提取 mip::Label 后,设置标记选项,并选择性地设置保护设置后,可以在处理程序上设置标签。

如果未设置保护设置,请通过在处理程序上调用 SetLabel 来设置标签:

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

如果需要保护设置来执行委托的操作,请使用:

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

在处理程序引用的文件上设置标签后,提交更改并将文件写入磁盘或创建输出流。

提交更改

要在 MIP SDK 中提交对文件的任何更改,最后一步是“提交”该更改。 使用 FileHandler->CommitAsync() 函数。

若要实现承诺函数,请返回 promise/future,为 a 创建一个 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,CommitAsync() 会创建该文件的副本 FileB.docx,并将该标签应用到该副本。 编写代码以删除或重命名 FileA.docx 并重命名 FileB.docx。


删除标签

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

mip::LabelingOptions labelingOptions(mip::AssignmentMethod::PRIVILEGED);
labelingOptions.SetDowngradeJustification(true, "Label unnecessary.");
fileHandler->DeleteLabel(labelingOptions);

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

删除保护

验证用户是否有权从要访问的文件中删除保护。 在删除保护之前执行 访问检查 。

函数 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.");
    }
}

后续步骤