मैं एक आंतरिक उपयोग अनुप्रयोग बनाने के साथ शामिल हूं जिसके माध्यम से उपयोगकर्ता Google ड्राइव के भीतर संग्रहीत करने के लिए फ़ाइलों को अपलोड कर सकते हैं। चूंकि यह अनुशंसा की जाती है कि सेवा मालिकों के रूप में सेवा खातों का उपयोग न करें, मैं एक निर्दिष्ट उपयोगकर्ता खाते की ओर से आवेदन अपलोड करना चाहता था, जिस पर कंपनी sysadmin पहुंच है।किसी सेवा खाते में Google ड्राइव पहुंच के प्रतिनिधिमंडल की विफलता
मैंने सेवा खाते के साथ-साथ एप्लिकेशन बनाया है। वहाँ सेवा खाते के लिए बनाई गई दो चाबियाँ, कर रहे हैं के रूप में मैं कोशिश की है दोनों JSON और PKCS12 प्रारूपों इस लक्ष्य को हासिल करने की कोशिश कर:
मैं OAuth 2.0 क्लाइंट आईडी विवरण डाउनलोड किया है, और यह भी .json है सेवा खाते चाबी के लिए और .p12 फ़ाइलें (इसी क्रम में के रूप में ऊपर प्रदर्शित):
मैं था मेरे सिस्टम प्रशासक सेवा खाते में ड्राइव API पहुंच के लिए प्राधिकरण को सौंपने के लिए यहाँ विस्तृत चरणों को देखें: https://developers.google.com/drive/v2/web/delegation#delegate_domain-wide_authority_to_your_service_account
हमने पाया कि चरण 4 में "क्लाइंट नाम" के लिए काम करने वाली एकमात्र चीज वेब एप्लिकेशन (समापन .apps.googleusercontent.com) के लिए सूचीबद्ध "क्लाइंट आईडी" थी। लंबे हेक्साडेसिमल सेवा खाते चाबी के लिए सूचीबद्ध आईडी नहीं थे कि यह क्या आवश्यक (देखें नीचे): उपरोक्त के पहले
, मुझे लगता है कि सीधे सेवा को अपलोड कर सकते हैं कोड है जो एक DriveService उदाहरण बनाने होता था खाते, सेवा खाता चाबी के लिए .json फ़ाइल को संदर्भित:
private DriveService GetServiceA()
{
var settings = SettingsProvider.GetInstance();
string keyFilePath = HostingEnvironment.MapPath("~/App_Data/keyfile.json");
var scopes = new string[] { DriveService.Scope.Drive };
var stream = new IO.FileStream(keyFilePath, IO.FileMode.Open, IO.FileAccess.Read);
var credential = GoogleCredential.FromStream(stream);
credential = credential.CreateScoped(scopes);
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "MyAppName"
});
return service;
}
कि लिस्टिंग और अपलोड करने के लिए काम करता है, निश्चित रूप से फ़ाइलों तक पहुँच के लिए कोई वेब यूआई वहाँ है, और ऐसा लगता है जैसे कि यह संभाल नहीं करता, हालांकि उदाहरण के लिए अनुमति मेटाडेटा या थंबनेल की पीढ़ी जैसी चीजें पीडीएफ़। यही कारण है कि मैं अपलोड के लिए एक मानक खाते का उपयोग करने की कोशिश कर रहा हूं।
एक बार जब प्रतिनिधिमंडल स्पष्ट रूप से क्रमबद्ध किया गया था, तो मैंने ऊपर दिए गए प्रतिनिधिमंडल संदर्भ में दिखाए गए कोड को अनुकूलित करने का प्रयास किया, जो .json कुंजी फ़ाइल से आवश्यक विवरण निकालने के लिए कहीं और से कोड के संयोजन के साथ संयोजन किया गया।
अपवाद विवरण::
FileList fileList = service.FileList().Execute();
मैं एक त्रुटि प्राप्त: इस कोड के साथ, जैसे ही मैं किसी भी एपीआई आदेश, यहां तक कि के रूप में सरल निष्पादित करने के लिए के रूप में की कोशिश के रूप में Google.Apis.Auth.OAuth2.Responses.TokenResponseException : त्रुटि: "unauthorized_client", विवरण: "अनधिकृत ग्राहक या अनुरोध में गुंजाइश है।", उरी: ""
कि प्रयास के लिए कोड है:
private DriveService GetServiceB()
{
var settings = SettingsProvider.GetInstance();
string keyFilePath = HostingEnvironment.MapPath("~/App_Data/keyfile.json");
string serviceAccountEmail = "<account-email>@<project-id>.iam.gserviceaccount.com";
var scopes = new string[] { DriveService.Scope.Drive };
var stream = new IO.FileStream(keyFilePath, IO.FileMode.Open, IO.FileAccess.Read);
var reader = new IO.StreamReader(stream);
string jsonCreds = reader.ReadToEnd();
var o = JObject.Parse(jsonCreds);
string privateKey = o["private_key"].ToString();
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = scopes,
User = "[email protected]"
}
.FromPrivateKey(privateKey)
);
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "MyAppName"
});
return service;
}
अंत में, मैं दूसरे से बनाया एक बचाने के लिए rvice खाता कुंजी।आदेश और अधिक बारीकी से अधिकार प्रतिनिधिमंडल दस्तावेज में कोड से मिलान करने में p12 फ़ाइल है, लेकिन जो एक ही अपवाद में परिणाम:
private DriveService GetServiceC()
{
var settings = SettingsProvider.GetInstance();
string p12KeyFilePath = HostingEnvironment.MapPath("~/App_Data/keyfile.p12");
string serviceAccountEmail = "<account-email>@<project-id>.iam.gserviceaccount.com";
var scopes = new string[] { DriveService.Scope.Drive }; // Full access
X509Certificate2 certificate = new X509Certificate2(
p12KeyFilePath,
"notasecret",
X509KeyStorageFlags.Exportable
);
var credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = scopes,
User = "[email protected]"
}
.FromCertificate(certificate)
);
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "MyAppName"
});
return service;
}
minimial प्रासंगिक वर्ग जहां इस पद्धति रहती है:
public class GoogleDrive
{
public DriveService Service { get; private set; }
public GoogleDrive()
{
this.Service = this.GetService();
}
private DriveService GetService()
{
// Code from either A, B or C
}
public FilesResource.ListRequest FileList()
{
return this.Service.Files.List();
}
}
और वह है इस फैशन में प्रयोग किया जाता है:
var service = new GoogleDrive();
FilesResource.ListRequest listRequest = service.FileList();
FileList fileList = listRequest.Execute();
उस अंतिम पंक्ति पर अपवाद होता है।
मुझे समझ में नहीं आता कि मेरा सेवा खाता नामित उपयोगकर्ता की तरफ से क्यों कार्य नहीं कर सकता है, जो उस डोमेन का हिस्सा है जिसके लिए आवेदन के सेवा खाते को प्राधिकृत प्राधिकारी होना चाहिए। यह क्या है कि मैंने यहां गलत समझा है?
var credential = new ServiceAccountCredential...
होना चाहिए
ServiceAccountCredential credential = new ServiceAccountCredential...
बी की जांच:
यह कॉन्फ़िगरेशन त्रुटि का विषय हो सकता है। क्या आपने क्लाइंट नाम में सेवा खाता क्लाइंट आईडी दर्ज की है? यह [आपके सेवा खाते में प्रतिनिधि डोमेन-व्यापी प्राधिकरण] में चरण # 5 है (https://developers.google.com/drive/v2/web/delegation#delegate_domain-wide_authority_to_your_service_account) – noogui
@noogui द जेसन फ़ाइल जेनरेट की गई सेवा खाता कुंजी में "client_id" प्रविष्टि होती है, जो 21 अंकों का दशमलव संख्या है। चरण # 5 के लिए इसका उपयोग एक त्रुटि संदेश दिखाता है: "यह क्लाइंट नाम अभी तक Google के साथ पंजीकृत नहीं है।" –