Linux-kodexempelLinux code examples

Viktigt

Versioner av Microsoft Rights Management Service SDK som lanserades före mars 2020 är inaktuella. program som använder tidigare versioner måste uppdateras för att använda versionen från mars 2020.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. Fullständig information finns i utfasnings meddelandet.For full details, see the deprecation notice.

Inga ytterligare förbättringar planeras för Microsoft Rights Management Service SDK.No further enhancements are planned for the Microsoft Rights Management Service SDK. Vi rekommenderar starkt att du använder Microsoft Information Protection SDK för klassificering, märkning och skydds tjänster.We strongly recommend adoption of the Microsoft Information Protection SDK for classification, labeling, and protection services.

I det här avsnittet presenteras viktiga scenarier och kodelement för Linux-versionen av RMS SDK.This topic introduces you to important scenarios and code elements for the Linux version of the RMS SDK.

Kodavsnitten nedan är från exempelprogrammen rms_sample och rmsauth_sample.The code snippets below are from the sample applications, rms_sample and rmsauth_sample. Mer information finns i samples i GitHub-lagret.For more information, see samples at the GitHub repository.

Scenario: Komma åt skyddsprincipinformation från en skyddad filScenario: Access protection policy information from a protected file

Öppnar och läser en RMS-skyddad fil Källa: RMS _ Sample/mainwindow. cppOpens and reads an RMS protected file Source: rms_sample/mainwindow.cpp

Beskrivning: När ett filnamn hämtas från användaren, läs certifikaten (se MainWindow::addCertificates), ställ in auktoriseringsåteranrop med klient-ID och omdirigerings-URL, anropa ConvertFromPFile (se följande kodexempel) och läs sedan ut skyddsprincipnamnet, beskrivningen och innehållets giltighetsdatum.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();
  }

Skapa en skyddad fil ström Källa: RMS _ Sample/pfileconverter. cppCreate a protected file stream Source: rms_sample/pfileconverter.cpp

Beskrivning: den här metoden skapar en skyddad fil ström från den överförda data strömmen via SDK-metoden ProtectedFileStream:: Acquiresom sedan returneras till anroparen.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;
  }

Scenario: Skapa en ny skyddad fil med en mallScenario: Create a new protected file using a template

Skyddar en fil med en användardefinierad mall Källa: RMS _ Sample/mainwindow. cppProtects a file with a user selected template Source: rms_sample/mainwindow.cpp

Beskrivning: När ett filnamn hämtas från användaren, läs certifikaten (se MainWindow::addCertificates) och ställ in auktoriseringsåteranrop med klient-ID och omdirigerings-URL. Den valda filen skyddas genom att anropa ConvertToPFileTemplates (se följande kodexempel).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();
  }

Skyddar en fil med en princip som skapats från en mall Källa: RMS _ Sample/pfileconverter. cppProtects a file using a policy created from a template Source: rms_sample/pfileconverter.cpp

Beskrivning: En lista över mallar som är associerade med användaren hämtas och den valda mallen används sedan för att skapa en princip som i sin tur används för att skydda filen.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);
  }
  }

Skyddar en fil med en princip Källa: RMS _ Sample/pfileconverter. cppProtects a file given a policy Source: rms_sample/pfileconverter.cpp

Beskrivning: Skapa en skyddad filström med hjälp av den angivna principen och sedan skydda filen.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();
  }

Scenario: Skydda en fil med anpassat skyddScenario: Protect a file using custom protection

Skyddar en fil med anpassat skydd Källa: RMS _ Sample/mainwindow. cppProtects a file using custom protection Source: rms_sample/mainwindow.cpp

Beskrivning: När ett filnamn hämtas från användaren, läs certifikaten (se MainWindow::addCertificates) och ställ in auktoriseringsåteranrop med klient-ID och omdirigerings-URL. Den valda filen projiceras genom att anropa ConvertToPFilePredefinedRights (se följande kodexempel).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();
  }

Skapar en skydds princip ge användare valda rättigheter Källa: RMS _ Sample/pfileconverter. cppCreates a protection policy give user selected rights Source: rms_sample/pfileconverter.cpp

