Rychlý start: Inicializace klientské aplikace (C++)
V tomto rychlém startu se dozvíte, jak implementovat model inicializace klienta používaný sadou MIP C++ SDK za běhu.
Poznámka:
Kroky popsané v tomto rychlém startu se vyžadují pro všechny klientské aplikace, které používají sady SDK MIP File, Policy nebo Protection. I když tento rychlý start ukazuje použití sad FILE SDK, tento vzor platí pro klienty používající sady SDK zásad a ochrany. Dokončete zbývající rychlé starty sériově, protože každý z nich vychází z předchozího, přičemž tento rychlý start je první.
Předpoklady
Pokud jste to ještě neudělali, nezapomeňte:
- Dokončete kroky v nastavení a konfiguraci sady Microsoft Information Protection (MIP) SDK. Tento rychlý start "Inicializace klientské aplikace" spoléhá na správné nastavení a konfiguraci sady SDK.
- Volitelně:
- Zkontrolujte objekty profilu a modulu. Objekty profilu a modulu jsou univerzální koncepty vyžadované klienty, kteří používají sady SDK MIP File/Policy/Protection.
- Projděte si koncepty ověřování a zjistěte, jak jsou ověřování a souhlas implementovány sadou SDK a klientskou aplikací.
- Projděte si koncepty pozorovatele a seznamte se s dalšími pozorovateli a jejich implementací. Sada MIP SDK používá vzor pozorovatele k implementaci asynchronních oznámení událostí.
Vytvoření řešení a projektu sady Visual Studio
Nejprve vytvoříme a nakonfigurujeme počáteční řešení a projekt sady Visual Studio, na kterém se sestaví další rychlé starty.
Otevřete Visual Studio 2017 a vyberte nabídku Soubor , Nový, Projekt. V dialogovém okně Nový projekt :
V levém podokně v části Nainstalováno, Další jazyky vyberte Visual C++.
V prostředním podokně vyberte Konzolová aplikace systému Windows.
V dolním podokně odpovídajícím způsobem aktualizujte název projektu, umístění a obsahující název řešení.
Po dokončení klikněte na tlačítko OK v pravém dolním rohu.
Přidejte balíček NuGet pro sadu MIP File SDK do projektu:
V Průzkumník řešení klikněte pravým tlačítkem myši na uzel projektu (přímo pod horním uzlem nebo uzlem řešení) a vyberte Spravovat balíčky NuGet...:
Když se v oblasti Karet skupiny editoru otevře karta Správce balíčků NuGet:
- Vyberte Procházet.
- Do vyhledávacího pole zadejte "Microsoft.InformationProtection".
- Vyberte balíček Microsoft.InformationProtection.File.
- Po zobrazení potvrzovací dialogového okna Náhled změn klikněte na Instalovat a potom klikněte na OK.
Implementace třídy pozorovatele pro monitorování profilu souboru a objektů modulu
Teď vytvořte základní implementaci pro třídu pozorovatele profilu souboru rozšířením třídy sady SDK mip::FileProfile::Observer
. Pozorovatel se vytvoří instance a později se použije k monitorování načítání objektu profilu Souboru a přidání objektu modulu do profilu.
Přidejte do projektu novou třídu, která za vás vygeneruje soubory header/.h i implementation/.cpp:
V Průzkumník řešení znovu klikněte pravým tlačítkem myši na uzel projektu, vyberte Přidat a pak vyberte Třída.
V dialogovém okně Přidat třídu :
- Do pole Název třídy zadejte "profile_observer". Všimněte si, že pole souboru .h i souboru .cpp se automaticky vyplní na základě zadaného názvu.
- Po dokončení klikněte na tlačítko OK .
Po vygenerování souborů .h a .cpp pro třídu se oba soubory otevřou na kartách Skupina editoru. Teď aktualizujte každý soubor tak, aby implementovali novou třídu pozorovatele:
Aktualizujte "profile_observer.h" tak, že vyberete nebo odstraníte vygenerovanou
profile_observer
třídu. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#pragma, #include). Potom zkopírujte/vložte následující zdroj do souboru za všechny existující direktivy preprocesoru:#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; };
Aktualizujte "profile_observer.cpp" výběrem nebo odstraněním vygenerované
profile_observer
implementace třídy. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#pragma, #include). Potom zkopírujte/vložte následující zdroj do souboru za všechny existující direktivy preprocesoru:#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); }
Volitelně můžete pomocí F6 (sestavit řešení) spustit testovací kompilaci nebo propojení vašeho řešení, abyste se ujistili, že se sestavení úspěšně sestaví, než budete pokračovat.
Implementace delegáta ověřování
Sada MIP SDK implementuje ověřování pomocí rozšiřitelnosti tříd, který poskytuje mechanismus pro sdílení ověřování s klientskou aplikací. Klient musí získat vhodný přístupový token OAuth2 a poskytnout sadě MIP SDK za běhu.
Teď vytvořte implementaci pro delegáta ověřování rozšířením třídy sady SDK mip::AuthDelegate
a přepsáním nebo implementací mip::AuthDelegate::AcquireOAuth2Token()
čistě virtuální funkce. Delegát ověřování se vytvoří instance a později ho použije objekty file profile a file engine.
Pomocí stejné funkce Přidat třídu v sadě Visual Studio, kterou jsme použili v kroku 1 předchozí části, přidejte do projektu další třídu. Tentokrát do pole Název třídy zadejte "auth_delegate".
Teď aktualizujte každý soubor tak, aby implementovali novou třídu delegáta ověřování:
Aktualizujte "auth_delegate.h" nahrazením veškerého vygenerovaného
auth_delegate
kódu třídy následujícím zdrojem. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#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; };
Aktualizujte "auth_delegate.cpp" nahrazením všech vygenerovaných
auth_delegate
implementací třídy následujícím zdrojem. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#pragma, #include).Důležité
Následující kód získání tokenu není vhodný pro použití v produkčním prostředí. V produkčním prostředí musí být nahrazen kódem, který dynamicky získává token pomocí:
- Id aplikace a identifikátor URI pro odpověď/přesměrování zadaný v registraci aplikace Microsoft Entra (odpověď/identifikátor URI přesměrování musí odpovídat vaší registraci aplikace)
- Adresa URL autority a prostředku předaná sadou SDK v argumentu
challenge
(adresa URL prostředku musí odpovídat rozhraní API nebo oprávnění registrace vaší aplikace) - Platné přihlašovací údaje aplikace/uživatele, kde účet odpovídá argumentu
identity
předaného sadou SDK. Nativní klienti OAuth2 by měli vyzvat k zadání přihlašovacích údajů uživatele a použít tok autorizačního kódu. "Důvěrné klienty" OAuth2 můžou používat vlastní zabezpečené přihlašovací údaje s tokem "přihlašovacích údajů klienta" (jako je služba) nebo zobrazit výzvu k zadání přihlašovacích údajů uživatele pomocí toku "autorizačního kódu" (například webové aplikace).
Získání tokenu OAuth2 je složitý protokol, který se obvykle provádí pomocí knihovny. TokenAcquireOAuth2Token() je volána pouze sadou MIP SDK podle potřeby.
#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; }
Volitelně můžete pomocí F6 (sestavit řešení) spustit testovací kompilaci nebo propojení vašeho řešení, abyste se ujistili, že se sestavení úspěšně sestaví, než budete pokračovat.
Implementace delegáta souhlasu
Teď vytvořte implementaci pro delegáta souhlasu rozšířením třídy sady SDK mip::ConsentDelegate
a přepsáním nebo implementací mip::AuthDelegate::GetUserConsent()
čisté virtuální funkce. Delegát souhlasu se vytvoří instance a později ho použije objekty file profile a file engine.
Pomocí stejné funkce Přidat třídu sady Visual Studio, kterou jsme použili dříve, přidejte do projektu další třídu. Tentokrát do pole Název třídy zadejte "consent_delegate".
Teď aktualizujte každý soubor tak, aby implementovali novou třídu delegáta souhlasu:
Aktualizujte "consent_delegate.h" nahrazením veškerého vygenerovaného
consent_delegate
kódu třídy následujícím zdrojem. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#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; };
Aktualizujte "consent_delegate.cpp" nahrazením všech vygenerovaných
consent_delegate
implementací třídy následujícím zdrojem. Neodebíjejte direktivy preprocesoru generované předchozím krokem (#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; }
Volitelně můžete pomocí F6 (sestavit řešení) spustit testovací kompilaci nebo propojení vašeho řešení, abyste se ujistili, že se sestavení úspěšně sestaví, než budete pokračovat.
Vytvoření profilu souboru a modulu
Jak už bylo zmíněno, objekty profilu a modulu jsou vyžadovány pro klienty sady SDK pomocí rozhraní API MIP. Dokončete část kódu tohoto rychlého startu přidáním kódu pro vytvoření instance objektů profilu a modulu:
Z Průzkumník řešení otevřete v projektu soubor .cpp, který obsahuje implementaci
main()
metody. Ve výchozím nastavení se použije stejný název jako projekt, který obsahuje, který jste zadali při vytváření projektu.Odeberte vygenerovanou implementaci .
main()
Neodebíjejte direktivy preprocesoru generované sadou Visual Studio během vytváření projektu (#pragma, #include). Za všechny direktivy preprocesoru připojte následující kód:
#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;
}
Nahraďte všechny zástupné hodnoty ve zdrojovém kódu, které jste právě vložili, pomocí řetězcových konstant:
Zástupný symbol Hodnota Příklad <ID aplikace> ID aplikace Microsoft Entra (GUID) přiřazené k aplikaci zaregistrované v kroku 2 článku Nastavení a konfigurace sady MIP SDK. Nahraďte 2 instance. "0edbblll-8773-44de-b87c-b8c6276d41eb"
<název aplikace> Uživatelsky definovaný popisný název aplikace. Musí obsahovat platné znaky ASCII (s výjimkou ;) a v ideálním případě se shoduje s názvem aplikace, který jste použili v registraci Microsoft Entra. "AppInitialization"
<verze aplikace> Informace o verzi definované uživatelem pro vaši aplikaci Musí obsahovat platné znaky ASCII (s výjimkou ;). "1.1.0.0"
<účet engine-account> Účet použitý pro identitu modulu. Při ověřování pomocí uživatelského účtu během získávání tokenů se musí shodovat s touto hodnotou. "user1@tenant.onmicrosoft.com"
<stav motoru> Uživatelem definovaný stav, který se má přidružit k modulu. "My App State"
Teď proveďte finální sestavení aplikace a vyřešte případné chyby. Kód by se měl úspěšně sestavit, ale ještě se nespustí správně, dokud nedokončíte další rychlý start. Pokud spustíte aplikaci, zobrazí se výstup podobný následujícímu. Přístupový token nebudete mít k dispozici, dokud nedokončíte další rychlý start.
Další kroky
Teď, když je inicializační kód hotový, jste připraveni na další rychlý start, kde začnete používat sady MIP File SDK.