I'm using the following code to get credentials from Google's Authentication server in order to access the Google drive API
public static Google.Apis.Services.BaseClientService.Initializer getCredentials()
{
String serviceAccountEmail = "[email protected]";
var certificate = new X509Certificate2(@"xxx.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { DriveService.Scope.Drive }
}.FromCertificate(certificate));
return new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "AppName",
};
}
then retrieving the Download url from the file metadata and attempting to download that file with the following code:
public static System.IO.Stream DownloadFile(Google.Apis.Drive.v2.Data.File file, Google.Apis.Drive.v2.DriveService service)
{
if (!String.IsNullOrEmpty(file.DownloadUrl))
{
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
new Uri(file.DownloadUrl));
// authenticator.ApplyAuthenticationToRequest(request);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
return response.GetResponseStream();
}
else
{
Console.WriteLine(
"An error occurred: " + response.StatusDescription);
return null;
}
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
return null;
}
}
else
{
// The file doesn't have any content stored on Drive.
return null;
}
}
However I'm receiving a 401 unauthorized response. I'm assuming I need to add an Authorization header in the request along the lines of Authorization: Bearer {ACCESS_TOKEN} but the HttpClientInitializer.Token property is null. Is it possible to authenticate this Request using the ServiceAccountCredential?
I faced the same problem today. Using your approach to make a request no Authentication header is provided. I needed to construct the request a bit differently. Where you have:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(
new Uri(file.DownloadUrl));
You should have:
HttpResponseMessage response = await service.HttpClient.GetAsync(new Uri(file.DownloadUrl));
This ensures that the request is properly authenticated.
Your code is off a little. I don't have a service account Google Drive API example right this minute. This is one for Big Query its almost the same.
String serviceAccountEmail = "539621478854-imkdv94bgujcom228h3ea33kmkoefhil@developer.gserviceaccount.com";
var certificate = new X509Certificate2(@"C:\Users\linda_l\Documents\GitHub\GoogleBigQueryServiceAccount\GoogleBigQueryServiceAccount\key.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { BigqueryService.Scope.DevstorageReadOnly }
}.FromCertificate(certificate));
// Create the service.
var service = new BigqueryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "BigQuery API Sample",
});
Can you see where the BaseClientService.Initializer() is used to create the BigqueryService. I think you need to create a GoogleDriveService. Once you have created the service you should be able to use the service to download the file. You shouldn't need to be doing it though a HTTPRequest.
I will see if i can find a better example tonight using Google Drive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With