Get Token from Client Email and Private Key (Service Account) in Google

google service account json key
how to get access token google api
google service account authentication
google cloud console
google developer console
google oauth2
google_application_credentials json example
google console

I have spent many hours trying to get a auth token.

I need to show to my users some Analytics information collected (I'm the owner of Analytics). I have created a Service Account, and I have tested all with this example, and all works fine (using the Nuget Package, of course).

Examples: Link

Code Example Working:

string[] scopes = new string[] {AnalyticsService.Scope.Analytics}; // view and manage your Google Analytics data

var keyFilePath = @"c:\file.p12" ;    // Downloaded from https://console.developers.google.com
var serviceAccountEmail = "xx@developer.gserviceaccount.com";  // found https://console.developers.google.com

//loading the Key file
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential( new ServiceAccountCredential.Initializer(serviceAccountEmail) {
                                                   Scopes = scopes}.FromCertificate(certificate));

I have used Fiddler, and I can see how the token is "flying" between Google and my App, but I don't have any options to take it.

I need to do, something like this code on Python, but in C# to use Embed API

# service-account.py

import json
from oauth2client.client import SignedJwtAssertionCredentials

# The scope for the OAuth2 request.
SCOPE = 'https://www.googleapis.com/auth/analytics.readonly'

# The location of the key file with the key data.
KEY_FILEPATH = 'path/to/json-key.json'

# Load the key file's private data.
with open(KEY_FILEPATH) as key_file:
  _key_data = json.load(key_file)

# Construct a credentials objects from the key data and OAuth2 scope.
_credentials = SignedJwtAssertionCredentials(
    _key_data['client_email'], _key_data['private_key'], SCOPE)

# Defines a method to get an access token from the credentials object.
# The access token is automatically refreshed if it has expired.
def get_access_token():
  return _credentials.get_access_token().access_token

If you read documentation about Embed Api, you see that you need the token...

 /**
   * Authorize the user with an access token obtained server side.
   */
  gapi.analytics.auth.authorize({
    'serverAuth': {
      'access_token': '{{ ACCESS_TOKEN_FROM_SERVICE_ACCOUNT }}'
    }
  });

With all this information... How can I onbtain the service token??? Thanks!!

This works for me

c# code:

   public string bearer;
   GoogleCredential credential;

        string fichero = Server.MapPath("") + "//file.json";
        using (Stream stream = new FileStream(fichero, FileMode.Open,   FileAccess.Read, FileShare.Read))
        {
            credential = GoogleCredential.FromStream(stream);
        }
        credential = credential.CreateScoped(new[] { 
       "https://www.googleapis.com/auth/analytics.readonly" });


        try
        {
            Task<string> task = ((ITokenAccess)credential).GetAccessTokenForRequestAsync();
            task.Wait();
            bearer = task.Result;

        }
        catch (AggregateException ex)
        {
            throw ex.InnerException;
        }

Javascript code:

gapi.analytics.auth.authorize({
    'serverAuth': {
        'access_token': '<%=bearer%>'
    }
});

Using OAuth 2.0 to Access Google APIs, Then your client application requests an access token from the Google Before your application can access private data using a Google API, it must Your application calls Google APIs on behalf of the service account, and email address that is unique, a client ID, and at least one public/private key pair. In a Service to Service authentication model, the application directly talks to the Google API, using a service account, by using a JSON Web Token. This is the simplest method, especially if you’re building a prototype or an application that talks from your server (like a Node.js app) to the Google APIs.

just to add to https://stackoverflow.com/a/38218844/5334191, same in .netcore:

    public async Task<string> Token(Microsoft.AspNetCore.Hosting.IWebHostEnvironment webenv)
    {
            var root = webenv.ContentRootPath;
            var file = System.IO.Path.Combine(root, "googleanalytics.json");
            Google.Apis.Auth.OAuth2.GoogleCredential credential = GoogleCredential.FromFile(file);
            credential = credential.CreateScoped(new[] {"https://www.googleapis.com/auth/analytics.readonly" });
            var result = await ((ITokenAccess)credential).GetAccessTokenForRequestAsync();
            return result;
    }

Creating and managing service account keys, While client applications can provide users with a web sign-in prompt to submit their Creates a JWT and signs it with the service account's private key. private key file and to assign the service account the Service Account Token Creator role. Subject and email should match the service account's email Note: Ensure you have set the GOOGLE_APPLICATION_CREDENTIALS environment variable to your service account private key file path. Save the request body in a file called request.json, and execute the

So you're all good in creating your ServiceAccountCredential. What you need to do next is call RequestAccessTokenAsync() on your ServiceAccountCredential instance after which that instance will have it's Token property populated with the access token e.g.

if (await credential.RequestAccessTokenAsync(new CancellationToken())) {
    var token = credential.Token.AccessToken;
}

You can then use that token in your javascript.

Authentication between services, This works for me. c# code: public string bearer; GoogleCredential credential; string fichero = Server.MapPath("") + "//file.json"; using (Stream� open_id_connect_token = id_token.fetch_id_token(Request(), client_id) # Fetch the Identity-Aware Proxy-protected URL, including an # Authorization header containing "Bearer " followed by a #

Get Token from Client Email and Private Key (Service Account) in , Generate a new private key. A Service Account is automatically� Authenticating with a service account key file Manually create and obtain service account credentials to use BigQuery when an application is deployed on premises or to other public clouds. You can set the environment variable to load the credentials using Application Default Credentials , or you can specify the path to load the credentials

Authenticate with a Service Account, You generate these tokens on your server, pass them back to a client device, and then use Also note that the private key in a service account JSON file is sensitive Service account IDs are email addresses that have the following format:� Click Create credentials > Service account key. Choose whether to download the service account's public/private key as a standard P12 file, or as a JSON file that can be loaded by a Google API

Create Custom Tokens - Firebase, The access tokens can be generated using a service account with Clicking the Generate New Private Key button at the bottom of the Service Accounts section of the Once you have a service account key file, you can use one of the Google API client "https://www.googleapis.com/auth/userinfo.email", Second, the user may get artifacts signed by the Google-managed private key of the service account using the iam.serviceAccounts.signBlob permission and by calling either the signBlob() or signJwt() method. The Google-managed private key is always held in escrow and is never directly exposed.

Comments
  • Thanks! I have been looking for something like this for 2 hours.
  • This worked for me also. Allowed me to go from a Service Account credential to an access token that worked in Postman,