Since Google stopped support for their older Auth, and now we have to use oAuth 2, our simple desktop application can no longer read contacts from my google account.
Fine - i understand this, however this new oAuth 2 is extraordinarily complicated... and im not talking about from a developer perspective. From what i am reading online. We now have to make our customers jump over a multitude of hoops in order for our simple application to read contacts stored in their Google mail/Contacts.
My iPhone seems to be able to sync contacts just fine with just the typical email and password that i entered about a year ago. How do they get it to work? and yet with my simple desktop application, the client has to be rummaging around in Google Developer sites and with API settings etc. I'm a developer and im confused!! - could you imagine what my customer is going to go through... it cant be this complicated.
Is there anyone who can give me the simple 1,2,3 to get a C# desktop application to go off and get the contacts (read-only) from a particular Gmail account... with the least amount of fiddling around (for the owner of the Gmail account).
Ill do all the hard work in the application - i just don't want to client to have to spend an hour authorizing and creating API's and clicking around in a developer site (he/she is NOT a developer).
The main problem you have here is that contacts is an old Gdata API. It is possible to use Oauth2 with the Gdata library but its not pretty. Personally I like to hack things a little. I use the Current .net client library with the old Gdata client library.
Nuget New client library for authentication:
not 100% sure this is the only one you need let me know if it doesn't work we can find it. You basically need Google.apis.auth.oauth2 and google apis.util.store.
Install-Package Google.Apis.Auth
Nuget old client library for contacts:
Install-Package Google.GData.Contacts
Code
using Google.Apis.Auth.OAuth2;
using Google.Apis.Util.Store;
using Google.Contacts;
using Google.GData.Client;
using System;
using System.Threading;
public static void auth()
{
string clientId = "xxxxxx.apps.googleusercontent.com";
string clientSecret = "xxxxx";
string[] scopes = new string[] { "https://www.googleapis.com/auth/contacts.readonly" }; // view your basic profile info.
try
{
// Use the current Google .net client library to get the Oauth2 stuff.
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
, scopes
, "test"
, CancellationToken.None
, new FileDataStore("test")).Result;
// Translate the Oauth permissions to something the old client libray can read
OAuth2Parameters parameters = new OAuth2Parameters();
parameters.AccessToken = credential.Token.AccessToken;
parameters.RefreshToken = credential.Token.RefreshToken;
RunContactsSample(parameters);
Console.ReadLine();
}
catch (Exception ex)
{
Console.ReadLine();
}
Console.ReadLine();
}
/// <summary>
/// Send authorized queries to a Request-based library
/// </summary>
/// <param name="service"></param>
private static void RunContactsSample(OAuth2Parameters parameters)
{
try
{
RequestSettings settings = new RequestSettings("Google contacts tutorial", parameters);
ContactsRequest cr = new ContactsRequest(settings);
Feed<Contact> f = cr.GetContacts();
foreach (Contact c in f.Entries)
{
Console.WriteLine(c.Name.FullName);
}
}
catch (Exception a)
{
Console.WriteLine("A Google Apps error occurred.");
Console.WriteLine();
}
}
Tutorial can be found here
Google developers console
All applications accessing google apis must be registered on Google developers console. It is the application accessing Google that is registered users running the code do not need to do this step. Its you as a developer who has to register it.
From this you get the client id and client secret used in the code above.
I have done this but its all a bit of a blur from like you say, a lot of fiddling.
I think you can sign up and setup a project in google developer console and generate a service account. Then the client will need to sign in to HERE as the google app admin and fill out the clientID field with the name of your service account generated by the developer console and the API scope you need access to.
In the end I just logged in as the client to their admin panel and set it up for them. There is no easy way about it without the client also engaging a google apps re-seller to assist. I managed to figure it out as a developer with a lot of googling.
Related
So this is an issue that has been plaguing me for a bit and my deadline is coming up. I'm working on an application that sends emails and my workplace uses Office365 via Exchange. I'm using a C# webapp and using Mailkit to deliver emails.
The issue (not really an issue but good practice that's getting in my way) is that we made an email account to deliver mail yet our organization requires MFA. After talking about it with my director, creating an app password would not be a good idea for how this program is deployed so I'm trying to find ways to authenticate properly.
I eventually landed on using the Microsoft.Identity.Client library to require logging in via a registered Azure application. I could then cache this and refresh as needed, this way making sure the access is still valid.
However, I'm stuck on something. I have the app registration set to public with no client secrets or certificates with all of the necessary permissions. However right at the var oauth2 step, it fails while giving the error "Original exception: AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'."
The issue is that the application is public and is defined to allow public client flows. So I'm not getting how the request could still require a client secret when that's not how I'm building the request at all. I tried using private, but because of the MFA requirement, that fails too.
Below is what I have. Ignore that I'm hard coding stuff; it's temporary until I can get this sorted out. I'm also only scoping the SMTP permissions because all this application needs to do is send an email; IMAP isn't needed since it's not reading or anything else.
var options = new PublicClientApplicationOptions
{
ClientId = "[clientID]",
TenantId = "[tenandID]",
RedirectUri = "http://localhost"
};
var publicClientApplication = PublicClientApplicationBuilder
.CreateWithApplicationOptions(options)
.Build();
var scopes = new string[] {
"email",
"offline_access",
"https://outlook.office.com/SMTP.Send" // Only needed for SMTP
};
var authToken = await publicClientApplication.AcquireTokenInteractive(scopes).ExecuteAsync();
//Here is where it returns that it needs a client_secret and won't advance.
// The login window appears and states it was successfully authenticated,
// but the application crashes with that error at this step.
var oauth2 = new SaslMechanismOAuth2(Config.Env.smtpUser, authToken.AccessToken);
I trying to create a spreadsheet using the google spreadsheets v4. I generated a new server to server credential json on console api. All appears to work, but when I try to access the generated url, I got a screen saying to request permission. The credential was generated from my own service account, associated with my own google account, so I understand that I already have this permission. What could I do to access the generated sheet on browser? Above my code to generate the spreadsheet and the screen I getting.
public class Program
{
static string[] Scopes = { SheetsService.Scope.Spreadsheets, SheetsService.Scope.Drive, SheetsService.Scope.DriveFile };
static string ApplicationName = "Google Sheets API .NET Quickstart";
public static void Main(string[] args)
{
AppendData();
}
public static void AppendData()
{
// the downloaded jsonn file with private key
var credential = GoogleCredential.FromStream(new FileStream(Environment.CurrentDirectory + "/ApiKey/api_key.json", FileMode.Open)).CreateScoped(Scopes);
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
Spreadsheet requestBody = new Spreadsheet()
{
Properties = new SpreadsheetProperties()
{
Title = "Calculo Projeção",
},
};
SpreadsheetsResource.CreateRequest request = service.Spreadsheets.Create(requestBody);
}
}
So, the GSheet you've created was created using the service account. This means that the service account is the owner of the GSheet.
Depending on what your end goal is, and what type of Google Account you're using you may have some options here.
If you're using a G Suite account, the solution is relatively simple. It's to use impersonation with the service account. You're then basically using the service account to impersonate a user to perform the actions. If you impersonate your own account while creating the GSheet, the owner will be your own account. The documentation talks about the specifics here.
If you're NOT using a G Suite account, but a 'normal' Google account, it becomes a bit more tricky. I can think of some options here though:
Quick and dirty: Create the GSheet with your personal account first and give the service account access to it.
Have the service account create the GSheet and use the API/library to give your personal account access.
Create the GSheet not with the service account, but using OAuth and your own credentials. There's several ways to go about this. A good starting point for this would be here...
I may have missed one or two here, but you should understand what's actually happening now.
NOTE: One very important thing you have to take into account. If you delete the service account, any and all Google Drive items (including Sheets, Docs, Forms, etc) get deleted without any way of getting them back.
i am facing so much of confusions and problems while migrating from google api v2 over to v3.
I am dealing with the job scheduling of each employees in a company with the help of integrated google calender. i lost the full control while the provider change the version. let me know the following thing?
can i access the calender of an employee if his/her gmail id and its password is known?
is it needed to provide individual CLIENT ID and CLIENT secret?
what is the use of public Public API access(server key)
how to form the request url that must send to the server.
how to use the JSON file downloaded from the developer console
previously i was using the query as
Try
Dim myService As New CalendarService("test")
myService.setUserCredentials(user_name, user_password)
Dim query As New CalendarQuery()
query.Uri = New Uri("https://www.google.com/calendar/feeds/default/owncalendars/full")
Dim resultFeed As CalendarFeed = DirectCast(myService.Query(query), CalendarFeed)
Catch ex As Exception
lblerror.Text = ex.ToString
connect = 0
End Try
Can I access the calendar of an employee if his/her gmail id and its password is known?
no you must use Oauth2 Google Calendar Authentication
Is it needed to provide individual CLIENT ID and CLIENT secret?
No client_id and Client secret identify your project to Google you only need one.
what is the use of public Public API access(server key)
This is for public apis like Google Books API that do not require authentication.
how to form the request url that must send to the server.
I recommend you look into using the Google-api-dotnet-client lib it will handle all that for
you. Nuget
how to use the JSON file downloaded from the developer console
you don't really need to use it if you use the client lib it just contains the same data as you already asked about open it and see
previously i was using the query as
That is VB code I think and not C# that's not how you will be doing it now. I recommend you start by reading Google Calendar API Authentication with C#
Are there any libraries out there for C# that wrap the process of sharing moments to a user's Google+ account (or to their stream)? I'm looking for something that simply take your ClientId and ClientSecret, and maybe your apiKey along with the user's id to send some text that the user has decided to share with his/her friends.
If not, but you have an example of creating a WebRequest to accomplish the same thing, that would be much appreciated too!
I've reviewed this landing page: https://developers.google.com/+/quickstart/csharp
But I'm trying to integrate into an existing MVC5 application that already has the Auth for GooglePlus taken care of.
The correct client to be using for Google APIs is the Google .NET API Client library, available via NuGet. Additional libraries for specific APIs are required if you use more than the core library. For Plus, you need the Google.Apis.Plus.v1 package.
After you have added it to your projects and have configured an API client, writing app activities is as easy as:
/// <summary>The app activity type for ADD.</summary>
private const string ADD_ACTIVITY_TYPE = #"http://schemas.google.com/AddActivity";
// Construct your Plus Service, I'll assume a helper for here.
PlusService plusService = GetPlusService(credentials);
Moment addMoment = new Moment();
ItemScope target = new ItemScope()
{
Url = ContentUrl
};
addMoment.Type = ADD_ACTIVITY_TYPE;
addMoment.Target = target;
Moment response = null;
try
{
response = plusService.Moments.Insert(addMoment, "me",
MomentsResource.InsertRequest.CollectionEnum.Vault).Execute();
}
catch (System.AggregateException)
{
/* Occurs when the server can't be seen by Google. */
}
catch (Google.GoogleApiException)
{
/* Occurs when the server can't be seen by Google. */
}
How to authenticate a user and authorize your client for access to Google APIs in MVC can be found on this blog: ASP.NET MVC with OpenID and OAuth.
A final note, app activities require you to specify an app activities pseudo-scope (request_visible_actions) which is easier with the Sign-In button than via the framework. If you are getting 401 errors, this is the most likely culprit.
I am not sure if there any libraries(if anyone knows any please let me know) out there that make it easier to use googles api. I know they have classes for .net but they don't seem to work with Windows Phone 7.
I am trying to figure out how it all works but I really find Google's documentation confusion and missing lots of steps.
I decided to try to at first to use their library in an asp.net mvc application before trying to figure out how to do it all with REST requests in a WP7 app.
I am stuck at trying to figure out how to do the Oauth to validation user so I can get their contacts.
RequestSettings settings = new RequestSettings("<var>Test</var>");
settings.OAuth2Parameters = new OAuth2Parameters
{
ClientId = "",
ClientSecret = "",
};
// Need some Code here to validation user so I can then get their contacts.
ContactsRequest cr = new ContactsRequest(settings);
var c = cr.GetGroups();
There is an OAuth NuGet package (DotNetOpenAuth) available, providing authentication through Google, Twitter, Facebook, MSN and possibly more.
Maybe you have more luck with that.