Linux-CodebeispieleLinux code examples

Wichtig

Versionen des Microsoft Rights Management Service SDK, die vor dem 2020 von März veröffentlicht wurden, sind veraltet. Anwendungen, die frühere Versionen verwenden, müssen aktualisiert werden, um die Version vom März 2020 zu verwenden.Versions of the Microsoft Rights Management Service SDK released prior to March 2020 are deprecated; applications using earlier versions must be updated to use the March 2020 release. Ausführliche Informationen finden Sie im Hinweis zur Veraltung.For full details, see the deprecation notice.

Für das Microsoft Rights Management Service SDK sind keine weiteren Erweiterungen geplant.No further enhancements are planned for the Microsoft Rights Management Service SDK. Es wird dringend empfohlen, das Microsoft Information Protection SDK für Klassifizierungen, Bezeichnungen und Schutzdienste zu erhalten.We strongly recommend adoption of the Microsoft Information Protection SDK for classification, labeling, and protection services.

In diesem Thema werden wichtige Szenarien Codeelemente der Linux-Version des RMS SDK vorgestellt.This topic introduces you to important scenarios and code elements for the Linux version of the RMS SDK.

Die folgenden Code Ausschnitte stammen aus den Beispielanwendungen RMS _ Sample und rmsauth _ Sample.The code snippets below are from the sample applications, rms_sample and rmsauth_sample. Weitere Informationen finden Sie im GitHub-Repository unter Beispiele.For more information, see samples at the GitHub repository.

Szenario: Zugriff auf Informationen der Schutzrichtlinie einer geschützten DateiScenario: Access protection policy information from a protected file

Öffnet und liest eine RMS-geschützte Datei . Quelle: RMS _ Sample/MainWindow. cppOpens and reads an RMS protected file Source: rms_sample/mainwindow.cpp

Beschreibung: Nachdem ein Dateinamen vom Benutzer erhalten wurde, werden die Zertifikate gelesen (siehe MainWindow::addCertificates), der Autorisierungsrückruf mit Client-ID und Umleitungs-URL wird eingerichtet und ConvertFromPFile wird aufgerufen (siehe folgendes Codebeispiel). Anschließend werden der Name der Schutzrichtlinie, die Beschreibung und das Gültigkeitsdatum des Inhalts ausgelesen.Description: After getting a file name from the user, reading the certificates (see MainWindow::addCertificates), setting up the authorization callback with Client ID and Redirect URL, calling ConvertFromPFile (see following code example), then reading out the protection policy name, description and content validity date.

C++:C++:

  void MainWindow::ConvertFromPFILE(const string& fileIn,
      const string& clientId,
      const string& redirectUrl,
      const string& clientEmail) 
  {
  // add trusted certificates using HttpHelpers of RMS and Auth SDKs
  addCertificates();
  
  // create shared in/out streams
  auto inFile = make_shared<ifstream>(
  fileIn, ios_base::in | ios_base::binary);
  
  if (!inFile->is_open()) {
   AddLog("ERROR: Failed to open ", fileIn.c_str());
  return;
  }
  
  string fileOut;
  
  // generate output filename
  auto pos = fileIn.find_last_of('.');
  
  if (pos != string::npos) {
   fileOut = fileIn.substr(0, pos);
  }
  
   // create streams
  auto outFile = make_shared<fstream>(
  fileOut, ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary);
  
  if (!outFile->is_open()) {
   AddLog("ERROR: Failed to open ", fileOut.c_str());
   return;
    }
  
  try
  {
  // create authentication context
  AuthCallback auth(clientId, redirectUrl);
  
  // process conversion
  auto pfs = PFileConverter::ConvertFromPFile(
    clientEmail,
    inFile,
    outFile,
    auth,
    this->consent);
  
  AddLog("Successfully converted to ", fileOut.c_str());
  }
  catch (const rmsauth::Exception& e)
  {
  AddLog("ERROR: ", e.error().c_str());
  }
  catch (const rmscore::exceptions::RMSException& e) {
  AddLog("ERROR: ", e.what());
  }
  inFile->close();
  outFile->close();
  }

Erstellen eines geschützten Datei Datenstroms Quelle: RMS _ Sample/pfileconverter. cppCreate a protected file stream Source: rms_sample/pfileconverter.cpp

