SDK de Microsoft Information Protection: Conceptos del controlador de archivos

En el SDK de archivos MIP, mip::FileHandler expone todas las distintas operaciones que se pueden usar para leer y escribir etiquetas, o para protección, en un conjunto de tipos de archivo para los que la compatibilidad está integrada.

Tipos de archivo compatibles

  • Formatos de archivo de Office basados en OPC (Office 2010 y versiones posteriores)
  • Formatos de archivo de Office heredados (Office 2007)
  • PDF
  • Compatibilidad con PFILE genérico
  • Archivos que admiten Adobe XMP

Funciones del controlador de archivos

mip::FileHandler expone métodos para leer, escribir y eliminar tanto etiquetas como información de protección. Para obtener la lista completa, consulte la referencia de API.

En este artículo, trataremos los siguientes métodos:

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

Requisitos

La creación de un FileHandler para trabajar con un archivo específico requiere lo siguiente:

  • Un FileProfile
  • Agregar un FileEngine a FileProfile
  • Una clase que herede mip::FileHandler::Observer

Creación de un controlador de archivos

El primer paso necesario para administrar los archivos del SDK de archivos es crear un objeto FileHandler. Esta clase implementa todas las funciones necesarias para obtener, establecer, actualizar, eliminar y confirmar los cambios de etiqueta en los archivos.

Para crear FileHandler, solo hay que llamar a la función CreateFileHandlerAsync de FileEngine mediante el patrón promesa/futuro.

CreateFileHandlerAsync acepta tres parámetros: la ruta de acceso al archivo que se debe leer o modificar, el mip::FileHandler::Observer para las notificaciones de eventos asincrónicas y la promesa de FileHandler.

Nota: La clase mip::FileHandler::Observer debe implementarse en una clase derivada, ya que CreateFileHandler requiere el objeto 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();

Después de crear correctamente el objeto FileHandler, se pueden realizar operaciones de archivo (obtener/definir/eliminar/confirmar).

Leer una etiqueta

Requisitos de metadatos

Hay algunos requisitos para leer correctamente los metadatos de un archivo y traducirlos en algo que se puede usar en las aplicaciones.

  • La etiqueta que se lee debe seguir existiendo en el servicio de Microsoft 365. Si se ha eliminado por completo, el SDK no obtendrá información sobre esa etiqueta y devolverá un error.
  • Los metadatos del archivo deben estar intactos. Los metadatos incluyen:
    • Attribute1
    • Attribute2

GetLabelAsync()

Después de crear el controlador para que apunte a un archivo específico, volveremos al patrón promesa/futuro para leer de forma asincrónica la etiqueta. La promesa es para un objeto mip::ContentLabel que contiene toda la información sobre la etiqueta aplicada.

Después de crear instancias de los objetos promise y future, se lee la etiqueta llamando a fileHandler->GetLabelAsync() y proporcionando promise como el parámetro lone. Por último, la etiqueta se puede almacenar en un objeto mip::ContentLabel que obtendremos de 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();

Los datos de etiqueta se pueden leer desde el objeto label y pasarse a cualquier otro componente o funcionalidad de la aplicación.


Definición de una etiqueta

Establecer una etiqueta es un proceso que consta de dos partes. En primer lugar, después de crear un controlador que apunte al archivo en cuestión, la etiqueta se puede establecer llamando a FileHandler->SetLabel() con algunos parámetros: mip::Label, mip::LabelingOptions y mip::ProtectionOptions. Primero, debemos resolver el id. de etiqueta en una etiqueta y, a continuación, definir las opciones de etiquetado.

Resolución del id. de etiqueta en mip::Label

El primer parámetro de la función SetLabel es mip::Label. A menudo, la aplicación trabaja con identificadores de etiqueta en lugar de con etiquetas. El identificador de etiqueta se puede resolver en mip::Label mediante una llamada a GetLabelById en el archivo o motor de directivas:

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

Opciones de etiquetado

El segundo parámetro necesario para definir la etiqueta es mip::LabelingOptions.

