Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Ce guide de démarrage rapide vous montre comment implémenter le modèle d’initialisation du client, utilisé par le SDK C++ MIP au moment de l’exécution.
Note
Les étapes décrites dans ce guide de démarrage rapide sont requises pour toute application cliente qui utilise les kits SDK MIP File, Policy ou Protection. Bien que ce guide de démarrage rapide illustre l’utilisation des kits SDK File, ce même modèle s’applique aux clients qui utilisent les kits SDK de stratégie et de protection. Suivez les guides de démarrage rapide restants en série, car chacun s’appuie sur le précédent, avec celui-ci étant le premier.
Prerequisites
Si ce n’est déjà fait, veillez à :
- Effectuez les étapes de configuration et de configuration du Kit de développement logiciel (SDK) Microsoft Information Protection (MIP). Ce guide de démarrage rapide « Initialisation de l’application cliente » s’appuie sur la configuration et l’installation appropriées du Kit de développement logiciel (SDK).
- Optionnellement:
- Passez en revue les objets profil et moteur. Les objets de profil et de moteur sont des concepts universels, requis par les clients qui utilisent les kits SDK MIP File/Policy/Protection.
- Passez en revue les concepts d’authentification pour savoir comment l’authentification et le consentement sont implémentés par le Kit de développement logiciel (SDK) et l’application cliente.
- Passez en revue les concepts de l’observateur pour en savoir plus sur les observateurs et comment ils sont implémentés. Le SDK MIP utilise le modèle d’observateur pour implémenter des notifications d’événements asynchrones.
Créer une solution et un projet Visual Studio
Tout d’abord, nous créons et configurons la solution et le projet Visual Studio initiaux, sur lesquels les autres démarrages rapides créent.
Ouvrez Visual Studio 2019 ou version ultérieure, sélectionnez le menu Fichier , Nouveau, Projet. Dans la boîte de dialogue Nouveau projet :
Dans le volet gauche, sous Installé, Autres langues, sélectionnez Visual C++.
Dans le volet central, sélectionnez Application console Windows
Dans le volet inférieur, mettez à jour le nom du projet, l’emplacement et le nom de solution contenant en conséquence.
Lorsque vous avez terminé, cliquez sur le bouton OK en bas à droite.
Ajoutez le package NuGet pour le Kit de développement logiciel (SDK) de fichier MIP à votre projet :
Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le nœud du projet (directement sous le nœud supérieur/solution), puis sélectionnez Gérer les packages NuGet... :
Lorsque l’onglet Gestionnaire de package NuGet s’ouvre dans la zone onglets Groupe d’éditeurs :
- Sélectionnez Parcourir.
- Entrez « Microsoft.InformationProtection » dans la zone de recherche.
- Sélectionnez le package « Microsoft.InformationProtection.File ».
- Cliquez sur « Installer », puis sur « OK » lorsque la boîte de dialogue de confirmation d’aperçu change s’affiche.
Implémenter une classe d’observateur pour surveiller le profil de fichier et les objets moteur
Créez maintenant une implémentation de base pour une classe d’observateur de profil de fichier, en étendant la classe du Kit de mip::FileProfile::Observer développement logiciel (SDK). L’observateur est instancié et utilisé ultérieurement pour surveiller le chargement de l’objet profil fichier et ajouter l’objet moteur au profil.
Ajoutez une nouvelle classe à votre projet, qui génère à la fois les fichiers d’en-tête/.h et d’implémentation/.cpp pour vous :
Dans l’Explorateur de solutions, cliquez à nouveau avec le bouton droit sur le nœud du projet, sélectionnez Ajouter, puis sélectionnez Classe.
Dans la boîte de dialogue Ajouter une classe :
- Dans le champ Nom de la classe , entrez « profile_observer ». Notez que le fichier .h et les champs de fichier .cpp sont automatiquement renseignés en fonction du nom que vous entrez.
- Lorsque vous avez terminé, cliquez sur le bouton OK .
Après avoir généré les fichiers .h et .cpp pour la classe, les deux fichiers sont ouverts dans les onglets groupe d’éditeurs. À présent, mettez à jour chaque fichier pour implémenter votre nouvelle classe d’observateur :
Mettez à jour « profile_observer.h », en sélectionnant/supprimant la classe générée
profile_observer. Ne supprimez pas les directives de préprocesseur générées par l’étape précédente (#pragma, #include). Copiez/collez ensuite la source suivante dans le fichier, après toutes les directives de préprocesseur existantes :#include <memory> #include "mip/file/file_profile.h" class ProfileObserver final : public mip::FileProfile::Observer { public: ProfileObserver() { } void OnLoadSuccess(const std::shared_ptr<mip::FileProfile>& profile, const std::shared_ptr<void>& context) override; void OnLoadFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override; void OnAddEngineSuccess(const std::shared_ptr<mip::FileEngine>& engine, const std::shared_ptr<void>& context) override; void OnAddEngineFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override; };Mettez à jour « profile_observer.cpp », en sélectionnant/supprimant l’implémentation de classe générée
profile_observer. Ne supprimez pas les directives de préprocesseur générées par l’étape précédente (#pragma, #include). Copiez/collez ensuite la source suivante dans le fichier, après toutes les directives de préprocesseur existantes :#include <future> using std::promise; using std::shared_ptr; using std::static_pointer_cast; using mip::FileEngine; using mip::FileProfile; void ProfileObserver::OnLoadSuccess(const shared_ptr<FileProfile>& profile, const shared_ptr<void>& context) { auto promise = static_pointer_cast<std::promise<shared_ptr<FileProfile>>>(context); promise->set_value(profile); } void ProfileObserver::OnLoadFailure(const std::exception_ptr& error, const shared_ptr<void>& context) { auto promise = static_pointer_cast<std::promise<shared_ptr<FileProfile>>>(context); promise->set_exception(error); } void ProfileObserver::OnAddEngineSuccess(const shared_ptr<FileEngine>& engine, const shared_ptr<void>& context) { auto promise = static_pointer_cast<std::promise<shared_ptr<FileEngine>>>(context); promise->set_value(engine); } void ProfileObserver::OnAddEngineFailure(const std::exception_ptr& error, const shared_ptr<void>& context) { auto promise = static_pointer_cast<std::promise<shared_ptr<FileEngine>>>(context); promise->set_exception(error); }
Si vous le souhaitez, utilisez F6 (Build Solution) pour exécuter une compilation de test/lien de votre solution pour vous assurer qu’elle est générée correctement avant de continuer.
Implémenter un délégué d’authentification
Le SDK MIP implémente l’authentification à l’aide de l’extensibilité de classe, qui fournit un mécanisme permettant de partager l’authentification avec l’application cliente. Le client doit acquérir un jeton d’accès OAuth2 approprié et fournir au SDK MIP au moment de l’exécution.
À présent, créez une implémentation pour un délégué d’authentification, en étendant la classe du Kit de mip::AuthDelegate développement logiciel (SDK) et en remplaçant/implémentant la mip::AuthDelegate::AcquireOAuth2Token() fonction virtuelle pure. Le délégué d’authentification est instancié et utilisé ultérieurement, par le profil de fichier et les objets du moteur de fichiers.
À l’aide de la même fonctionnalité « Ajouter une classe » de Visual Studio que nous avons utilisée à l’étape 1 de la section précédente, ajoutez une autre classe à votre projet. Cette fois, entrez « auth_delegate » dans le champ Nom de la classe .
À présent, mettez à jour chaque fichier pour implémenter votre nouvelle classe de délégué d’authentification :
Mettez à jour « auth_delegate.h », en remplaçant tout le code de classe généré
auth_delegatepar la source suivante. Ne supprimez pas les directives de préprocesseur générées par l’étape précédente (#pragma, #include) :#include <string> #include "mip/common_types.h" class AuthDelegateImpl final : public mip::AuthDelegate { public: AuthDelegateImpl() = delete; // Prevents default constructor AuthDelegateImpl( const std::string& appId) // AppID for registered AAD app : mAppId(appId) {}; bool AcquireOAuth2Token( // Called by MIP SDK to get a token const mip::Identity& identity, // Identity of the account to be authenticated, if known const OAuth2Challenge& challenge, // Authority (AAD tenant issuing token), and resource (API being accessed; "aud" claim). OAuth2Token& token) override; // Token handed back to MIP SDK private: std::string mAppId; std::string mToken; std::string mAuthority; std::string mResource; };Mettez à jour « auth_delegate.cpp », en remplaçant l’implémentation de toutes les classes générées
auth_delegatepar la source suivante. Ne supprimez pas les directives de préprocesseur générées par l’étape précédente (#pragma, #include).Important
Le code d’acquisition de jeton suivant n’est pas adapté à une utilisation en production. En production, cela doit être remplacé par du code qui acquiert dynamiquement un jeton, à l’aide de :
- L’ID d’application et l’URI de réponse/redirection spécifiés dans votre inscription d’application Microsoft Entra (l’URI de réponse/redirection doit correspondre à votre inscription d’application)
- L’autorité et l’URL de ressource transmises par le SDK dans l’argument
challenge(l’URL de ressource doit correspondre à l’API/autorisations de votre inscription d’application) - Informations d’identification de l’application/de l’utilisateur valides, où le compte correspond à l’argument
identitytransmis par le Kit de développement logiciel (SDK). Les clients « natifs » OAuth2 doivent demander des informations d’identification utilisateur et utiliser le flux « code d’autorisation ». Les « clients confidentiels » OAuth2 peuvent utiliser leurs propres informations d’identification sécurisées avec le flux « informations d’identification client » (par exemple, un service) ou demander des informations d’identification utilisateur à l’aide du flux « code d’autorisation » (par exemple, une application web).
L’acquisition de jetonS OAuth2 est un protocole complexe et s’effectue normalement à l’aide d’une bibliothèque. TokenAcquireOAuth2Token() est appelé uniquement par le KIT SDK MIP, selon les besoins.
#include <iostream> using std::cout; using std::cin; using std::string; bool AuthDelegateImpl::AcquireOAuth2Token(const mip::Identity& identity, const OAuth2Challenge& challenge, OAuth2Token& token) { // Acquire a token manually, reuse previous token if same authority/resource. In production, replace with token acquisition code. string authority = challenge.GetAuthority(); string resource = challenge.GetResource(); if (mToken == "" || (authority != mAuthority || resource != mResource)) { cout << "\nRun the PowerShell script to generate an access token using the following values, then copy/paste it below:\n"; cout << "Set $authority to: " + authority + "\n"; cout << "Set $resourceUrl to: " + resource + "\n"; cout << "Sign in with user account: " + identity.GetEmail() + "\n"; cout << "Enter access token: "; cin >> mToken; mAuthority = authority; mResource = resource; system("pause"); } // Pass access token back to MIP SDK token.SetAccessToken(mToken); // True = successful token acquisition; False = failure return true; }
Si vous le souhaitez, utilisez F6 (Build Solution) pour exécuter une compilation de test/lien de votre solution pour vous assurer qu’elle est générée correctement avant de continuer.
Implémenter un délégué de consentement
À présent, créez une implémentation pour un délégué de consentement, en étendant la classe du Kit de mip::ConsentDelegate développement logiciel (SDK) et en remplaçant/implémentant la mip::AuthDelegate::GetUserConsent() fonction virtuelle pure. Le délégué de consentement est instancié et utilisé ultérieurement, par le profil de fichier et les objets du moteur de fichiers.
À l’aide de la même fonctionnalité « Ajouter une classe » de Visual Studio que nous avons utilisée précédemment, ajoutez une autre classe à votre projet. Cette fois, entrez « consent_delegate » dans le champ Nom de la classe .
À présent, mettez à jour chaque fichier pour implémenter votre nouvelle classe de délégué de consentement :
Mettez à jour « consent_delegate.h », en remplaçant tout le code de classe généré
consent_delegatepar la source suivante. Ne supprimez pas les directives de préprocesseur générées par l’étape précédente (#pragma, #include) :#include "mip/common_types.h" #include <string> class ConsentDelegateImpl final : public mip::ConsentDelegate { public: ConsentDelegateImpl() = default; virtual mip::Consent GetUserConsent(const std::string& url) override; };Mettez à jour « consent_delegate.cpp », en remplaçant l’implémentation de toutes les classes générées
consent_delegatepar la source suivante. Ne supprimez pas les directives de préprocesseur générées par l’étape précédente (#pragma, #include).#include <iostream> using mip::Consent; using std::string; Consent ConsentDelegateImpl::GetUserConsent(const string& url) { // Accept the consent to connect to the url std::cout << "SDK will connect to: " << url << std::endl; return Consent::AcceptAlways; }
Si vous le souhaitez, utilisez F6 (Build Solution) pour exécuter une compilation de test/lien de votre solution pour vous assurer qu’elle est générée correctement avant de continuer.
Construire un profil de fichier et un moteur
Comme mentionné, les objets de profil et de moteur sont requis pour les clients sdk utilisant des API MIP. Terminez la partie de codage de ce guide de démarrage rapide en ajoutant du code pour instancier les objets de profil et de moteur :
À partir de l’Explorateur de solutions, ouvrez le fichier .cpp dans votre projet qui contient l’implémentation de la
main()méthode. Il a par défaut le même nom que le projet qui le contient, que vous avez spécifié lors de la création du projet.Supprimez l’implémentation générée de
main(). Ne supprimez pas les directives de préprocesseur générées par Visual Studio lors de la création du projet (#pragma, #include). Ajoutez le code suivant après toutes les directives de préprocesseur :
#include "mip/mip_context.h"
#include "auth_delegate.h"
#include "consent_delegate.h"
#include "profile_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::FileProfile;
using mip::FileEngine;
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>"};
// Create MipConfiguration object.
std::shared_ptr<mip::MipConfiguration> mipConfiguration = std::make_shared<mip::MipConfiguration>(appInfo,
"mip_data",
mip::LogLevel::Trace,
false);
std::shared_ptr<mip::MipContext> mMipContext = mip::MipContext::Create(mipConfiguration);
auto profileObserver = make_shared<ProfileObserver>(); // 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
FileProfile::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<FileProfile>>>();
auto profileFuture = profilePromise->get_future();
try
{
mip::FileProfile::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
FileEngine::Settings engineSettings(
mip::Identity("<engine-account>"), // Engine identity (account used for authentication)
authDelegateImpl, // Token acquisition implementation
"<engine-state>", // User-defined engine state
"en-US"); // Locale (default = en-US)
// Set the engineId for caching.
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<FileEngine>>>();
auto engineFuture = enginePromise->get_future();
profile->AddEngineAsync(engineSettings, enginePromise);
std::shared_ptr<FileEngine> 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.
// handler = nullptr; // This will be used in later quick starts.
engine = nullptr;
profile = nullptr;
mMipContext->ShutDown();
mMipContext = nullptr;
return 0;
}
Remplacez toutes les valeurs d’espace réservé dans le code source dans lequel vous venez de coller, à l’aide de constantes de chaîne :
Placeholder Valeur Example <id d’application> L’ID d’application Microsoft Entra (GUID) affecté à l’application inscrite à l’étape 2 de l’article « Configuration et configuration du Kit de développement logiciel (SDK) MIP ». Remplacez 2 instances. "0edbblll-8773-44de-b87c-b8c6276d41eb"<nom de l’application> Nom convivial défini par l’utilisateur pour votre application. Doit contenir des caractères ASCII valides (à l’exception de « ; »), et correspond idéalement au nom de l’application que vous avez utilisé dans votre inscription Microsoft Entra. "AppInitialization"<version de l’application> Informations de version définies par l’utilisateur pour votre application. Doit contenir des caractères ASCII valides (à l’exception de ' ;'). "1.1.0.0"<engine-account> Compte utilisé pour l’identité du moteur. Lorsque vous vous authentifiez auprès d’un compte d’utilisateur lors de l’acquisition de jetons, il doit correspondre à cette valeur. "user1@tenant.onmicrosoft.com"<état du moteur> État défini par l’utilisateur à associer au moteur. "My App State"Effectuez maintenant une build finale de l’application et résolvez toutes les erreurs. Votre code doit être généré correctement, mais ne s’exécute pas encore correctement tant que vous n’avez pas terminé le prochain démarrage rapide. Si vous exécutez l’application, vous voyez une sortie similaire à ce qui suit. Vous n’aurez pas de jeton d’accès à fournir, tant que vous n’aurez pas terminé le guide de démarrage rapide suivant.
Étapes suivantes
Maintenant que votre code d’initialisation est terminé, vous êtes prêt pour le prochain guide de démarrage rapide, où vous commencerez à découvrir les kits SDK de fichier MIP.