Beskrivning: Skapa en principbeskrivning, fyll den med användarens rättighetsinformation och använd sedan principbeskrivningen till att skapa en användarprincip.Description: Create a policy descriptor and fill it with the user's rights information then, use the policy descriptor to create a user policy. Den här principen används för att skydda den valda filen via ett anrop till ConvertToPFileUsingPolicy (se beskrivningen av det här tidigare i det här avsnittet).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 - en stödmetodWorkerThread - a supporting method

WorkerThread()-metoden anropas av två tidigare exempelscenarier, Skapa en skyddad filström och Skyddar en fil med en angiven princip på följande sätt: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));

Stödmetod, 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();
    }
  }
  }
  }

Scenario: RMS-autentiseringScenario: RMS authentication

I följande exempel visas två olika autentiseringsmetoder: erhålla oAuth2-token för Azure-autentisering med och utan användargränssnitt.The following examples show two different authentication approaches; obtaining Azure Authentication oAuth2 token using UI and without UI. Hämtar oAuth2-autentiseringstoken med användar gränssnitt Källa: ett rmsauth _ Sample/mainwindow. cppAcquiring oAuth2 Authentication Token with UI Source: rmsauth_sample/mainwindow.cpp

Steg 1: skapa en delad punkt med ett rmsauth:: filecache -objektet.Step 1: Create a shared point of rmsauth::FileCache object. Beskrivning: Du kan ange cachesökvägen eller använda standardsökvägen.Description: You can set cache path or use default.

C++:C++:

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

Steg 2: Skapa objektet rmsauth::AuthenticationContext Beskrivning: Ange utfärdar-URI för Azure och FileCache-objekt.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);

Steg 3: anropa acquireToken -metoden för authContext -objektet och ange nästa parametrar: Beskrivning:Step 3: Call acquireToken method of authContext object and specify next parameters: Description:

  • Begärd resurs - en skyddad resurs som du vill komma åtRequested resource - protected resource you want to access
  • Unikt klient-ID - vanligtvis ett GUIDClient unique ID - usually a GUID
  • Omdirigerings-URI - Den URI som ska omadresseras efter att autentiseringstoken hämtasRedirection URI - the URI which will be readdressed after authentication token fetched
  • Funktionalitet för autentiseringsuppmaning - Om du ställer in PromptBehavior::Auto försöker biblioteket använda cache och uppdatera token om det behövsAuthentication prompt behavior - if you set PromptBehavior::Auto the library tries to use cache and refresh token if necessary
  • Användar-ID - Användarnamnet visas i uppmaningsfönstretUser 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"));

Steg 4: Hämta åtkomsttoken från resultat Beskrivning: anropa result-> accessToken ()- metodenStep 4: Get access token from result Description: Call result-> accessToken() method

Obs! Alla metoder i autentiseringsbiblioteket kan kasta ett rmsauth::ExceptionNote Any of the authentication library methods may raise rmsauth::Exception

Hämtar oAuth2-autentiseringstoken utan användar gränssnitt Källa: ett rmsauth _ Sample/mainwindow. cppAcquiring oAuth2 Authentication Token without UI Source: rmsauth_sample/mainwindow.cpp

Steg 1: Skapa en delad punkt av ett rmsauth::FileCache-objekt Beskrivning: Du kan ange cachesökvägen eller använda standardsökvägenStep 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>();

Steg 2: Skapa ett UserCredential-objekt Beskrivning: Ange användarinloggning och lösenordStep 2:Create UserCredential object Description: Specify user login and password

C++:C++:

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

Steg 3: Skapa objektet rmsauth::AuthenticationContext Beskrivning: Ange utfärdar-URI för Azure och FileCache-objektStep 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);

Steg 4: anropa acquireToken -metoden för authContext och ange parametrar:Step 4: Call the acquireToken method of authContext and specify parameters:

  • Begärd resurs - en skyddad resurs som du vill komma åtRequested resource - protected resource you want to access
  • Unikt klient-ID - vanligtvis ett GUIDClient unique ID - usually a GUID
  • Användarens autentiseringsuppgifter - Överför det skapade objektetUser credentials - pass the created object

C++:C++:

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

Steg 5: Hämta åtkomsttoken från resultat Beskrivning: anropa result-> accessToken ()- metodenStep 5: Get access token from result Description: Call result-> accessToken() method

Obs! Alla metoder i autentiseringsbiblioteket kan kasta ett rmsauth::ExceptionNote Any of the authentication library methods may raise rmsauth::Exception