Description: Diese Methode erstellt einen geschützten Dateistream aus dem weiter gegebenen sicherungsstream über die SDK-Methode protectedfilestream:: Abruf, die dann an den Aufrufer zurückgegeben wird.Description: This method creates a protected file stream from the passed in backing stream through the SDK method, ProtectedFileStream::Acquire, which is then returned to the caller.

C++:C++:

  shared_ptr<GetProtectedFileStreamResult>PFileConverter::ConvertFromPFile(
  const string           & userId,
  shared_ptr<istream>      inStream,
  shared_ptr<iostream>     outStream,
  IAuthenticationCallback& auth,
  IConsentCallback       & consent)
  {
  auto inIStream = rmscrypto::api::CreateStreamFromStdStream(inStream);
  
  auto fsResult = ProtectedFileStream::Acquire(
  inIStream,
  userId,
  auth,
  consent,
  POL_None,
  static_cast<ResponseCacheFlags>(RESPONSE_CACHE_INMEMORY
                                  | RESPONSE_CACHE_ONDISK));
  
  if ((fsResult.get() != nullptr) && (fsResult->m_status == Success) &&
    (fsResult->m_stream != nullptr)) {
  auto pfs = fsResult->m_stream;
  
  // preparing
  readPosition  = 0;
  writePosition = 0;
  totalSize     = pfs->Size();
  
  // start threads
  for (size_t i = 0; i < THREADS_NUM; ++i) {
    threadPool.push_back(thread(WorkerThread,
                                static_pointer_cast<iostream>(outStream), pfs,
                                false));
  }
  
  for (thread& t: threadPool) {
    if (t.joinable()) {
      t.join();
    }
  }
  }
    return fsResult;
  }

Szenario: Erstellen einer neuen geschützten Datei mithilfe einer VorlageScenario: Create a new protected file using a template

Schützt eine Datei mit einer vom Benutzer ausgewählten Vorlage . Quelle: RMS _ Sample/MainWindow. cppProtects a file with a user selected template Source: rms_sample/mainwindow.cpp

Beschreibung: Nachdem ein Dateinamen vom Benutzer erhalten wurde, werden die Zertifikate gelesen (siehe MainWindow::addCertificates) und der Autorisierungsrückruf mit Client-ID und Umleitungs-URL wird eingerichtet. Die ausgewählte Datei wird durch den Aufruf von ConvertToPFileTemplates geschützt (siehe folgendes Codebeispiel).Description: After getting a file name from the user, reading the certificates (see MainWindow::addCertificates) and setting up the authorization callback with Client ID and Redirect URL, the selected file is protected by calling ConvertToPFileTemplates (see following code example).

C++:C++:

  void MainWindow::ConvertToPFILEUsingTemplates(const string& fileIn,
                                            const string& clientId,
                                            const string& redirectUrl,
                                            const string& clientEmail) 
  {
  // generate output filename
  string fileOut = fileIn + ".pfile";
  
  // add trusted certificates using HttpHelpers of RMS and Auth SDKs
  addCertificates();
  
  // create shared in/out streams
  auto inFile = make_shared<ifstream>(
  fileIn, ios_base::in | ios_base::binary);
  auto outFile = make_shared<fstream>(
  fileOut, ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary);
  
  if (!inFile->is_open()) {
  AddLog("ERROR: Failed to open ", fileIn.c_str());
  return;
  }
  
  if (!outFile->is_open()) {
  AddLog("ERROR: Failed to open ", fileOut.c_str());
  return;
  }
  
  // find file extension
  string fileExt;
  auto   pos = fileIn.find_last_of('.');
  
  if (pos != string::npos) {
  fileExt = fileIn.substr(pos);
  }
  
  try {
  // create authentication callback
  AuthCallback auth(clientId, redirectUrl);
  
  // process conversion
  PFileConverter::ConvertToPFileTemplates(
    clientEmail, inFile, fileExt, outFile, auth,
    this->consent, this->templates);
  
  AddLog("Successfully converted to ", fileOut.c_str());
  }
 catch (const rmsauth::Exception& e) {
  AddLog("ERROR: ", e.error().c_str());
  outFile->close();
  remove(fileOut.c_str());
  }
  catch (const rmscore::exceptions::RMSException& e) {
  AddLog("ERROR: ", e.what());
  
  outFile->close();
  remove(fileOut.c_str());
  }
  inFile->close();
  outFile->close();
  }

