Поделиться через


Быстрый старт: Инициализация клиентского приложения для SDK-библиотек защиты (C++)

В этом кратком руководстве показано, как реализовать шаблон инициализации клиента, используемый пакетом SDK MIP C++ во время выполнения.

Примечание.

Действия, описанные в этом кратком руководстве, необходимы для любого клиентского приложения, использующего пакеты SDK для защиты MIP. Эти краткие руководства должны выполняться последовательно после инициализации приложения и реализации классов делегатов проверки подлинности и согласия.

Предпосылки

Если вы еще не сделали этого, обязательно выполните следующие действия.

  • Выполните действия, описанные в настройке и конфигурации пакета SDK Microsoft Information Protection (MIP). Это краткое руководство по инициализации клиентского приложения зависит от правильной настройки пакета SDK.
  • Необязательно:
    • Просмотрите объекты профиля и обработчика. Объекты профиля и движка — это универсальные понятия, необходимые клиентам, использующим SDK для MIP-файлов, политик и защиты.
    • Ознакомьтесь с концепциями проверки подлинности , чтобы узнать, как проверка подлинности и согласие реализованы пакетом SDK и клиентским приложением.
    • Ознакомьтесь с концепциями наблюдателя , чтобы узнать больше о наблюдателях и о том, как они реализуются. Пакет SDK MIP использует шаблон наблюдателя для реализации асинхронных уведомлений о событиях.

Создание решения и проекта Visual Studio

Сначала мы создаём и настраиваем начальное решение и проект в Visual Studio, на которых основываются другие быстрые старты.

  1. Откройте Visual Studio 2017, выберите меню "Файл ", "Создать", "Проект". В диалоговом окне "Новый проект ":

    • В области слева в разделе "Установленные", "Другие языки" выберите Visual C++.

    • В центральной области выберите консольное приложение Windows

    • В нижней области обновите имя проекта, расположение и соответствующее имя содержащего решения .

    • По завершении нажмите кнопку "ОК " в правом нижнем углу.

      Создание решения Visual Studio

  2. Добавьте пакет Nuget для пакета SDK для защиты MIP в проект:

    • В Обозревателе решений щелкните правой кнопкой мыши по узлу проекта (непосредственно под верхним узлом или узлом решения) и выберите "Управление пакетами NuGet..."

    • Когда откроется вкладка Диспетчер пакетов NuGet в области вкладок группы редакторов:

      • Выберите Обзор.
      • В поле поиска введите "Microsoft.InformationProtection".
      • Выберите пакет Microsoft.InformationProtection.Protection.
      • Нажмите кнопку "Установить", а затем нажмите кнопку "ОК" при отображении диалогового окна подтверждения изменений предварительного просмотра .

      Добавление пакета NuGet в Visual Studio

Реализуйте классы наблюдателей для мониторинга профиля защиты и объектов движка

Теперь создайте базовую реализацию для класса наблюдателя профиля Защиты, расширив класс ПАКЕТА SDK mip::ProtectionProfile::Observer . Наблюдатель создается как объект и используется позже для мониторинга загрузки объекта профиля Защита, а также для добавления объекта движка в профиль.

  1. Добавьте новый класс в свой проект, который автоматически генерирует для вас заголовочные файлы (.h) и файлы реализации (.cpp).

    • В обозревателе решений снова щелкните правой кнопкой мыши узел проекта, выберите "Добавить", а затем выберите "Класс".

    • В диалоговом окне добавления класса :

      • В поле "Имя класса " введите "profile_observer". Обратите внимание, что поля файлов H и .cpp автоматически заполняются в зависимости от введенного имени.
      • По завершении нажмите кнопку "ОК ".

      Добавление класса Visual Studio

  2. После создания файлов 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);
      }
      
  3. Выполните действия, описанные в 1. добавьте в проект новый класс для наблюдателя модуля защиты — "engine_observer", который создает как файлы заголовка (.h), так и реализации (.cpp) для вас.

  4. После создания файлов 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);
        };
      
  5. При необходимости используйте CTRL+SHIFT+B (сборка решения) для запуска тестовой компиляции или ссылки решения, чтобы убедиться, что она успешно выполняет сборку, прежде чем продолжить.

Пакет SDK MIP реализует проверку подлинности с помощью расширяемости классов, что позволяет совместно использовать задачу аутентификации с клиентским приложением. Клиент должен получить подходящий токен доступа OAuth2 и предоставить его SDK MIP во время выполнения.

Создайте реализацию для делегата проверки подлинности, расширив класс пакета SDK mip::AuthDelegate и переопределяя или реализуя чистую виртуальную mip::AuthDelegate::AcquireOAuth2Token() функцию. Выполните действия, описанные в кратком руководстве по инициализации приложений пакета SDK для файлов. Делегат проверки подлинности создается и используется позже объектами профиля защиты и движка защиты.

Теперь создайте реализацию для делегата согласия, расширив класс пакета SDK mip::ConsentDelegate и переопределяя или реализуя чистую виртуальную mip::AuthDelegate::GetUserConsent() функцию. Выполните действия, описанные в кратком руководстве по инициализации приложений пакета SDK для файлов. Делегат согласия создается как экземпляр и позже используется объектами профиля защиты и движка защиты.

Создайте профиль защиты и движок

Как упоминалось, для клиентов пакета SDK с использованием API MIP требуются объекты профиля и движка. Завершите часть этого краткого руководства по программированию, добавив код для создания экземпляров объектов профиля и движка.

  1. В обозревателе решений откройте файл .cpp в проекте, который содержит реализацию main() метода. По умолчанию используется то же имя, что и проект, содержащий его, указанный во время создания проекта.

  2. Удалите созданную реализацию 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;
}
  1. Замените все значения заполнителей в исходном коде, вставленном только что с помощью строковых констант:

    Замещающее поле Ценность Пример
    <идентификатор приложения> Идентификатор приложения Microsoft Entra (GUID), назначенный приложению, зарегистрированным на шаге 2 статьи "Настройка и конфигурация пакета SDK MIP" (setup-configure-mip.md). Замените 2 вхождения. "0edbblll-8773-44de-b87c-b8c6276d41eb"
    <имя приложения> Пользовательское понятное имя для вашего приложения. Должен содержать допустимые символы ASCII (за исключением ";") и в идеале соответствует имени приложения, используемому в регистрации Microsoft Entra. "AppInitialization"
    <версия приложения> Определяемые пользователем сведения о версии приложения. Должен содержать допустимые символы ASCII (за исключением ";"). "1.1.0.0"
    <учетная запись engine-account> Учетная запись, используемая для идентификации движка. При проверке подлинности с учетной записью пользователя во время приобретения токена учетная запись должна соответствовать этому значению. "[email protected]"
    <состояние подсистемы> Определяемое пользователем состояние, связанное с движком. "My App State"
  2. Теперь выполните окончательную сборку приложения и устраните все ошибки. Код должен успешно скомпилироваться, но еще не будет работать правильно, пока вы не завершите следующий шаг. При запуске приложения вы увидите выходные данные, аналогичные приведенным ниже. Приложение создаст профиль защиты и подсистему защиты, но модуль проверки подлинности не будет активирован, и у вас еще не будет токена доступа, пока вы не завершите следующее краткое руководство.

     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.