0

I am trying to work with Google drive from Windows application or service.

I don't need Web App, MVC, so on.

System must work automatically, without any user intrusion, so I created service account and get certificate and email.

And, of course, downloaded last client library - http://code.google.com/p/google-api-dotnet-client/

I build the service object as in documentation:

        private const string SERVICE_ACCOUNT_EMAIL = "xxx@developer.gserviceaccount.com";
    private const string SERVICE_ACCOUNT_PKCS12_FILE_PATH = @"xxx-privatekey.p12";

    /// <summary>
    /// Build a Drive service object authorized with the service account.
    /// </summary>
    /// <returns>Drive service object.</returns>
    static DriveService BuildService ( )
    {
        X509Certificate2 certificate = new X509Certificate2 ( SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret",
            X509KeyStorageFlags.Exportable );

        var provider = new AssertionFlowClient ( GoogleAuthenticationServer.Description, certificate )
        {
            ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
            Scope = DriveService.Scopes.Drive.GetStringValue ( ),
            ServiceAccountUser = "myemail@gmail.com",
        };
        var auth = new OAuth2Authenticator<AssertionFlowClient> ( provider, AssertionFlowClient.GetState );
        return new DriveService ( auth );
    } // BuildService

and then I do this:

service = BuildService ( );
FilesResource.InsertMediaUpload request = service.Files.Insert ( body, stream, mimeType );
request.Upload ( );
File file = request.ResponseBody;

I got the exception in Upload method - Unknown object identifier (OID). I found the command, which throws this exception:

String signature = UnpaddedUrlSafeBase64Encode ( Key.SignData ( Encoding.ASCII.GetBytes ( assertion.ToString ( ) ), "SHA256" ) );

This in an Google.Apis.Authentication.OAuth2.dll, file AssertionflowClient.cs, method GenerateMessage.

But Google certificate has only SHA1 algorithm. This is evident from the certificate info window: X509Certificate2UI.DisplayCertificate ( certificate ); or from windows.

I tried use SHA1: String signature = UnpaddedUrlSafeBase64Encode ( Key.SignData ( Encoding.ASCII.GetBytes ( assertion.ToString ( ) ), "SHA1" ) );

After that this exception disappeared, but I got HTTP Error 400 (Invalid request). How I can to work with Google drive with service account?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Pavel
  • 1
  • 1

2 Answers2

1

In Your code remove

ServiceAccountUser = "myemail@gmail.com",

or Go to admin console of the google apps domain and authorize your service account.

Then it works.

Srikanth P Vasist
  • 1,327
  • 2
  • 14
  • 26
  • In my case when I try to fetch file using BuildService() it's return no data.Can you please help me in that. – amit ghosh Jul 21 '13 at 18:17
  • Are those files shared to the service account? This service account mechanism is mainly for google enterprise apps. If you are using these APIs on your personal Drive, you might have to share those files to service account explicitly. – Srikanth P Vasist Aug 13 '13 at 09:48
0

Did you follow the instructions in OAuth2 service account page and generate a new key?

Can you try other service requests, lets say Insert request without media upload (InsertRequest Insert(Google.Apis.Drive.v1.Data.File body) - and let me know if other methods didn't work for you as well.

And notice that in the service account documentation it says: "Service Accounts rely on the RSA SHA256 algorithm and the JWT token format". That's the supported algorithm, and not SHA1.

peleyal
  • 3,472
  • 1
  • 14
  • 25
  • In my case when I try to fetch file using BuildService() it's return no data.Can you please help me in that. – amit ghosh Jul 21 '13 at 18:17