Generate Access Token For Google Service Account Form JSON Or P12 Key In C#

Service Accounts are used for Server to Server communication so the user doesn't need to interact for authentication.
 
Section 1 Generate Keys for Google Service Account
 
If you haven’t generated keys yet, follow the steps to generate one or skip to the next section.
 
Go to https://console.developers.google.com/permissions/serviceaccounts
 
Select project for which you want the service account.

 
Create a new service account here. You can add roles and permissions as per your use cases.

 
 
Now, besides your account name, click Options >> Create Key. 

 
 
Select your desired format and hit "Create".
 
 
I have generated both the keys for demo.

 
 
Section 2 Generate Access Tokens
 
Now, let's retrieve Acess Token from the above-generated keys. I have taken Console Application here. Install Google.Apis.Auth NuGet package. It will add all the required dependencies.

 
Add key files to your project and set "Copy to Output Directory" as "Copy Always" or "Copy if newer".

 
 
Generate token from JSON key

Write the below code where jsonKeyFilePath is the path to your JSON key file, and scopes takes all the scopes you required in your access token.
  1. /// <summary>  
  2. /// Get Access Token From JSON Key Async  
  3. /// </summary>  
  4. /// <param name="jsonKeyFilePath">Path to your JSON Key file</param>  
  5. /// <param name="scopes">Scopes required in access token</param>  
  6. /// <returns>Access token as string Task</returns>  
  7. public static async Task<string> GetAccessTokenFromJSONKeyAsync(string jsonKeyFilePath, params string[] scopes)  
  8. {  
  9.     using (var stream = new FileStream(jsonKeyFilePath, FileMode.Open, FileAccess.Read))  
  10.     {  
  11.         return await GoogleCredential  
  12.             .FromStream(stream) // Loads key file  
  13.             .CreateScoped(scopes) // Gathers scopes requested  
  14.             .UnderlyingCredential // Gets the credentials  
  15.             .GetAccessTokenForRequestAsync(); // Gets the Access Token  
  16.     }  
  17. }  
Above is an Asynchronous implementation which can be optionally wrapped as Synchronous like given below.
  1. /// <summary>  
  2. /// Get Access Token From JSON Key  
  3. /// </summary>  
  4. /// <param name="jsonKeyFilePath">Path to your JSON Key file</param>  
  5. /// <param name="scopes">Scopes required in access token</param>  
  6. /// <returns>Access token as string</returns>  
  7. public static string GetAccessTokenFromJSONKey(string jsonKeyFilePath, params string[] scopes)  
  8. {  
  9.     return GetAccessTokenFromJSONKeyAsync(jsonKeyFilePath, scopes).Result;  
  10. }  
Let’s test it for my Google project. I have enabled Google Plus API, so I am requesting the given user’s profile here.
  1. class TestJSONKey  
  2. {  
  3.     public static void GetTokenAndCall()  
  4.     {  
  5.         var token = GoogleServiceAccount.GetAccessTokenFromJSONKey(  
  6.          "Keys/C-SharpCorner-0338f58d564f.json",  
  7.          "https://www.googleapis.com/auth/userinfo.profile");  
  8.   
  9.         WriteLine(new HttpClient().GetStringAsync($"https://www.googleapis.com/plus/v1/people/110259743757395873050?access_token={token}").Result);  
  10.     }  
  11. }  
 And, call API.
  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         // Testing with JSON key  
  6.         TestJSONKey.GetTokenAndCall();  
  7.     }  
  8. }  
You will get response like this.

 

Generate token from P12 key
 
Write the below code where p12KeyFilePath is the path to your JSON key file. You can get serviceAccountEmail from Google Developer Console. The keyPassword will be asked while generating key. By default, it is "notasecret" and scopes takes all the scopes you require in your access token.
  1. /// <summary>  
  2. /// Get Access Token From P12 Key Async  
  3. /// </summary>  
  4. /// <param name="p12KeyFilePath">Path to your P12 Key file</param>  
  5. /// <param name="serviceAccountEmail">Service Account Email</param>  
  6. /// <param name="keyPassword">Key Password</param>  
  7. /// <param name="scopes">Scopes required in access token</param>  
  8. /// <returns>Access token as string Task</returns>  
  9. public static async Task<string> GetAccessTokenFromP12KeyAsync(string p12KeyFilePath, string serviceAccountEmail, string keyPassword = "notasecret"params string[] scopes)  
  10. {  
  11.     return await new ServiceAccountCredential(  
  12.         new ServiceAccountCredential.Initializer(serviceAccountEmail)  
  13.         {  
  14.             Scopes = scopes  
  15.         }.FromCertificate(  
  16.             new X509Certificate2(  
  17.                 p12KeyFilePath,  
  18.                 keyPassword,  
  19.                 X509KeyStorageFlags.Exportable))).GetAccessTokenForRequestAsync();  
  20. }  
Above is an Asynchronous implementation which can be optionally wrapped as Synchronous like given below.
  1. /// <summary>  
  2. /// Get Access Token From P12 Key  
  3. /// </summary>  
  4. /// <param name="p12KeyFilePath">Path to your P12 Key file</param>  
  5. /// <param name="serviceAccountEmail">Service Account Email</param>  
  6. /// <param name="keyPassword">Key Password</param>  
  7. /// <param name="scopes">Scopes required in access token</param>  
  8. /// <returns>Access token as string</returns>  
  9. public static string GetAccessTokenFromP12Key(string p12KeyFilePath, string serviceAccountEmail, string keyPassword, params string[] scopes)  
  10. {  
  11.     return GetAccessTokenFromP12KeyAsync(p12KeyFilePath, serviceAccountEmail, keyPassword, scopes).Result;  
  12. }  
 Let’s test it.
  1. class TestP12Key  
  2. {  
  3.     public static void GetTokenAndCall()  
  4.     {  
  5.         var token = GoogleServiceAccount.GetAccessTokenFromP12Key(  
  6.             "Keys/C-SharpCorner-e0883ada1a3f.p12",  
  7.             "[email protected]",  
  8.             "notasecret",  
  9.             "https://www.googleapis.com/auth/userinfo.profile"  
  10.             );  
  11.   
  12.         WriteLine(new HttpClient().GetStringAsync($"https://www.googleapis.com/plus/v1/people/110259743757395873050?access_token={token}").Result);  
  13.     }  
  14. }  
 And, call API.
  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         // Testing with JSON key  
  6.         TestJSONKey.GetTokenAndCall();  
  7.   
  8.         // Testing with P12 key  
  9.         TestP12Key.GetTokenAndCall();  
  10.     }  
  11. }  
You will get a response like this.

 
You can change the scopes and use access token according to your need. Before making API call, just make sure to enable the same in Google Developer Console for he given project.
 
For complete code, check my GitHub repo.


Similar Articles