Краткое руководство. Инициализация клиентских приложений для пакетов SDK Protection (C++)
В этом кратком руководстве показано, как реализовать шаблон инициализации клиентов, используемый пакетом SDK MIP для C++ во время выполнения.
Примечание.
Действия, описанные в этом кратком руководстве, применимы к любому клиентскому приложению, использующему пакеты SDK MIP Protection. Эти краткие руководства следует выполнять последовательно после инициализации приложения и реализации классов делегата проверки подлинности и делегата согласия.
Необходимые компоненты
Обязательно сделайте следующее, если еще этого не сделали:
- Выполните действия, описанные в статье Установка и настройка пакета SDK Microsoft Information Protection (MIP). Для работы с кратким руководством "Инициализация клиентских приложений" требуется правильная установка и настройка пакета SDK.
- Дополнительно:
- Просмотрите раздел Объекты профиля и подсистемы. Объекты профиля и подсистемы — это универсальные понятия для клиентов, которые используют пакеты SDK MIP File, Policy и Protection.
- Изучите основные понятия проверки подлинности, чтобы узнать, как пакет SDK и клиентское приложение реализуют проверку подлинности и согласие.
- Изучите основные понятия наблюдателя, чтобы узнать о наблюдателях и их реализации. В пакете SDK MIP используется шаблон наблюдателя для реализации уведомлений об асинхронных событиях.
Создание решения и проекта Visual Studio
Сначала мы создадим и настроим первоначальное решение и проект Visual Studio для работы с другими краткими руководствами.
В Visual Studio 2017 откройте меню Файл и выберите Создать и Проект. В диалоговом окне Новый проект:
Добавьте пакет Nuget для пакета SDK MIP Protection в проект:
В Обозревателе решений щелкните правой кнопкой мыши узел проекта (непосредственно под верхним узлом или узлом решения) и выберите Управление пакетами NuGet:
Когда откроется вкладка Диспетчер пакетов NuGet в области вкладок группы редакторов:
- Выберите Обзор.
- Введите Microsoft.InformationProtection в поле поиска.
- Выберите пакет Microsoft.InformationProtection.Protection.
- Когда отобразится диалоговое окно подтверждения Предварительный просмотр изменений, щелкните "Установить" и "ОК".
Реализация классов наблюдателя для отслеживания объектов профиля и подсистемы Protection
Теперь создадим базовую реализацию для класса наблюдателя профиля Protection, расширив класс mip::ProtectionProfile::Observer
пакета SDK. Экземпляр наблюдателя создается и используется позже для отслеживания загрузки объекта профиля Protection и добавления объекта подсистемы в профиль.
Добавьте в проект новый класс, который создает файлы header/.h и implementation/.cpp:
В Обозревателе решений снова щелкните правой кнопкой мыши узел проекта, а затем выберите Добавить и Класс.
В диалоговом окне Добавить класс:
- В поле Имя класса введите profile_observer. Обратите внимание, что поля файлов .h и .cpp заполняются автоматически в зависимости от имени, которое вы вводите.
- По завершении щелкните ОК.
После создания файлов .h и .cpp для класса оба файла откроются на вкладках группы редакторов. Теперь обновите каждый файл, чтобы реализовать новый класс наблюдателя:
Обновите profile_observer.h, выбрав и удалив созданный класс
profile_observer
. Не удаляйте директивы препроцессора, созданные на предыдущем этапе (#pragma, #include). Затем скопируйте и вставьте в файл следующий исходный код после любых существующих директив препроцессора:#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; };
Обновите profile_observer.cpp, выбрав и удалив созданную реализацию класса
profile_observer
. Не удаляйте директивы препроцессора, созданные на предыдущем этапе (#pragma, #include). Затем скопируйте и вставьте в файл следующий исходный код после любых существующих директив препроцессора:#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); }
Выполните действия, указанные на этапе 1, и добавьте новый класс engine_observer для наблюдателя подсистемы Protection в ваш проект, который создает файлы header/.h и implementation/.cpp.
После создания файлов .h и .cpp для класса оба файла откроются на вкладках группы редакторов. Теперь обновите каждый файл, чтобы реализовать новый класс наблюдателя:
Обновите engine_observer.h, выбрав и удалив созданный класс
engine_observer
. Не удаляйте директивы препроцессора, созданные на предыдущем этапе (#pragma, #include). Затем скопируйте и вставьте в файл следующий исходный код после любых существующих директив препроцессора:#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; };
Обновите engine_observer.cpp, выбрав и удалив созданную реализацию класса
engine_observer
. Не удаляйте директивы препроцессора, созданные на предыдущем этапе (#pragma, #include). Затем скопируйте и вставьте в файл следующий исходный код после любых существующих директив препроцессора:#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); };
При желании нажмите сочетание клавиш Ctrl+Shift+B (Выполнить сборку решения) для запуска тестовой компиляции или ссылки решения, чтобы убедиться, что его сборка успешно выполняется, прежде чем продолжить.
Реализация делегата проверки подлинности и делегата согласия
Пакет SDK MIP реализует проверку подлинности с использованием расширяемости класса, которая предоставляет механизм совместного использования проверки подлинности с клиентским приложением. Клиент должен получить подходящий маркер доступа OAuth2 и предоставить его пакету SDK MIP во время выполнения.
Создайте реализацию для делегата проверки подлинности, расширив класс mip::AuthDelegate
пакета SDK и переопределив или реализовав чистую виртуальную функцию mip::AuthDelegate::AcquireOAuth2Token()
. Выполните шаги, описанные в статье Краткое руководство по инициализации приложений пакета SDK File. Экземпляр делегата проверки подлинности создается и используется позже объектами профиля и подсистемы Protection.
Реализация делегата согласия
Теперь создайте реализацию для делегата согласия, расширив класс mip::ConsentDelegate
пакета SDK и переопределив или реализовав чистую виртуальную функцию mip::AuthDelegate::GetUserConsent()
. Выполните шаги, описанные в статье Краткое руководство по инициализации приложений пакета SDK File. Экземпляр делегата согласия создается и используется позже объектами профиля и подсистемы Protection.
Создание профиля и подсистемы Protection
Как уже упоминалось, для клиентов пакета SDK, использующих API MIP, необходимы объекты профиля и подсистемы. Выполните часть этого краткого руководства, добавив код для создания экземпляров объектов профиля и подсистемы:
В Обозревателе решений откройте файл .cpp в проекте, содержащем реализацию метода
main()
. По умолчанию он имеет то же имя, что и содержащий его проект, который вы указали при создании проекта.Удалите созданную реализацию
main()
. Не удаляйте директивы препроцессора, созданные Visual Studio при создании проекта (#pragma, #include). Добавьте следующий код после директив препроцессора:
#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;
}
Замените все заполнители в только что вставленном вами исходном коде строковыми константами:
Заполнитель Значение Пример <application-id> Идентификатор приложения Microsoft Entra (GUID), назначенный приложению, зарегистрированным на шаге 2 статьи "Настройка и конфигурация пакета SDK MIP" (setup-configure-mip.md). Замените два экземпляра. "0edbblll-8773-44de-b87c-b8c6276d41eb"
<application-name> Определенное пользователем понятное имя вашего приложения. Должен содержать допустимые символы ASCII (за исключением ";") и в идеале соответствует имени приложения, используемому в регистрации Microsoft Entra. "AppInitialization"
<application-version> Определенные пользователем сведения о версии вашего приложения. Должны содержать допустимые символы ASCII (за исключением ;). "1.1.0.0"
<engine-account> Учетная запись, используемая для удостоверения подсистемы. При проверке подлинности с помощью учетной записи пользователя во время получения маркера она должна соответствовать этому значению. "user1@tenant.onmicrosoft.com"
<engine-state> Определяемое пользователем состояние, связанное с подсистемой. "My App State"
Теперь вы можете выполнить окончательную сборку приложения и устранить все ошибки. Ваш код должен быть успешно скомпилирован, но не будет работать правильно, пока вы не завершите следующее краткое руководство. При запуске приложения вы увидите результат, аналогичный указанному ниже. Приложение успешно создаст профиль и подсистему Protection, но не запустит подсистему проверки подлинности. Кроме того, пока вы не завершите выполнение следующего краткого руководства, у вас не будет маркера доступа.
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 . . .
Дальнейшие действия
Теперь, когда код инициализации написан, вы можете переходить к следующему краткому руководству по началу работы с пакетом SDK MIP Protection.