Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом кратком руководстве показано, как реализовать шаблон инициализации клиента, используемый пакетом SDK MIP C++ во время выполнения.
Примечание.
Действия, описанные в этом кратком руководстве, необходимы для любого клиентского приложения, использующего SDK MIP для работы с файлами, политики или защиты. Хотя в этом кратком руководстве показано использование пакетов SDK для файлов, этот же шаблон применим к клиентам с помощью пакетов SDK политики и защиты. Выполните оставшиеся инструкции последовательно, поскольку каждая из них строится на предыдущей, и это руководство — первое.
Предпосылки
Если вы еще не сделали этого, обязательно выполните следующие действия.
- Выполните действия, описанные в настройке и конфигурации пакета SDK Microsoft Information Protection (MIP). Это краткое руководство по инициализации клиентского приложения зависит от правильной настройки пакета SDK.
- Необязательно:
- Просмотрите объекты профиля и движка. Объекты профиля и движка — это универсальные понятия, необходимые клиентам, использующим SDK для MIP-файлов, политик и защиты.
- Ознакомьтесь с концепциями проверки подлинности , чтобы узнать, как проверка подлинности и согласие реализованы пакетом SDK и клиентским приложением.
- Ознакомьтесь с концепциями наблюдателя , чтобы узнать больше о наблюдателях и о том, как они реализуются. Пакет SDK MIP использует шаблон наблюдателя для реализации асинхронных уведомлений о событиях.
Создание решения и проекта Visual Studio
Сначала мы создаём и настраиваем начальное решение и проект в Visual Studio, на которых основываются другие быстрые старты.
Откройте Visual Studio 2019 или более поздней версии, выберите меню "Файл ", "Создать", "Проект". В диалоговом окне "Новый проект ":
Добавьте пакет NuGet для пакета SDK для файлов MIP в проект:
В Обозревателе решений щелкните правой кнопкой мыши по узлу проекта (непосредственно под верхним узлом или узлом решения) и выберите "Управление пакетами NuGet..."
Когда откроется вкладка Диспетчер пакетов NuGet в области вкладок группы редакторов:
- Выберите Обзор.
- В поле поиска введите "Microsoft.InformationProtection".
- Выберите пакет Microsoft.InformationProtection.File.
- Нажмите кнопку "Установить", а затем нажмите кнопку "ОК" при отображении диалогового окна подтверждения изменений предварительного просмотра .
Реализация класса наблюдателя для мониторинга объектов профиля файла и обработчика
Теперь создайте базовую реализацию для класса наблюдателя профиля файла, расширив класс ПАКЕТА SDK mip::FileProfile::Observer . Наблюдатель создаётся и используется позже для наблюдения за загрузкой объекта профиля файла и добавления объекта движка в профиль.
Добавьте новый класс в свой проект, который автоматически генерирует для вас заголовочные файлы (.h) и файлы реализации (.cpp).
В обозревателе решений снова щелкните правой кнопкой мыши узел проекта, выберите "Добавить", а затем выберите "Класс".
На диалоговом окне Добавить класс
- В поле "Имя класса " введите "profile_observer". Обратите внимание, что поля файлов H и .cpp автоматически заполняются в зависимости от введенного имени.
- По завершении нажмите кнопку "ОК ".
После создания файлов H и .cpp для класса оба файла открываются на вкладках "Группа редакторов". Теперь обновите каждый файл, чтобы реализовать новый класс наблюдателя:
Обновите "profile_observer.h", выбрав или удалив созданный
profile_observerкласс. Не удаляйте директивы препроцессора, созданные на предыдущем шаге (#pragma, #include). Затем скопируйте и вставьте следующий источник в файл после всех существующих директив препроцессора:#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; };Обновите "profile_observer.cpp", выбрав или удалив созданную
profile_observerреализацию класса. Не удаляйте директивы препроцессора, созданные на предыдущем шаге (#pragma, #include). Затем скопируйте и вставьте следующий источник в файл после всех существующих директив препроцессора:#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); }
При необходимости используйте F6 (сборка решения) для запуска тестовой компиляции/связывания вашего решения, чтобы убедиться, что она успешно выполняется перед тем как продолжить.
Внедрить делегата проверки подлинности
Пакет SDK MIP реализует проверку подлинности с помощью расширяемости классов, что позволяет совместно использовать задачу аутентификации с клиентским приложением. Клиент должен получить подходящий токен доступа OAuth2 и предоставить его SDK MIP во время выполнения.
Теперь создайте реализацию для делегата проверки подлинности, расширив класс пакета SDK mip::AuthDelegate и переопределяя или реализуя чистую виртуальную mip::AuthDelegate::AcquireOAuth2Token() функцию. Делегат проверки подлинности создается и используется позже объектами профиля файлов и обработчика файлов.
Используя ту же функцию Visual Studio "Добавить класс", которую мы использовали на шаге 1 предыдущего раздела, добавьте в проект другой класс. На этот раз введите "auth_delegate" в поле "Имя класса ".
Теперь обновите каждый файл, чтобы реализовать новый класс делегата проверки подлинности:
Обновите файл "auth_delegate.h", заменив весь созданный
auth_delegateкод класса следующим источником. Не удаляйте директивы препроцессора, созданные на предыдущем шаге (#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; };Обновите "auth_delegate.cpp", заменив весь сгенерированный код реализации класса
auth_delegateследующим кодом. Не удаляйте директивы препроцессора, созданные на предыдущем шаге (#pragma, #include).Это важно
Следующий код получения токена не подходит для использования в промышленной среде. В рабочей среде это должно быть заменено кодом, динамически получающим маркер, с помощью:
- Идентификатор приложения и URI ответа или перенаправления, указанный в регистрации приложения Microsoft Entra (URI ответа или перенаправления должен совпадать с регистрацией вашего приложения).
- URL-адрес центра и ресурса, переданный пакетом SDK в аргументе
challenge(URL-адрес ресурса должен соответствовать API и разрешениям регистрации приложения). - Допустимые учетные данные приложения или пользователя, где учетная запись соответствует аргументу
identity, передаваемого пакетом SDK. Клиенты OAuth2 "native" должны запрашивать учетные данные пользователя и использовать процесс "авторизационного кода". OAuth2 "конфиденциальные клиенты" могут использовать свои собственные безопасные учетные данные с потоком "учетные данные клиента" (например, служба) или запрашивать учетные данные пользователей с помощью потока "код авторизации" (например, веб-приложение).
Получение маркера OAuth2 — это сложный протокол, который обычно выполняется с помощью библиотеки. TokenAcquireOAuth2Token() вызывается только пакетом SDK MIP по мере необходимости.
#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; }
При необходимости используйте F6 (сборка решения) для запуска тестовой компиляции/связывания вашего решения, чтобы убедиться, что она успешно выполняется перед тем как продолжить.
Внедрение делегата согласия
Теперь создайте реализацию для делегата согласия, расширив класс пакета SDK mip::ConsentDelegate и переопределяя или реализуя чистую виртуальную mip::AuthDelegate::GetUserConsent() функцию. Делегат согласия создается и используется позже объектами профиля файлов и обработчика файлов.
Используя ту же функцию Visual Studio "Добавить класс", которую мы использовали ранее, добавьте другой класс в проект. На этот раз введите "consent_delegate" в поле "Имя класса ".
Теперь обновите каждый файл, чтобы реализовать новый класс делегата согласия:
Обновите файл "consent_delegate.h", заменив весь созданный
consent_delegateкод класса следующим источником. Не удаляйте директивы препроцессора, созданные на предыдущем шаге (#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; };Обновите "consent_delegate.cpp", заменив всю созданную
consent_delegateреализацию класса следующим кодом. Не удаляйте директивы препроцессора, созданные на предыдущем шаге (#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; }
При необходимости используйте F6 (сборка решения) для запуска тестовой компиляции/связывания вашего решения, чтобы убедиться, что она успешно выполняется перед тем как продолжить.
Создание профиля файла и движка
Как упоминалось, для клиентов пакета SDK с использованием API MIP требуются объекты профиля и движка. Завершите часть этого краткого руководства по программированию, добавив код для создания экземпляров объектов профиля и движка.
В обозревателе решений откройте файл .cpp в проекте, который содержит реализацию
main()метода. По умолчанию используется то же имя, что и проект, содержащий его, указанный во время создания проекта.Удалите созданную реализацию
main(). Не удаляйте директивы препроцессора, созданные Visual Studio во время создания проекта (#pragma, #include). Добавьте следующий код после любых директив препроцессора:
#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;
}
Замените все значения заполнителей в исходном коде, вставленном только что с помощью строковых констант:
Замещающее поле Ценность Пример <идентификатор приложения> Идентификатор приложения Microsoft Entra (GUID), назначенный приложению, зарегистрированным на шаге 2 статьи "Настройка и настройка пакета SDK MIP". Замените 2 вхождения. "0edbblll-8773-44de-b87c-b8c6276d41eb"<имя приложения> Пользовательское понятное имя для вашего приложения. Должен содержать допустимые символы ASCII (за исключением ";") и в идеале соответствует имени приложения, используемому в регистрации Microsoft Entra. "AppInitialization"<версия приложения> Определяемые пользователем сведения о версии приложения. Должен содержать допустимые символы ASCII (за исключением ";"). "1.1.0.0"<учетная запись двигателя> Учетная запись, используемая для идентификации движка. При проверке подлинности с учетной записью пользователя во время приобретения токена учетная запись должна соответствовать этому значению. "user1@tenant.onmicrosoft.com"<состояние подсистемы> Определяемое пользователем состояние, связанное с движком. "My App State"Теперь выполните окончательную сборку приложения и устраните все ошибки. Код должен успешно скомпилироваться, но еще не будет работать правильно, пока вы не завершите следующий шаг. При запуске приложения вы увидите выходные данные, аналогичные приведенным ниже. У вас не будет токена доступа, пока не выполните следующее краткое руководство.
Дальнейшие шаги
Теперь, когда код инициализации завершен, вы готовы к следующему этапу быстрого начала, где вы начнете изучать инструментарий SDK файлов MIP.