Szybki start: inicjowanie aplikacji klienckiej (C++)
W tym przewodniku Szybki start pokazano, jak wdrożyć wzorzec inicjowania klienta używany przez zestaw SDK MIP C++ w czasie wykonywania.
Uwaga
Kroki opisane w tym przewodniku Szybki start są wymagane dla każdej aplikacji klienckiej, która korzysta z pliku MIP, zasad lub zestawów SDK ochrony. Ten szybki start pokazuje użycie zestawów SDK plików, jednak ten sam wzorzec obowiązuje dla klientów korzystających z zestawów SDK zasad i ochrony. Wykonaj pozostałe zadania Szybki start po raz kolejny, ponieważ każda z nich jest kompilowana na poprzednim, przy tym pierwszym.
Wymagania wstępne
Jeśli jeszcze tego nie zrobić, pamiętaj, aby:
- Wykonaj czynności opisane w te Microsoft Information Protection (MIP) SDK konfiguracji. Ten przewodnik Szybki start "Inicjowanie aplikacji klienckich" korzysta z odpowiedniej konfiguracji i konfiguracji zestawu SDK.
- Opcjonalnie:
- Przejrzyj obiekty profilów i aparatów. Obiekty profilu i aparatu to uniwersalne koncepcje wymagane przez klientów, którzy korzystają z zestawów SDK plików/zasad/ochrony miP.
- Zapoznaj się z pojęciami uwierzytelniania, aby dowiedzieć się, jak uwierzytelnianie i zgoda są zaimplementowane przez zestaw SDK i aplikację kliencną.
- Przejrzyj koncepcje konceptuu, aby dowiedzieć się więcej na temat obserwatorów i sposobu ich wdrożenia. Zestaw SDK MIP używa wzorca wzorców asynchronicznych powiadomień o zdarzeniach.
Tworzenie Visual Studio i projektu
Najpierw tworzymy i konfigurujemy początkowe Visual Studio rozwiązania i projektu, na podstawie którego są konstruowane inne szybkie starty.
Otwórz Visual Studio 2017, wybierz menu Plik,Nowy, Project. W oknie Project dialogowym Nowe:
W okienku po lewej stronie w obszarze Zainstalowane, Inne językiwybierz Visual C++.
W środkowym okienku wybierz pozycję Windows Konsoli
W dolnym okienku zaktualizuj odpowiednio nazwę projektu,lokalizację i odpowiednio zawierającą nazwę rozwiązania.
Po zakończeniu kliknij przycisk OK w prawym dolnym rogu.
Dodaj pakiet Nuget do zestawu SDK pliku MIP do projektu:
W Eksploratorze rozwiązańkliknij prawym przyciskiem myszy węzeł projektu (bezpośrednio poniżej węzła górnego/węzła rozwiązania) i wybierz pozycję Zarządzaj NuGet pakietami...:
Gdy karta NuGet Menedżer pakietów zostanie otwarta w obszarze kart Grupy edytorów:
- Wybierz pozycję Przeglądaj.
- W polu wyszukiwania wprowadź "Microsoft.InformationProtection".
- Wybierz pakiet "Microsoft.InformationProtection.File".
- Kliknij przycisk "Zainstaluj", a następnie kliknij przycisk "OK", gdy zostanie wyświetlone okno dialogowe potwierdzenia zmian w podglądzie.
Implementowanie klasy obserwatorów w celu monitorowania obiektów profilu pliku i aparatu
Teraz należy utworzyć podstawową implementację klasy profilu pliku przez rozszerzenie klasy zestawu mip::FileProfile::Observer SDK. Obserwator jest wytężany i używany później do monitorowania ładowania obiektu Profilu pliku oraz dodawania obiektu aparatu do profilu.
Dodaj do projektu nową klasę, która wygeneruje dla Ciebie zarówno pliki nagłówka/.h, jak i implementacji/.cpp:
W Eksploratorze rozwiązańkliknij ponownie prawym przyciskiem myszy węzeł projektu, wybierz pozycję Dodaj, a następnie wybierz pozycję Klasa.
W oknie dialogowym Dodawanie zajęć:
- W polu Nazwa zajęć wprowadź "profile_observer". Zwróć uwagę, że zarówno pola pliku h, jak i pola pliku cpp są automatycznie wypełniane na podstawie wprowadzeniu nazwy.
- Po zakończeniu kliknij przycisk OK.
Po wygenerowaniu plików h i cpp dla zajęć oba pliki są otwierane na kartach Grupy Redaktora. Teraz zaktualizuj każdy plik, aby wdrożyć swoją nową klasę obserwatorów:
Zaktualizuj "profile_observer.h", zaznaczając/usuwając wygenerowaną
profile_observerklasę. Nie usuwaj użytkowników przedprocesowych wygenerowanych w poprzednim kroku (na przykład #pragma, #include). Następnie skopiuj/wklej do pliku następujące źródło po jakiejkolwiek istniejącej zaraz przedprocesorowi.#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; };Zaktualizuj "profile_observer.cpp", wybierając/usuwając wygenerowaną
profile_observerimplementację klasy. Nie usuwaj użytkowników przedprocesowych wygenerowanych w poprzednim kroku (na przykład #pragma, #include). Następnie skopiuj/wklej do pliku następujące źródło po jakiejkolwiek istniejącej zaraz przedprocesorowi.#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); }
Opcjonalnie użyj klawisza F6(kompilacjarozwiązania), aby uruchomić testowe zestawienie/link do rozwiązania, aby upewnić się, że będzie ono pomyślnie kompilowane przed kontynuowaniem.
Implementowanie pełnomocnika uwierzytelniania
Zestaw SDK protokołu MIP implementuje uwierzytelnianie za pomocą rozszerzalności klasy, który udostępnia mechanizm udostępniania uwierzytelniania podczas pracy z aplikacją kliencową. Klient musi uzyskać odpowiedni token dostępu OAuth2 i podać zestaw SDK MIP w czasie wykonywania.
Teraz utwórz implementację pełnomocnika uwierzytelniania, rozszerzając klasę zestawu SDK mip::AuthDelegate i zastępując/implementując funkcję mip::AuthDelegate::AcquireOAuth2Token() wyłącznie wirtualną. Pełnomocnik uwierzytelniania jest wystąpienia i używany później przez obiekty Profil pliku i Aparat plików.
Używając tej samej Visual Studio "Dodaj zajęcia" użytej w kroku nr 1 poprzedniej sekcji, dodaj kolejne zajęcia do projektu. Tym razem wprowadź "auth_delegate" w polu Nazwa zajęć.
Teraz zaktualizuj każdy plik, aby zaimplementować nową klasę pełnomocnika uwierzytelniania:
Zaktualizuj plik "auth_delegate.h", zastępując cały wygenerowany kod
auth_delegateklasy następującym źródłem. Nie usuwaj użytkowników przedprocesowych wygenerowanych w poprzednim kroku (na przykład #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; };Zaktualizuj plik "auth_delegate.cpp", zastępując wszystkie wygenerowane
auth_delegateimplementacje klasy następującym źródłem. Nie usuwaj użytkowników przedprocesowych wygenerowanych w poprzednim kroku (na przykład #pragma, #include).Ważne
Poniższy kod nabycia tokenu nie nadaje się do użytku produkcyjnego. W środowisku produkcyjnym musi to zostać zastąpione kodem, który dynamicznie otrzymuje token, używając:
- The appId and reply/redirect URI specified in your Azure AD app registration (reply/redirect URI must match match your app registration)
- Urząd i adres URL zasobu przekazany przez zestaw SDK w tym argumentie (adres URL zasobu musi być zgodne z interfejsem
challengeAPI/uprawnieniami rejestracji aplikacji)challenge - Prawidłowe poświadczenia aplikacji/użytkownika, dla których konto jest odpowiednie dla
identityargumentu przekazywanego przez zestaw SDK. Klienci "natywny" OAuth2 powinni monitować o poświadczenia użytkownika i używać przepływu "autoryzacji". "Klienci poufni" OAuth2 mogą używać własnych bezpiecznych poświadczeń przy użyciu przepływu "poświadczeń klienta" (na przykład usługi) lub monitować o poświadczenia użytkowników przy użyciu przepływu "kod autoryzacji" (na przykład aplikacji sieci Web).
Pozyskiwanie tokenu OAuth2 jest złożonym protokołem i zwykle odbywa się przy użyciu biblioteki. TokenAcquireOAuth2Token() jest wywoływany tylko przez zestaw SDK MIP, zgodnie z wymaganiami.
#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; }
Opcjonalnie użyj klawisza F6(kompilacjarozwiązania), aby uruchomić testowe zestawienie/link do rozwiązania, aby upewnić się, że będzie ono pomyślnie kompilowane przed kontynuowaniem.
Implementowanie pełnomocnika zgody
Teraz utwórz implementację pełnomocnika zgody, rozszerzając klasę zestawu SDK mip::ConsentDelegate i zastępując/implementując funkcję mip::AuthDelegate::GetUserConsent() wyłącznie wirtualną. Pełnomocnik zgody jest wystąpienia i używany później przez obiekty Profil pliku i Aparat plików.
Używając tej samej Visual Studio "Dodaj zajęcia" użytej wcześniej, dodaj kolejne zajęcia do projektu. Tym razem wprowadź "consent_delegate" w polu Nazwa zajęć.
Teraz zaktualizuj każdy plik, aby zaimplementować nową klasę pełnomocnika zgody:
Zaktualizuj "consent_delegate.h", zastępując cały wygenerowany kod
consent_delegateklasy następującym źródłem. Nie usuwaj użytkowników przedprocesowych wygenerowanych w poprzednim kroku (na przykład #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; };Zaktualizuj plik "consent_delegate.cpp", zastępując wszystkie wygenerowane
consent_delegateimplementacje klasy następującym źródłem. Nie usuwaj użytkowników przedprocesowych wygenerowanych w poprzednim kroku (na przykład #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; }
Opcjonalnie użyj klawisza F6(kompilacjarozwiązania), aby uruchomić testowe zestawienie/link do rozwiązania, aby upewnić się, że będzie ono pomyślnie kompilowane przed kontynuowaniem.
Konstruowanie profilu pliku i aparatu
Jak wspomniano, obiekty profilu i aparatu są wymagane dla klientów zestawu SDK korzystających z interfejsów API miP. Ukończ kodowanie tej funkcji Szybki start, dodając kod w celu wystąpienia obiektów profilu i aparatu:
W Eksploratorze rozwiązańotwórz plik cpp w projekcie, który zawiera implementację metody. Domyślna nazwa jest taka sama jak nazwa projektu zawierającego projekt, która jest określona podczas tworzenia projektu.
Usuń wygenerowaną implementację
main()programu . Nie usuwaj preprocesorów wygenerowanych przez Visual Studio podczas tworzenia projektu (#pragma, #include). Dołącz następujący kod po wszystkich przedprocesowych danych źródłowych:
#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>(mAppInfo,
"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,
authDelegateImpl,
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)
"<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;
mipContext.Shutdown();
mipContext = nullptr;
return 0;
}
Zamień wszystkie wartości zastępcze w właśnie wklejonym kodzie źródłowym, używając stałych ciągów:
Symbol zastępczy Wartość Przykład <application-id> Identyfikator aplikacji usługi Azure AD (GUID) przypisany do aplikacji zarejestrowanej w kroku 2 artykułu "Konfiguracja i konfiguracja zestawu SDK MIP". Zamień 2 wystąpienia. "0edbblll-8773-44de-b87c-b8c6276d41eb"<nazwa aplikacji> Zdefiniowana przez użytkownika przyjazna nazwa aplikacji. Musi zawierać prawidłowe znaki ASCII (z wyjątkiem znaków ';') i najlepiej pasuje do nazwy aplikacji użytej podczas rejestracji w usłudze Azure AD. "AppInitialization"<application-version> Informacje o wersji zdefiniowanej przez użytkownika dla aplikacji. Musi zawierać prawidłowe znaki ASCII (z wyjątkiem znaków ';'). "1.1.0.0"<engine-account> Konto używane na celu tożsamości aparatu. Uwierzytelnianie przy użyciu konta użytkownika podczas pozyskiwania tokenu musi być zgodne z tą wartością. "user1@tenant.onmicrosoft.com"<stan-aparat> Stan zdefiniowany przez użytkownika, który ma zostać skojarzony z aparatem. "My App State"Teraz wykonaj ostateczną kompilację aplikacji i rozwiąż wszelkie błędy. Kod powinien zostać pomyślnie skompilowany, ale nie będzie działał poprawnie do momentu ukończenia następnego przewodnika Szybki start. Po uruchomieniu aplikacji zobaczysz dane wyjściowe podobne do poniższych. Nie będziesz mieć tokenu dostępu do podania, dopóki nie ukończysz następnego przewodnika Szybki start.
Następne kroki
Teraz, gdy kod inicjowania został ukończony, możesz rozpocząć kolejny szybki start, w którym będą dostępne zestawy SDK plików MIP.


