Inicio rápido: Inicialización de aplicaciones cliente para SDK de Protection (C++)
En este inicio rápido, se muestra cómo implementar el patrón de inicialización de cliente, que usa el SDK de MIP para C++ en tiempo de ejecución.
Nota:
Los pasos descritos en este inicio rápido son necesarios para cualquier aplicación cliente que use los SDK de protección de MIP. Estos inicios rápidos deben realizarse en serie después de inicializar la aplicación e implementar las clases de delegado de autenticación y delegado de consentimiento.
Requisitos previos
Si aún no lo ha hecho:
- Completar los pasos de Instalación y configuración del SDK de Microsoft Information Protection (MIP). Este inicio rápido "Inicialización de la aplicación cliente" se basa en la instalación y configuración correctas del SDK.
- Opcionalmente:
- Revise Objetos de perfil y motor. Los objetos de perfil y motor son conceptos universales, necesarios para los clientes que usan los SDK de archivos, directivas o protección de MIP.
- Revise Conceptos de autenticación para información sobre cómo el SDK y la aplicación cliente implementan la autenticación y el consentimiento.
- Revise Conceptos de observador para más información sobre los observadores y cómo se implementan. El SDK de MIP usa el patrón de observador para implementar notificaciones de eventos asincrónicos.
Creación de una solución y un proyecto de Visual Studio
En primer lugar, se crearán y configurarán la solución y el proyecto iniciales de Visual Studio, en los que se basan los demás inicios rápidos.
Abra Visual Studio 2017, seleccione el menú Archivo y, luego, Nuevo y Proyecto. En el cuadro de diálogo Nuevo proyecto:
En el panel de la izquierda, en Instalados, Otros lenguajes, seleccione Visual C++.
En el panel central, seleccione Aplicación de consola Windows.
En el panel inferior, actualice el Nombre y la Ubicación del proyecto, y el Nombre de la solución en la que se incluye, según corresponda.
Cuando termine, haga clic en el botón Aceptar en la esquina inferior derecha.
Agregue el paquete Nuget para el SDK de protección de MIP al proyecto:
En el Explorador de soluciones, haga clic con el botón derecho en el nodo del proyecto (directamente debajo del nodo principal o de la solución) y seleccione Administrar paquetes NuGet…:
Cuando se abra la pestaña Administrador de paquetes NuGet en el área de pestañas del grupo de editores:
- Seleccione Examinar.
- Escriba "Microsoft.InformationProtection" en el cuadro de búsqueda.
- Seleccione el paquete "Microsoft.InformationProtection.Protection".
- Haga clic en "Instalar" y después en "Aceptar" cuando se muestre el cuadro de diálogo de confirmación Vista previa de los cambios.
Implementación de clases de observador para supervisar los objetos de perfil y motor de protección
Ahora, creará una implementación básica para una clase de observador de perfil de protección mediante la ampliación de la clase mip::ProtectionProfile::Observer
del SDK. Se crea una instancia del observador que después se usa para supervisar la carga del objeto de perfil de protección y la incorporación del objeto de motor al perfil.
Agregue una clase nueva al proyecto, que genera de manera automática los archivos header/.h e implementation/.cpp:
En el Explorador de soluciones, vuelva a hacer clic con el botón derecho en el nodo del proyecto, seleccione Agregar y después Clase.
En el cuadro de diálogo Agregar clase:
- En el campo Nombre de clase, escriba "profile_observer". Observe que los campos Archivo .h y Archivo .cpp se rellenan automáticamente, en función del nombre que escriba.
- Cuando termine, haga clic en el botón Aceptar.
Después de generar los archivos .h y .cpp para la clase, se abren en las pestañas del grupo de editores. Ahora actualice cada archivo para implementar la nueva clase de observador:
Actualice "profile_observer.h"; para ello, seleccione o elimine la clase
profile_observer
generada. No quite las directivas de preprocesador generadas por el paso anterior (#pragma, #include). Después, copie y pegue el siguiente código en el archivo, después de las directivas de preprocesador existentes:#include <memory> #include "mip/protection/protection_profile.h" using std::exception_ptr; using std::shared_ptr; class ProtectionProfileObserver final : public mip::ProtectionProfile::Observer { public: ProtectionProfileObserver() { } void OnLoadSuccess(const std::shared_ptr<mip::ProtectionProfile>& profile, const std::shared_ptr<void>& context) override; void OnLoadFailure(const std::exception_ptr& Failure, const std::shared_ptr<void>& context) override; void OnAddEngineSuccess(const std::shared_ptr<mip::ProtectionEngine>& engine, const std::shared_ptr<void>& context) override; void OnAddEngineFailure(const std::exception_ptr& Failure, const std::shared_ptr<void>& context) override; };
Actualice "profile_observer.cpp"; para ello, seleccione o elimine la implementación de la clase
profile_observer
generada. No quite las directivas de preprocesador generadas por el paso anterior (#pragma, #include). Después, copie y pegue el siguiente código en el archivo, después de las directivas de preprocesador existentes:#include <future> using std::promise; using std::shared_ptr; using std::static_pointer_cast; using mip::ProtectionEngine; using mip::ProtectionProfile; void ProtectionProfileObserver::OnLoadSuccess(const shared_ptr<ProtectionProfile>& profile, const shared_ptr<void>& context) { auto promise = static_pointer_cast<std::promise<shared_ptr<ProtectionProfile>>>(context); promise->set_value(profile); } void ProtectionProfileObserver::OnLoadFailure(const std::exception_ptr& error, const shared_ptr<void>& context) { auto promise = static_pointer_cast<std::promise<shared_ptr<ProtectionProfile>>>(context); promise->set_exception(error); } void ProtectionProfileObserver::OnAddEngineSuccess(const shared_ptr<ProtectionEngine>& engine, const shared_ptr<void>& context) { auto promise = static_pointer_cast<std::promise<shared_ptr<ProtectionEngine>>>(context); promise->set_value(engine); } void ProtectionProfileObserver::OnAddEngineFailure(const std::exception_ptr& error, const shared_ptr<void>& context) { auto promise = static_pointer_cast<std::promise<shared_ptr<ProtectionEngine>>>(context); promise->set_exception(error); }
Siga los pasos en 1. agregue una clase nueva para el observador del motor de protección - "engine_observer" al proyecto, lo que genera de manera automática los archivos header/.h e implementation/.cpp.
Después de generar los archivos .h y .cpp para la clase, se abren en las pestañas del grupo de editores. Ahora actualice cada archivo para implementar la nueva clase de observador:
Actualice "engine_observer.h"; para ello, seleccione o elimine la clase
engine_observer
generada. No quite las directivas de preprocesador generadas por el paso anterior (#pragma, #include). Después, copie y pegue el siguiente código en el archivo, después de las directivas de preprocesador existentes:#include <memory> #include "mip/protection/protection_engine.h" using std::vector; using std::exception_ptr; using std::shared_ptr; class ProtectionEngineObserver final : public mip::ProtectionEngine::Observer { public: ProtectionEngineObserver() {} void OnGetTemplatesSuccess(const vector<std::shared_ptr<mip::TemplateDescriptor>>& templateDescriptors, const shared_ptr<void>& context) override; void OnGetTemplatesFailure(const exception_ptr& Failure, const shared_ptr<void>& context) override; };
Actualice "engine_observer.cpp"; para ello, seleccione o elimine la implementación de la clase
engine_observer
generada. No quite las directivas de preprocesador generadas por el paso anterior (#pragma, #include). Después, copie y pegue el siguiente código en el archivo, después de las directivas de preprocesador existentes:#include "mip/protection/protection_profile.h" #include "engine_observer.h" using std::promise; void ProtectionEngineObserver::OnGetTemplatesSuccess(const vector<shared_ptr<mip::TemplateDescriptor>>& templateDescriptors,const shared_ptr<void>& context) { auto loadPromise = static_cast<promise<vector<shared_ptr<mip::TemplateDescriptor>>>*>(context.get()); loadPromise->set_value(templateDescriptors); }; void ProtectionEngineObserver::OnGetTemplatesFailure(const exception_ptr& Failure, const shared_ptr<void>& context) { auto loadPromise = static_cast<promise<shared_ptr<mip::ProtectionProfile>>*>(context.get()); loadPromise->set_exception(Failure); };
Opcionalmente, presione Ctrl+Mayús+B (Compilar solución) a fin de ejecutar una compilación o vínculo de prueba de la solución, para asegurarse de que se compila correctamente antes de continuar.
Implementación de un delegado de autenticación y un delegado de consentimiento
El SDK de MIP implementa la autenticación mediante la extensibilidad de clases, que proporciona un mecanismo para compartir el trabajo de autenticación con la aplicación cliente. El cliente debe adquirir un token de acceso de OAuth2 adecuado y proporcionarlo al SDK de MIP en tiempo de ejecución.
Cree una implementación para un delegado de autenticación, mediante la extensión de la clase mip::AuthDelegate
del SDK y el reemplazo e implementación de la función virtual pura mip::AuthDelegate::AcquireOAuth2Token()
. Siga los pasos que se detallan en el inicio rápido Inicialización de aplicaciones cliente del SDK de archivo. Se crea una instancia del delegado de autenticación, que después usan los objetos de perfil de protección y de motor de protección.
Implementación de un delegado de consentimiento
Ahora creará una implementación para un delegado de consentimiento, mediante la extensión de la clase mip::ConsentDelegate
del SDK y el reemplazo e implementación de la función virtual pura mip::AuthDelegate::GetUserConsent()
. Siga los pasos que se detallan en el inicio rápido Inicialización de aplicaciones cliente del SDK de archivo. Se crea una instancia del delegado de consentimiento, que después usan los objetos de perfil de protección y de motor de protección.
Creación de un motor y un perfil de protección
Como ya se mencionó, los objetos de perfil y motor son necesarios para los clientes del SDK que usan las API de MIP. Complete la parte de codificación de este inicio rápido mediante la incorporación de código para crear una instancia de los objetos de perfil y motor:
En el Explorador de soluciones, abra el archivo .cpp del proyecto que contiene la implementación del método
main()
. De manera predeterminada, tiene el mismo nombre que el proyecto que lo contiene, que especificó al crear el proyecto.Quite la implementación generada de
main()
. No quite las directivas de preprocesador generadas por Visual Studio durante la creación del proyecto (#pragma, #include). Anexe el código siguiente después de las directivas de preprocesador:
#include "mip/mip_init.h"
#include "mip/mip_context.h"
#include "auth_delegate.h"
#include "consent_delegate.h"
#include "profile_observer.h"
#include"engine_observer.h"
using std::promise;
using std::future;
using std::make_shared;
using std::shared_ptr;
using std::string;
using std::cout;
using mip::ApplicationInfo;
using mip::ProtectionProfile;
using mip::ProtectionEngine;
int main(){
// Construct/initialize objects required by the application's profile object
// ApplicationInfo object (App ID, name, version)
ApplicationInfo appInfo{"<application-id>",
"<application-name>",
"<application-version>"};
std::shared_ptr<mip::MipConfiguration> mipConfiguration = std::make_shared<mip::MipConfiguration>(mAppInfo,
"mip_data",
mip::LogLevel::Trace,
false);
std::shared_ptr<mip::MipContext> mMipContext = mip::MipContext::Create(mipConfiguration);
auto profileObserver = make_shared<ProtectionProfileObserver>(); // Observer object
auto authDelegateImpl = make_shared<AuthDelegateImpl>("<application-id>"); // Authentication delegate object (App ID)
auto consentDelegateImpl = make_shared<ConsentDelegateImpl>(); // Consent delegate object
// Construct/initialize profile object
ProtectionProfile::Settings profileSettings(
mMipContext,
mip::CacheStorageType::OnDisk,
consentDelegateImpl,
profileObserver);
// Set up promise/future connection for async profile operations; load profile asynchronously
auto profilePromise = make_shared<promise<shared_ptr<ProtectionProfile>>>();
auto profileFuture = profilePromise->get_future();
try
{
mip::ProtectionProfile::LoadAsync(profileSettings, profilePromise);
}
catch (const std::exception& e)
{
cout << "An exception occurred... are the Settings and ApplicationInfo objects populated correctly?\n\n"
<< e.what() << "'\n";
system("pause");
return 1;
}
auto profile = profileFuture.get();
// Construct/initialize engine object
ProtectionEngine::Settings engineSettings(
mip::Identity("<engine-account>"), // Engine identity (account used for authentication)
authDelegateImpl, // Reference to mip::AuthDelegate implementation
"", // ClientData field
"en-US"); // Locale (default = en-US)
// Set the engineId so it can be cached and reused.
engineSettings.SetEngineId("<engine-account>");
// Set up promise/future connection for async engine operations; add engine to profile asynchronously
auto enginePromise = make_shared<promise<shared_ptr<ProtectionEngine>>>();
auto engineFuture = enginePromise->get_future();
profile->AddEngineAsync(engineSettings, enginePromise);
std::shared_ptr<ProtectionEngine> engine;
try
{
engine = engineFuture.get();
}
catch (const std::exception& e)
{
cout << "An exception occurred... is the access token incorrect/expired?\n\n"
<< e.what() << "'\n";
system("pause");
return 1;
}
// Application shutdown. Null out profile and engine, call ReleaseAllResources();
// Application may crash at shutdown if resources aren't properly released.
engine = nullptr;
profile = nullptr;
mipContext.Shutdown();
mipContext = nullptr;
return 0;
}
Reemplace por constantes de cadena todos los valores de marcador de posición en el código fuente que acaba de pegar:
Marcador Valor Ejemplo <application-id> Id. de la aplicación de Microsoft Entra (GUID) asignado a la aplicación registrada en el paso 2 del artículo “Instalación y configuración del SDK de MIP”(setup-configure-mip.md). Reemplace ambas instancias. "0edbblll-8773-44de-b87c-b8c6276d41eb"
<application-name> Nombre descriptivo de la aplicación definido por el usuario. Debe contener caracteres ASCII válidos (excluyendo “;”) e, idealmente, coincide con el nombre de la aplicación que ha usado en el registro de Microsoft Entra. "AppInitialization"
<application-version> Información de versión definida por el usuario para la aplicación. Debe contener caracteres ASCII válidos (excluyendo ";"). "1.1.0.0"
<engine-account> Cuenta usada para la identidad del motor. Cuando se autentique con una cuenta de usuario durante la adquisición de tokens, debe coincidir con este valor. "user1@tenant.onmicrosoft.com"
<engine-state> Estado definido por el usuario que se asociará con el motor. "My App State"
Ahora realice una compilación final de la aplicación y resuelva los errores. El código se debe compilar de manera correcta, pero todavía no se ejecutará correctamente hasta que complete el inicio rápido siguiente. Si ejecuta la aplicación, verá un resultado similar al siguiente. La aplicación construiría correctamente el motor y el perfil de protección, pero no activaría el módulo de autenticación y todavía no se tendría un token de acceso hasta que complete el inicio rápido siguiente.
C:\MIP Sample Apps\ProtectionQS\Debug\ProtectionQS.exe (process 8252) exited with code 0. To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops. Press any key to close this window . . .
Pasos siguientes
Ahora que el código de inicialización está completo, ya está listo para el siguiente inicio rápido, donde empezará a experimentar el SDK de protección de MIP.