Schützt eine Datei mithilfe einer aus einer Vorlage erstellten Richtlinie. Quelle: RMS _ Sample/pfileconverter. cppProtects a file using a policy created from a template Source: rms_sample/pfileconverter.cpp

Beschreibung: Eine Liste mit dem Benutzer zugeordneten Vorlagen wird abgerufen. Mithilfe der ausgewählte Vorlage wird dann eine Richtlinie zum Schutz der Datei erstellt.Description: A list of templates associated with the user is fetched and selected template is then used to create a policy which in turn is used to protect the file.

C++:C++:

  void PFileConverter::ConvertToPFileTemplates(const string           & userId,
                                           shared_ptr<istream>      inStream,
                                           const string           & fileExt,
                                           std::shared_ptr<iostream>outStream,
                                           IAuthenticationCallback& auth,
                                           IConsentCallback& /*consent*/,
                                           ITemplatesCallback     & templ)
  {
  auto templates = TemplateDescriptor::GetTemplateList(userId, auth);
  
  rmscore::modernapi::AppDataHashMap signedData;
  
  size_t pos = templ.SelectTemplate(templates);
  
  if (pos < templates.size()) {
  auto policy = UserPolicy::CreateFromTemplateDescriptor(
    templates[pos],
    userId,
    auth,
    USER_AllowAuditedExtraction,
    signedData);
 
  ConvertToPFileUsingPolicy(policy, inStream, fileExt, outStream);
  }
  }

Schützt eine Datei mit einer bestimmten Richtlinie . Quelle: RMS _ Sample/pfileconverter. cppProtects a file given a policy Source: rms_sample/pfileconverter.cpp

Beschreibung: Hierbei wird ein geschützter Dateidatenstrom mithilfe der angegebenen Richtlinie erstellt und anschließend die Datei geschützt.Description: Create a protected file stream using the given policy then protect that file.

