Linux kodu örnekleri
Önemli
Mart 2020'den önce yayımlanan Microsoft Rights Management Service SDK sürümleri kullanım dışı bırakılmıştır; önceki sürümleri kullanan uygulamaların Mart 2020 sürümünü kullanacak şekilde güncelleştirilmiş olması gerekir. Tüm ayrıntılar için kullanımdan kaldırma bildirimine bakın.
Microsoft Rights Management Service SDK'sı için başka geliştirme planlanmıyor. Sınıflandırma, etiketleme ve koruma hizmetleri için Microsoft Bilgi Koruması SDK'sının benimsenmesini kesinlikle öneririz.
Bu konuda, RMS SDK’in Linux sürümü için önemli senaryolar ve kod öğeleri sunulacaktır.
Aşağıdaki kod parçacıkları rms_sample vermsauth_sample örnek uygulamalardan alınıyor. Daha fazla bilgi için, GitHub deposunda örneklere bakın.
Senaryo: Korumalı bir dosyada koruma ilkesi bilgilerine erişim
RMS korumalı dosyayı açar veokurKaynak: rms_sample/mainwindow.cpp
Açıklama: Kullanıcıdan dosya adını aldıktan sonra, sertifikaları okuma (bkz. MainWindow::addCertificates), İstemci kimliği ve Yönlendirme URL’siyle yetki geri çağırmayı ayarlama, ConvertFromPFile çağırma (aşağıdaki kod örneğine bakın), sonra koruma ilke adını, açıklamayı ve içerik geçerlilik tarihini okuma.
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();
}
Korumalı dosya oluşturmastreamSource: rms_sample/pfileconverter.cpp
Açıklama: Bu yöntem, sdk yöntemi aracılığıyla geçirilen yedekleme akışından korumalı bir dosya akışı oluşturur, ProtectedFileStream::Acquire, daha sonra çağırana döndürülür.
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;
}
Senaryo: Bir şablon kullanarak yeni bir korumalı dosya oluşturma
Kullanıcının seçtiği şablonla bir dosyayıkorurKaynak: rms_sample/mainwindow.cpp
Açıklama: Kullanıcıdan dosya adını aldıktan sonra, sertifikaları okuma (bkz. MainWindow::addCertificates), ve İstemci kimliği ve Yönlendirme URL’siyle yetki geri çağırmayı ayarlama, seçilen dosya ConvertToPFileTemplates çağrılarak korunur (aşağıdaki kod örneğine bakın).
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();
}
Şablondan oluşturulan bir ilkeyi kullanarak dosyayıkorurKaynak: rms_sample/pfileconverter.cpp
Açıklama: Kullanıcıyla ilişkili şablonların listesi getirilir ve daha sonra seçilen şablon dosyayı korumak için kullanılan bir ilke oluşturmak için kullanılır.
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);
}
}
İlke verilen bir dosyayıkorurKaynak: rms_sample/pfileconverter.cpp
Açıklama: Verilen ilkeyi kullanan bir korunan dosya akışı oluşturun, sonra bu dosyayı koruyun.
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();
}
Senaryo: Özel koruma kullanarak bir dosyayı koruma
Özel koruma kullanarak dosyayıkorurKaynak: rms_sample/mainwindow.cpp
Açıklama: Kullanıcıdan dosya adını aldıktan sonra, sertifikaları okuma (bkz. MainWindow::addCertificates), kullanıcıdan hak bilgilerini toplama ve İstemci kimliği ve Yönlendirme URL’siyle yetki geri çağırmayı ayarlama, seçilen dosya ConvertToPFilePredefinedRights çağrılarak yansıtılır(aşağıdaki kod örneğine bakın).
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();
}
Kullanıcıya seçili hakları veren bir koruma ilkesioluştururKaynak: rms_sample/pfileconverter.cpp
Açıklama: İlke tanımlayıcısı oluşturun ve bunu kullanıcının hak bilgileriyle doldurun, sonra kullanıcı ilkesi oluşturmak için ilke tanımlayıcısı kullanın. Bu ilke seçilen dosyayı bir ConvertToPFileUsingPolicy çağrısıyla korumak için kullanılır (Bu, bu konunun önceki bölümünde açıklanmıştır).
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 - destekleyen bir yöntem
WorkerThread() yöntemi önceki iki örnek senaryo tarafından çağrılır; aşağıdaki şekilde Korumalı dosya akışı oluşturma ve İlke verilen bir dosyayı korur:
C++:
threadPool.push_back(thread(WorkerThread,
static_pointer_cast<iostream>(outStream), pfs,
false));
Destekleyen yöntem, WorkerThread()
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();
}
}
}
}
Senaryo: RMS kimlik doğrulama
Aşağıdaki örnekler, iki farklı kimlik doğrulama yaklaşımını gösterir; Kullanıcı Arabirimi kullanarak ve Kullanıcı Arabirimi olmadan Azure kimlik doğrulama oAuth2 belirteci alma UISource ile oAuth2 Kimlik Doğrulama Belirteci Alma: rmsauth_sample/mainwindow.cpp
1. Adım: rmsauth::FileCache nesnesinin paylaşılan noktasını oluşturun. Açıklama: Önbellek yolunu ayarlayabilir veya varsayılanı kullanabilirsiniz.
C++:
auto FileCachePtr = std::make_shared< rmsauth::FileCache>();
2. adım: rmsauth::AuthenticationContext nesnesi oluşturun Açıklama: Azure yetki URI’si ve FileCache nesnesi belirtin.
C++:
AuthenticationContext authContext(
std::string("https://sts.aadrm.com/_sts/oauth/authorize"),
AuthorityValidationType::False,
FileCachePtr);
3. Adım: authContext nesnesinin acquireToken yöntemini çağırın ve sonraki parametreleri belirtin: Açıklama:
- İstenen kaynak -erişmek istediğiniz korumalı kaynak
- Benzersiz istemci kimliği -genellikle bir GUID
- Yeniden yönlendirme URI'si -kimlik doğrulama belirteci getirildikten sonra yeniden başvurulacak URI
- Kimlik doğrulama istemi davranışı - PromptBehavior::Auto olarak ayarlarsanız, kitaplık önbelleği kullanmaya ve gerekirse belirteci yenilemeye çalışır
- Kullanıcı Kimliği - komut istemi penceresinde görüntülenen kullanıcı adı
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"));
4. adım: Sonuçtan erişim belirteci alın Açıklama: result-> accessToken() yöntemini çağırın
Not Kimlik doğrulama kitaplığı yöntemlerinden herhangi biri rmsauth::Exception'a neden olabilir
UISource olmadan oAuth2 Kimlik Doğrulama Belirteci Alma: rmsauth_sample/mainwindow.cpp
1. adım: rmsauth::FileCache nesnesine ait bir paylaşılan nokta oluşturun Açıklama: Önbellek yolunu ayarlayabilir veya varsayılanı kullanabilirsiniz
C++:
auto FileCachePtr = std::make_shared< rmsauth::FileCache>();
2. adım: UserCredential nesnesi oluşturun Açıklama: kullanıcı oturum açma bilgileri ve parola belirtin
C++:
auto userCred = std::make_shared<UserCredential>("john.smith@msopentechtest01.onmicrosoft.com",
"SomePass");
3. adım: rmsauth::AuthenticationContext nesnesi oluşturun Açıklama: Azure yetki URI’si ve FileCache nesnesi belirtin
C++:
AuthenticationContext authContext(
std::string("https://sts.aadrm.com/_sts/oauth/authorize"),
AuthorityValidationType::False,
FileCachePtr);
4. Adım: authContext'inacquireToken yöntemini çağırın ve parametreleri belirtin:
- İstenen kaynak -erişmek istediğiniz korumalı kaynak
- Benzersiz istemci kimliği -genellikle bir GUID
- Kullanıcı kimlik bilgileri -oluşturulan nesneyi geçirin
C++:
auto result = authContext.acquireToken(
std::string("api.aadrm.com"),
std::string("4a63455a-cfa1-4ac6-bd2e-0d046cf1c3f7"),
userCred);
5. adım: Sonuçtan erişim belirteci alın Açıklama: result-> accessToken() yöntemini çağırın
Not Kimlik doğrulama kitaplığı yöntemlerinden herhangi biri rmsauth::Exception'a neden olabilir