LabelingOptions especifica información adicional sobre la etiqueta, como AssignmentMethod y la justificación para una acción.

  • mip::AssignmentMethod es un enumerador que tiene tres valores: STANDARD, PRIVILEGED o AUTO. Revise la referencia mip::AssignmentMethod para obtener más detalles.
  • La justificación solo es necesaria si la directiva de servicio la requiere y al reducir la confidencialidad existente de un archivo.

En este fragmento se muestra cómo crear el objeto mip::LabelingOptions y establecer la justificación y el mensaje de degradación.

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

Configuración de la protección

Es posible que algunas aplicaciones necesiten realizar operaciones en nombre de una identidad de usuario delegada. La clase mip::ProtectionSettings permite que la aplicación defina la identidad delegada por controlador. Anteriormente, las clases de motor realizaban la delegación. Esto tenía importantes desventajas en la sobrecarga de la aplicación y los recorridos de ida y vuelta de servicio. Al mover la configuración del usuario delegado a mip::ProtectionSettings y convertir esa parte de la clase de controlador, eliminamos esta sobrecarga, lo que da lugar a un mejor rendimiento de las aplicaciones que realizan muchas operaciones en nombre de diversos conjuntos de identidades de usuario.

Si no es necesaria la delegación, pase mip::ProtectionSettings() a la función SetLabel. Si se requiere delegación, se puede lograr creando un objeto mip::ProtectionSettings y estableciendo la dirección de correo delegada:

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

Definición de la etiqueta

Después de capturar mip::Label mediante el identificador, establecer las opciones de etiquetado y, opcionalmente, establecer la configuración de protección, la etiqueta ahora se puede establecer en el controlador.

Si no estableció la configuración de protección, establezca la etiqueta llamando SetLabel en el controlador:

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

En caso de que necesitara una configuración de protección para realizar una operación delegada, haga lo siguiente:

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

Después de establecer la etiqueta en el archivo al que el controlador hace referencia, todavía hay un paso más para confirmar el cambio y escribir un archivo en el disco o crear un flujo de salida.

Confirmación de cambios

El último paso para confirmar cualquier cambio en un archivo en el SDK de MIP es confirmar el cambio. Esto se logra mediante el la función FileHandler->CommitAsync().

Para implementar la función de compromiso, volvemos a promesa/futuro, creando una promesa para bool. La función CommitAsync() devolverá true si la operación se realizó correctamente o false si se produjo un error por algún motivo.

Después de crear promise y future, se llama a CommitAsync() y se proporcionan dos parámetros: la ruta de acceso del archivo de resultados (std::string) y la promesa. Por último, el resultado se consigue obteniendo el valor del objeto future.

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

Importante:FileHandler no actualizará ni sobrescribirá los archivos existentes. Es responsabilidad del desarrollador implementar la sustitución del archivo que se está etiquetando.

Si escribe una etiqueta en FileA.docx, se creará una copia del archivo FileB.docx con la etiqueta aplicada. El código debe escribirse para eliminar o cambiar el nombre de de FileA.docx y cambiar el nombre de FileB.docx.


Eliminación de una etiqueta

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);

Eliminación de la protección

La aplicación del SDK de archivos MIP debe validar que el usuario tiene derechos para eliminar la protección del archivo al que se accede. Para ello, realice una comprobación de acceso antes de eliminar la protección.

La función RemoveProtection() se comporta de forma similar a SetLabel() o DeleteLabel(). Se llama al método en el objeto FileHandler existente y, a continuación, se debe confirmar el cambio.

Importante

Como desarrollador de aplicaciones, es su responsabilidad realizar esta comprobación de acceso. Si no se realiza correctamente la comprobación de acceso, se puede producir una pérdida de datos.

Ejemplo de 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.");
    }
}

Ejemplo de .NET:

if(handler.Protection != null)
{                
    // Validate that user has rights to remove protection from the file.                    
    if(handler.Protection.AccessCheck(Rights.Extract) || 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.");
    }
}