C++:C++:

  void PFileConverter::ConvertToPFileUsingPolicy(shared_ptr<UserPolicy>   policy,
                                             shared_ptr<istream>      inStream,
                                             const string           & fileExt,
                                             std::shared_ptr<iostream>outStream)
  {
  if (policy.get() != nullptr) {
  auto outIStream = rmscrypto::api::CreateStreamFromStdStream(outStream);
  auto pStream    = ProtectedFileStream::Create(policy, outIStream, fileExt);
  
  // preparing
  readPosition  = 0;
  writePosition = pStream->Size();
  
  inStream->seekg(0, ios::end);
  totalSize = inStream->tellg();
  
  // start threads
  for (size_t i = 0; i < THREADS_NUM; ++i) {
    threadPool.push_back(thread(WorkerThread,
                                static_pointer_cast<iostream>(inStream),
                                pStream,
                                true));
  }
  
  for (thread& t: threadPool) {
    if (t.joinable()) {
      t.join();
    }
  }
  
  pStream->Flush();
  }

Szenario: Schützen einer Datei mit benutzerdefiniertem SchutzScenario: Protect a file using custom protection

Schützt eine Datei mit benutzerdefiniertem Schutz Quelle: RMS _ Sample/MainWindow. cppProtects a file using custom protection Source: rms_sample/mainwindow.cpp

Beschreibung: Nachdem ein Dateinamen vom Benutzer erhalten wurde, werden die Zertifikate gelesen (siehe MainWindow::addCertificates), Informationen zu den jeweiligen Benutzerrechten abgerufen und der Autorisierungsrückruf mit Client-ID und Umleitungs-URL eingerichtet. Die ausgewählte Datei wird durch den Aufruf von ConvertToPFilePredefinedRights geschützt (siehe folgendes Codebeispiel).Description: After getting a file name from the user, reading the certificates (see MainWindow::addCertificates), collecting rights information from the user, and setting up the authorization callback with Client ID and Redirect URL, the selected file is projected by calling ConvertToPFilePredefinedRights (see following code example).

C++:C++:

  void MainWindow::ConvertToPFILEUsingRights(const string            & fileIn,
                                         const vector<UserRights>& userRights,
                                         const string            & clientId,
                                         const string            & redirectUrl,
                                         const string            & clientEmail)
  {
  // generate output filename
  string fileOut = fileIn + ".pfile";
  
  // add trusted certificates using HttpHelpers of RMS and Auth SDKs
  addCertificates();
  
  // create shared in/out streams
  auto inFile = make_shared<ifstream>(
  fileIn, ios_base::in | ios_base::binary);
  auto outFile = make_shared<fstream>(
  fileOut, ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary);
  
  if (!inFile->is_open()) {
  AddLog("ERROR: Failed to open ", fileIn.c_str());
  return;
  }
  
  if (!outFile->is_open()) {
  AddLog("ERROR: Failed to open ", fileOut.c_str());
  return;
  }
  
  // find file extension
  string fileExt;
  auto   pos = fileIn.find_last_of('.');
  
  if (pos != string::npos) {
  fileExt = fileIn.substr(pos);
  }
  
  // is anything to add
  if (userRights.size() == 0) {
  AddLog("ERROR: ", "Please fill email and check rights");
  return;
  }
  
  
  try {
  // create authentication callback
  AuthCallback auth(clientId, redirectUrl);
  
  // process conversion
  PFileConverter::ConvertToPFilePredefinedRights(
    clientEmail,
    inFile,
    fileExt,
    outFile,
    auth,
    this->consent,
    userRights);
  
  AddLog("Successfully converted to ", fileOut.c_str());
  }
  catch (const rmsauth::Exception& e) {
  AddLog("ERROR: ", e.error().c_str());
  
  outFile->close();
  remove(fileOut.c_str());
  }
  catch (const rmscore::exceptions::RMSException& e) {
  AddLog("ERROR: ", e.what());
  
  outFile->close();
  remove(fileOut.c_str());
  }
  inFile->close();
  outFile->close();
  }

Erstellt eine Schutzrichtlinie, die vom Benutzer ausgewählte Rechte erhält. Quelle: RMS _ Sample/pfileconverter. cppCreates a protection policy give user selected rights Source: rms_sample/pfileconverter.cpp

Beschreibung: Hierbei wird eine Richtlinienbeschreibung erstellt und mit den Informationen zu den jeweiligen Benutzerrechten gefüllt. Anschließend wird mit der Richtlinienbeschreibung eine Benutzerrichtlinie erstellt.Description: Create a policy descriptor and fill it with the user's rights information then, use the policy descriptor to create a user policy. Diese Richtlinie dient zum Schutz der ausgewählten Datei. Dabei wird ConvertToPFileUsingPolicy aufgerufen. (Eine Beschreibung hierzu finden Sie weiter oben in diesem Thema.)This policy is used to protect the selected file via a call to ConvertToPFileUsingPolicy (see this described in a previous section of this topic).

C++:C++:

  void PFileConverter::ConvertToPFilePredefinedRights(
  const string            & userId,
  shared_ptr<istream>       inStream,
  const string            & fileExt,
  shared_ptr<iostream>      outStream,
  IAuthenticationCallback & auth,
  IConsentCallback& /*consent*/,
  const vector<UserRights>& userRights)
  {
  auto endValidation = chrono::system_clock::now() + chrono::hours(48);
  
  
  PolicyDescriptor desc(userRights);
  
  desc.Referrer(make_shared<string>("https://client.test.app"));
  desc.ContentValidUntil(endValidation);
  desc.AllowOfflineAccess(false);
  desc.Name("Test Name");
  desc.Description("Test Description");
  
  auto policy = UserPolicy::Create(desc, userId, auth,
                                 USER_AllowAuditedExtraction);
  ConvertToPFileUsingPolicy(policy, inStream, fileExt, outStream);

WorkerThread – eine unterstützende MethodeWorkerThread - a supporting method

Die WorkerThread()-Methode wird in den beiden vorherigen Szenarien Erstellen eines geschützten Dateidatenstroms und Schützt eine Datei auf Grundlage eine Richtlinie auf folgende Weise aufgerufen:The WorkerThread() method is called by two of the previous example scenarios; Create a protected file stream and Protects a file given a policy in the following manner:

C++:C++:

  threadPool.push_back(thread(WorkerThread,
                                static_pointer_cast<iostream>(outStream), pfs,
                                false));

Unterstützende Methode, WorkerThread()Supporting method, WorkerThread()

C++:C++:

  static mutex   threadLocker;
  static int64_t totalSize     = 0;
  static int64_t readPosition  = 0;
  static int64_t writePosition = 0;
  static vector<thread> threadPool;
  
  static void WorkerThread(shared_ptr<iostream>           stdStream,
                       shared_ptr<ProtectedFileStream>pStream,
                       bool                           modeWrite) {
  vector<uint8_t> buffer(4096);
  int64_t bufferSize = static_cast<int64_t>(buffer.size());
  
  while (totalSize - readPosition > 0) {
  // lock
  threadLocker.lock();
  
  // check remain
  if (totalSize - readPosition <= 0) {
    threadLocker.unlock();
    return;
  }
  
  // get read/write offset
  int64_t offsetRead  = readPosition;
  int64_t offsetWrite = writePosition;
  int64_t toProcess   = min(bufferSize, totalSize - readPosition);
  readPosition  += toProcess;
  writePosition += toProcess;
  
  // no need to lock more
  threadLocker.unlock();
  
  if (modeWrite) {
    // stdStream is not thread safe!!!
    try {
      threadLocker.lock();
  
      stdStream->seekg(offsetRead);
      stdStream->read(reinterpret_cast<char *>(&buffer[0]), toProcess);
      threadLocker.unlock();
      auto written =
        pStream->WriteAsync(
          buffer.data(), toProcess, offsetWrite, std::launch::deferred).get();
  
      if (written != toProcess) {
        throw rmscore::exceptions::RMSStreamException("Error while writing data");
      }
    }
    catch (exception& e) {
      qDebug() << "Exception: " << e.what();
    }
  } else {
    auto read =
      pStream->ReadAsync(&buffer[0],
                         toProcess,
                         offsetRead,
                         std::launch::deferred).get();
  
    if (read == 0) {
      break;
    }
  
    try {
      // stdStream is not thread safe!!!
      threadLocker.lock();
  
      // seek to write
      stdStream->seekp(offsetWrite);
      stdStream->write(reinterpret_cast<const char *>(buffer.data()), read);
      threadLocker.unlock();
    }
    catch (exception& e) {
      qDebug() << "Exception: " << e.what();
    }
  }
  }
  }

Szenario: RMS-AuthentifizierungScenario: RMS authentication

Die folgenden Beispiele zeigen zwei verschiedene Authentifizierungsmethoden, bei denen das Azure-Authentifizierungstoken oAuth2 mit und ohne Benutzeroberfläche abgerufen wird.The following examples show two different authentication approaches; obtaining Azure Authentication oAuth2 token using UI and without UI. Abrufen des oAuth2-Authentifizierungs Tokens mit Benutzeroberfläche Quelle: rmsauth _ Sample/MainWindow. cppAcquiring oAuth2 Authentication Token with UI Source: rmsauth_sample/mainwindow.cpp

Schritt 1: Erstellen eines gemeinsamen Punkts des rmsauth:: FileCache -Objekts.Step 1: Create a shared point of rmsauth::FileCache object. Beschreibung: Sie können den Cachepfad festlegen oder die Standardeinstellung verwenden.Description: You can set cache path or use default.

C++:C++:

  auto FileCachePtr = std::make_shared< rmsauth::FileCache>();

Schritt 2: Erstellen des Objekts rmsauth::AuthenticationContext. Beschreibung: Angeben des Azure-Registrierungsstellen-URI und des Objekts FileCache.Step 2: Create rmsauth::AuthenticationContext object Description: Specify Azure authority URI and FileCache object.

C++:C++:

  AuthenticationContext authContext(
                            std::string("https://sts.aadrm.com/_sts/oauth/authorize"),
                            AuthorityValidationType::False,
                            FileCachePtr);

Schritt 3: Aufrufen der acquiretoken -Methode des authcontext -Objekts und angeben der nächsten Parameter: Beschreibung:Step 3: Call acquireToken method of authContext object and specify next parameters: Description:

  • Angeforderte Ressource: die geschützte Ressource, auf die Sie zugreifen möchtenRequested resource - protected resource you want to access
  • Eindeutige Client-ID: normalerweise eine GUIDClient unique ID - usually a GUID
  • Umleitungs-URI: der URI, der nach Abruf des Authentifizierungstokens neu adressiert wirdRedirection URI - the URI which will be readdressed after authentication token fetched
  • Verhalten der Authentifizierungeingabeaufforderung: Wenn Sie PromptBehavior::Auto festlegen, versucht die Bibliothek bei Bedarf, den Cache und das Aktualisierungstoken zu verwenden.Authentication prompt behavior - if you set PromptBehavior::Auto the library tries to use cache and refresh token if necessary
  • Benutzer-ID: der im Eingabeaufforderungsfenster angezeigte BenutzernameUser ID - User name displayed in the prompt window

C++:C++:

  auto result = authContext.acquireToken(
              std::string("api.aadrm.com"),
              std::string("4a63455a-cfa1-4ac6-bd2e-0d046cf1c3f7"),
              std::string("https://client.test.app"),
              PromptBehavior::Auto,
              std::string("john.smith@msopentechtest01.onmicrosoft.com"));

Schritt 4: Abrufen des Zugriffstokens aus den Ergebnissen. Beschreibung: Aufrufen der result-> accessToken()-MethodeStep 4: Get access token from result Description: Call result-> accessToken() method

Hinweis Die Authentifizierungsbibliotheksmethoden können rmsauth::Exception auslösen.Note Any of the authentication library methods may raise rmsauth::Exception

Abrufen des oAuth2-Authentifizierungs Tokens ohne Benutzeroberfläche Quelle: rmsauth _ Sample/MainWindow. cppAcquiring oAuth2 Authentication Token without UI Source: rmsauth_sample/mainwindow.cpp

Schritt 1: Erstellen eines gemeinsamen Punkts des Objekts rmsauth::FileCache. Beschreibung: Sie können den Cachepfad festlegen oder die Standardeinstellung verwendenStep 1: Create a shared point of rmsauth::FileCache object Description: You can set cache path or use default

C++:C++:

  auto FileCachePtr = std::make_shared< rmsauth::FileCache>();

Schritt 2: Erstellen des Objekts UserCredential. Beschreibung: Angeben des Benutzernamens und des KennwortsStep 2:Create UserCredential object Description: Specify user login and password

C++:C++:

  auto userCred = std::make_shared<UserCredential>("john.smith@msopentechtest01.onmicrosoft.com",
                                               "SomePass");

Schritt 3: Erstellen des Objekts rmsauth::AuthenticationContext. Beschreibung: Angeben des Azure-Registrierungsstellen-URI und des Objekts FileCacheStep 3:Create rmsauth::AuthenticationContext object Description: Specify Azure authority URI and FileCache object

C++:C++:

  AuthenticationContext authContext(
                      std::string("https://sts.aadrm.com/_sts/oauth/authorize"),
                      AuthorityValidationType::False,
                      FileCachePtr);

Schritt 4: Aufrufen der acquiretoken -Methode von authcontext und Angeben von Parametern:Step 4: Call the acquireToken method of authContext and specify parameters:

  • Angeforderte Ressource: die geschützte Ressource, auf die Sie zugreifen möchtenRequested resource - protected resource you want to access
  • Eindeutige Client-ID: normalerweise eine GUIDClient unique ID - usually a GUID
  • Benutzeranmeldeinformationen: Übergeben Sie das erstellte Objekt.User credentials - pass the created object

C++:C++:

  auto result = authContext.acquireToken(
              std::string("api.aadrm.com"),
              std::string("4a63455a-cfa1-4ac6-bd2e-0d046cf1c3f7"),
              userCred);

Schritt 5: Abrufen des Zugriffstokens aus den Ergebnissen. Beschreibung: Aufrufen der result-> accessToken()-MethodeStep 5: Get access token from result Description: Call result-> accessToken() method

Hinweis Die Authentifizierungsbibliotheksmethoden können rmsauth::Exception auslösen.Note Any of the authentication library methods may raise rmsauth::Exception