{"id":13305676,"url":"https://github.com/ilanlal/serviceAccount-dotnet-sample","last_synced_at":"2025-03-10T13:32:17.013Z","repository":{"id":192373616,"uuid":"485925466","full_name":"ilanlal/serviceAccount-dotnet-sample","owner":"ilanlal","description":"How to access AdminAPI.DirectoryService using Service Account, .Net Framework 4.8 (C#)","archived":false,"fork":false,"pushed_at":"2022-04-27T02:31:15.000Z","size":19,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-04-20T18:55:35.829Z","etag":null,"topics":["admin-sdk","delegation","directory-api","dotnet-framework","google-workspace","impersonation","server2server","service-account"],"latest_commit_sha":null,"homepage":"https://www.easyadm.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ilanlal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-04-26T19:44:26.000Z","updated_at":"2022-04-27T00:54:43.000Z","dependencies_parsed_at":"2023-09-04T14:14:53.164Z","dependency_job_id":null,"html_url":"https://github.com/ilanlal/serviceAccount-dotnet-sample","commit_stats":null,"previous_names":["ilanlal/serviceaccount-dotnet-sample"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilanlal%2FserviceAccount-dotnet-sample","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilanlal%2FserviceAccount-dotnet-sample/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilanlal%2FserviceAccount-dotnet-sample/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ilanlal%2FserviceAccount-dotnet-sample/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ilanlal","download_url":"https://codeload.github.com/ilanlal/serviceAccount-dotnet-sample/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242859773,"owners_count":20196993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin-sdk","delegation","directory-api","dotnet-framework","google-workspace","impersonation","server2server","service-account"],"created_at":"2024-07-29T17:53:59.788Z","updated_at":"2025-03-10T13:32:16.774Z","avatar_url":"https://github.com/ilanlal.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sample: How to access AdminAPI.DirectoryService using Service Account, .Net Framework 4.8 (C#)\nA service account is a special kind of account used by an application, rather than a person. \n\nYou can use a service account to access data or perform actions by the robot account itself, or to access data on behalf of Google Workspace or Cloud Identity users.\n\n## Prerequisites:\n  + ### A Google Cloud Platform project \n    With the Admin SDK API enabled service account with domain-wide delegation. \n  + ### A Google Workspace domain.\n    With account in that domain with administrator privileges.\n  + ### Visual Studio 2013 or later \n\n## Step 1: Set up the Google Cloud Platform project\n+ ### Create Google Cloud project\n  A Google Cloud project is required to use Google Workspace APIs and build Google Workspace add-ons or apps.\n  If you don't already have a Google Cloud project, refer to: [How to create a Google Cloud project](https://developers.google.com/workspace/guides/create-project)\n\n+ ### Enable Google Workspace APIs\n  Before using Google APIs, you need to enable them in a Google Cloud project. \n    \n  To Enable Google Workspace APIs refer to: [How to Enable Google Workspace APIs](https://developers.google.com/workspace/guides/enable-apis)\n  \n  For this example you are enabling the the [Admin SDK Directory API](https://developers.google.com/admin-sdk/directory)\n  with the data scope `/auth/admin.directory.user.readonly`.\n \n    \n+ ### Create Service Account with domain-wide delegation\n  To create service account refer to: [How to create service account?](https://developers.google.com/workspace/guides/create-credentials#create_a_service_account)\n  \n  In the `Domain wide delegation` pane, select `Manage Domain Wide Delegation`.\n\n+ ### Download Service Account private key (p12 format)\n  Download p12 file [contains the private key](https://cloud.google.com/iam/docs/creating-managing-service-account-keys) for your Service Account.\n  \n## Step 2: Set up the Google Workspace \n+ ### Enable API access in the Google Workspace domain with\n  To enable API access in Google Workspace domain, refer to: [how to enable API access](https://support.google.com/a/answer/7281227?visit_id=637865874764605082-823144595\u0026rd=1)\n+ ### Delegating domain-wide authority to the service account\n  To call APIs on behalf of users in a Google Workspace organization, your service account needs to be granted domain-wide delegation of authority in the Google Workspace Admin console __by a super administrator account__\n  \n  To delegating domain-wide authority in Google Workspace domain, refer to: [How to Delegating domain-wide authority](https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority) to the service account\n\n## Step 3: Prepare Visual Stodio project - \n+ ### Create a new Visual C# Console Application (.NET Framework) project in Visual Studio.\n+ ### Open the NuGet Package Manager Console, select the package source nuget.org, and run the following commands:\n  + #### `Install-Package Google.Apis.Auth`\n  + #### `Install-Package Google.Apis.Admin.Directory.directory_v1`\n\n## Step 4: Add code\n\n### `SACService.cs`\n```csharp\n  using Google.Apis.Auth.OAuth2;\n\n  using System;\n  using System.Security.Cryptography.X509Certificates;\n  using System.Threading;\n\n  /// \u003csummary\u003e\n  //     Google OAuth 2.0 credential for accessing protected resources using an access\n  //     token. The Google OAuth 2.0 Authorization Server supports server-to-server interactions\n  //     such as those between a web application and Google Cloud Storage. The requesting\n  //     application has to prove its own identity to gain access to an API, and an end-user\n  //     doesn't have to be involved.\n  /// \u003c/summary\u003e\n  public static class SACService {\n    /// \u003csummary\u003e\n    /// Constructs a new service account credential using the given initializer.\n    /// \u003c/summary\u003e\n    /// \u003creturns\u003eServiceAccountCredential\u003c/returns\u003e\n    /// \u003cexception cref=\"InvalidOperationException\"\u003e\u003c/exception\u003e\n    public static ServiceAccountCredential CreateServiceAccountCredential(SACInitializeParameters parameters) {\n      using (var x509Certificate2 = new X509Certificate2(\n       parameters.X509CertificateFilePath,\n       \"notasecret\",\n       X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable)) {\n\n        var credential = new ServiceAccountCredential(\n          new ServiceAccountCredential.Initializer(parameters.ServiceAccountId) {\n            User = parameters.ImpersonateEmail,\n            Scopes = parameters.Scopes\n          }.FromCertificate(x509Certificate2));\n\n        \n        if (credential.RequestAccessTokenAsync(CancellationToken.None).Result) {\n          return credential;\n        }\n        else {\n          throw new InvalidOperationException($\"Request for access token failed. {parameters.ToString()} \");\n        }\n      }\n    }\n  }\n```\n\n### `DirectoryServiceStore.cs`\n```csharp\n  using Google.Apis.Services;\n  using AdminAPIs = Google.Apis.Admin.Directory.directory_v1;\n\n  public static class DirectoryServiceFactory {\n    public static AdminAPIs.DirectoryService CreateDirectoryService(SACInitializeParameters parameters) {\n      return new AdminAPIs.DirectoryService(\n        new BaseClientService.Initializer() {\n          HttpClientInitializer = SACService.CreateServiceAccountCredential(parameters)\n        });\n    }\n  }\n```\n\n### `SACInitializeParameters.cs`\n```csharp\n  /// \u003csummary\u003e\n  /// Initializer paramters to constructs any new google service account credential\n  /// \u003c/summary\u003e\n  public class SACInitializeParameters {\n    /// \u003csummary\u003e\n    /// The service account ID (typically an e-mail address like: *@*iam.gserviceaccount.com)\n    /// \u003c/summary\u003e\n    public string ServiceAccountId;\n    /// \u003csummary\u003e\n    /// The full path; name of a certificate file.\n    /// \u003c/summary\u003e\n    public string X509CertificateFilePath;\n    /// \u003csummary\u003e\n    /// The email address of the user the application trying to impersonate\n    /// \u003c/summary\u003e\n    public string ImpersonateEmail;\n    /// \u003csummary\u003e\n    /// The scopes which indicate API access your application is requesting\n    /// \u003c/summary\u003e\n    public string[] Scopes;\n\n    /// \u003csummary\u003e\n    /// Constructs initialize paramters for google service account credential\n    /// \u003c/summary\u003e\n    /// \u003cparam name=\"serviceAccountId\"\u003eThe service account ID\u003c/param\u003e\n    /// \u003cparam name=\"x509CertificateFilePath\"\u003eThe full path; name of a certificate file.\u003c/param\u003e\n    /// \u003cparam name=\"impersonateEmail\"\u003eThe email address of the user the application trying to impersonate\u003c/param\u003e\n    /// \u003cparam name=\"scopes\"\u003eThe scopes which indicate API access your application is requesting\u003c/param\u003e\n    public SACInitializeParameters(\n      string serviceAccountId, string x509CertificateFilePath, string impersonateEmail, string[] scopes) {\n      this.ServiceAccountId = serviceAccountId;\n      this.ImpersonateEmail = impersonateEmail;\n      this.Scopes = scopes;\n      this.X509CertificateFilePath = x509CertificateFilePath;\n    }\n\n    override public string ToString() {\n      return Newtonsoft.Json.JsonConvert.SerializeObject(this);\n    }\n  }\n```\n\n### Set up credentials parameters\n\n```csharp\n  var _paramters = new SACInitializeParameters(\n    \n  // The service account ID (typically an e-mail address like: *@*iam.gserviceaccount.com)\n  serviceAccountId: \"[Service Account ID]\",\n    \n  // The full path; name of a certificate file\n  x509CertificateFilePath: \"[X509 Certificate File]\",\n    \n  // The email address of the user you trying to impersonate\n  impersonateEmail: \"[User Email]\",\n    \n  // The scopes which indicate API access your application is requesting\n  scopes: _scopes);\n```\n\n### List top 10 users alias from Google Workspace Domain\n```csharp\n  /// \u003csummary\u003e\n  /// Example how to list all users from google workspace domain, using a service account (user impersonation).\n  /// \u003c/summary\u003e\n  internal class Program {\n    static void Main(string[] args) {\n      // Scope for only retrieving users or user aliases.\n      string[] _scopes = {\n        \"https://www.googleapis.com/auth/admin.directory.user.readonly\"\n      };\n\n      var _paramters = new SACInitializeParameters(\n        // The service account ID (typically an e-mail address like: *@*iam.gserviceaccount.com)\n        serviceAccountId: \"[Service Account ID]\",\n        // The full path; name of a certificate file\n        x509CertificateFilePath: \"[X509 Certificate File]\",\n        // The email address of the user you trying to impersonate\n        impersonateEmail: \"[User Email]\",\n        // The scopes which indicate API access your application is requesting\n        scopes: _scopes);\n\n\n      using (var directoryService = DirectoryServiceFactory.CreateDirectoryService(_paramters)) {\n        // Retrieves a paginated list of either deleted users or all users in a domain.\n        var request = directoryService.Users.List();\n        // The unique ID for the customer's Google Workspace account\n        // the `my_customer` alias represent current identety account's\n        request.Customer = \"my_customer\";\n        request.MaxResults = 10;\n        var response = request.Execute();\n\n        foreach (var user in response.UsersValue) {\n          System.Console.WriteLine($\"{user.Name.FullName}, {user.PrimaryEmail}, {user.Id}\");\n        }\n      }\n    }\n  }\n```\n\n## References\n\n  + [Creating and managing service account keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys#iam-service-account-keys-create-csharp)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filanlal%2FserviceAccount-dotnet-sample","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filanlal%2FserviceAccount-dotnet-sample","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filanlal%2FserviceAccount-dotnet-sample/lists"}