0

I am trying to populate users in my C# application. However, I keep getting this exception:

{"Error occurred while sending a direct message or getting the response."}
[DotNetOpenAuth.Messaging.ProtocolException]: {"Error occurred while sending a direct message or getting the response."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
InnerException: {"The remote server returned an error: (401) Unauthorized."}
Message: "Error occurred while sending a direct message or getting the response."
Source: "Google.Apis"
StackTrace: "   at Google.Apis.Requests.ClientServiceRequest`1.Execute() in c:\\code.google.com\\google-api-dotnet-client\\default\\Tools\\BuildRelease\\bin\\Release\\release140\\default\\Src\\GoogleApis\\Apis\\Requests\\ClientServiceRequest.cs:line 88\r\n   at GoogleAccountsPopulation.DirectoryServiceClient.CreateUser(User user) in E:\\GoogleAccountsPopulation\\GoogleAccountsPopulation\\GoogleAccountsPopulation\\DirectoryServiceClient.cs:line 70\r\n   at GoogleAccountsPopulation.frmGoogleAccountsPopulation.btnPopulateAccounts_Click(Object sender, EventArgs e) in E:\\GoogleAccountsPopulation\\GoogleAccountsPopulation\\GoogleAccountsPopulation\\PopulateForm.cs:line 449"
TargetSite: {TResponse Execute()}

The exception is being raised on the line:

userServiceClient.CreateUser(user);

Here is the codes for the service:

DirectoryServiceSpecs userServiceSpecs = new DirectoryServiceSpecs()
{
    CertificateFilePath = Path.GetDirectoryName(Application.ExecutablePath) + "\\Certificates\\" + gappsSchool.CertificateFile,
    PrivateKey = gappsSchool.PrivateKey,
    ServiceAccountId = gappsSchool.ServiceAccountId,
    ServiceAccountUser = gappsSchool.ServiceAccountUser,
    Domain = gappsSchool.EmailDomain,
    ServiceScope = DirectoryService.Scopes.AdminDirectoryUser.GetStringValue()
};
DirectoryServiceClient userServiceClient = new DirectoryServiceClient(userServiceSpecs);

User user = new User();
user.Name = new UserName();
if (userNames.Length > 1)
{
    user.Name.FamilyName = lmsUser.Name.Replace(userNames[0], "").Trim();
    user.Name.GivenName = userNames[0];
}
else
{
    user.Name.FamilyName = "N.A.";
    user.Name.GivenName = userNames[0];
}
user.Name.FullName = lmsUser.Name;
user.Password = lmsUser.Password;
user.PrimaryEmail = lmsUser.EmailAccount + "@" + gappsSchool.EmailDomain;
if (Properties.Settings.Default.LMSPasswardHashAlgorithm.Trim() != string.Empty)
    user.HashFunction = "MD5";

user = userServiceClient.CreateUser(user);
trackEntries.Add(new TrackEntry()
{
    EmailAccount = lmsUser.EmailAccount,
    SchoolName = gappsSchool.Name,
    Status = "Success",
    Error = ""
});
log.Info("Successfully created user \"" + lmsUser.EmailAccount + "\" (" + lmsUser.Id.ToString() + ", " + gappsSchool.Name + ").");  
userServiceClient.CreateUser(user);
ekad
  • 14,436
  • 26
  • 44
  • 46
Wee
  • 1
  • 1

1 Answers1

0

Authorization

In Google Apps domains, the domain administrator can grant third-party applications with domain-wide access to its users' data — this is referred as domain-wide delegation of authority. To delegate authority this way, domain administrators can use service accounts with OAuth 2.0.

Here is the list of scopes available in Directory API.

To request access using OAuth 2.0, your application needs the scope information, as well as information that Google supplies when you register your application (such as the client ID and the client secret).

Try checking how you perform Google Apps Domain-Wide delegation of authority. You are receiving an Exception 401 Unauthorized maybe because your service account is not authorized to create a user (wrong scope used or the scope to used is not added), based from Emily's answer - you must impersonate a administrator account (Note: only administrator can create users).

Community
  • 1
  • 1
Mr.Rebot
  • 6,703
  • 2
  • 16
  • 91