I am trying to authneticate gmail api using c# console application.
I am using.net sdk of Google api and the code i am using to authorize the api is as follows :
UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "clientId",
ClientSecret = "clientsecret"
},
new[] { GmailService.Scope.GmailModify },
"user",
CancellationToken.None, null);
But the above code open a browser window to ask for permission to access the service, I need to avoid this authentication activity as I need to schedule ".exe" file of the project on Azure
You're confusing between authorization and authentication.
Authorization is a one time process and you cannot authorize without user authorizing your app to do whatever you're meaning to do. It is a one time process.
What you're doing in the code is authorization. It will definitely open a browser for the user to authorize your app. Once you authorize your app, then for next time, all you need to do is authenticate. Authentication doesn't require this manual user process.
All you have to do is to use the UserCredential you receive from the Google from the next time you need it.
Store the credential you receive from the service somewhere and use it next time to initialize the Service
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential, //your stored credential
ApplicationName = "App",
});
However you may need to refresh the Credential token (which expires every 60 minutes). It should automatically refresh, but you can refresh it manually everytime you need it by making a check.
if (credential.Token.IsExpired)
var returnBool = await credential.RefreshTokenAsync(cancellationToken);
Related
I'm running a process without UI that retrieves uploaded videos from youtube. On a develpement machine it authenticates on user behalf and it works.
The problem is when process is running on a server: browser window doesn't fire for user to let use his account (it should only require to do it once).
Event viewer shows no errors whatsoever. Service accounts doesn't seem to work with youtube, with API key is too less permissions and
oath is the only way to authenticate and get broadcasted videos. Or am I wrong?
So the question is: How to run a service as a single user and retrieve his videos without UI?
private async Task Run()
{
try
{
UserCredential credential;
using (var stream = new FileStream(StartPath + "\\client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { YouTubeService.Scope.YoutubeReadonly, YouTubeService.Scope.Youtube },
"user",
CancellationToken.None,
new FileDataStore("Store")
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
....
}
I have also tried:
String serviceAccountEmail = "e-mail";
var certificate = new X509Certificate2(HostingEnvironment.MapPath("~/Content/key.p12"), "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { YouTubeService.Scope.Youtube, YouTubeService.Scope.YoutubepartnerChannelAudit, YouTubeService.Scope.YoutubeUpload }
}.FromCertificate(certificate));
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "api",
});
The YouTube Data API lets you incorporate functions normally executed on the YouTube website into your own website or application. The lists below identify the different types of resources that you can retrieve using the API. The API also supports methods to insert, update, or delete many of these resources.
This reference guide explains how to use the API to perform all of these operations. The guide is organized by resource type. A resource represents a type of item that comprises part of the YouTube experience, such as a video, a playlist, or a subscription. For each resource type, the guide lists one or more data representations, and resources are represented as JSON objects. The guide also lists one or more supported methods (LIST, POST, DELETE, etc.) for each resource type and explains how to use those methods in your application.
The following requirements apply to YouTube Data API requests:
Every request must either specify an API key (with the key parameter) or provide an OAuth 2.0 token.
Your API key is available in the Developer Console's API Access pane for your project.
You must send an authorization token for every insert, update, and delete request. You must also send an authorization token for any request that retrieves the authenticated user's private data.
In addition, some API methods for retrieving resources may support parameters that require authorization or may contain additional metadata when requests are authorized. For example, a request to retrieve a user's uploaded videos may also contain private videos if the request is authorized by that specific user.
The API supports the OAuth 2.0 authentication protocol. You can provide an OAuth 2.0 token in either of the following ways:
Use the access_token query parameter like this: ?access_token=oauth2-token
Use the HTTP Authorization header like this: Authorization: Bearer oauth2-token
Complete instructions for implementing OAuth 2.0 authentication in your application can be found in the authentication guide.
So I've managed to make a work around that situation by creating console application program that does the thing.
Authentication mechanism moved into console application and passed the results to the service. In a service made a call into that application every n seconds. This solution worked like a charm. Ugly one, but it worked. Now i can give application access to profile data and use it where I want to.
If anyone will have a better solution I would be glad to read it.
I have a windows phone 8.1 app and I'm trying to do Google Auth using either Azure Mobile Services Auth or Google Auth library and it fails using both methods returning a 400 error. I get to the sign-in page and after signing in it returns the 400 and does not take me to the consent page.
Here's my Google Auth code:
IConfigurableHttpClientInitializer credential;
var clientSecrets = new Uri(Settings.GoogleClientSecretsUri, UriKind.Absolute);
var scopes = new[] {CalendarService.Scope.Calendar};
credential = await GoogleWebAuthorizationBroker
.AuthorizeAsync(
clientSecrets,
scopes,
"user",
CancellationToken.None
);
Initializer = new BaseClientService.Initializer{
HttpClientInitializer = credential,
ApplicationName = Settings.ApplicationName
Azure Auth is very stright forward one line code
azureClient.LoginAsync(MobileServiceAuthenticationProvider.Google);
My Azure Auth code is working fine for Facebook and Microsoft Account.
My redirect Uri on the google developer console is of https://todolist.azure-mobile.net/signin-google format and I also tried https://todolist.azure-mobile.net/login/google.
Has anyone been successful in using Google Auth on a Windows Phone?
I was able to get a RefreshToken by following the instruction given in this link : How do I authorise a background web app without user intervention? (canonical ?).
Now I need user credential for getting driveservice object. I have searched a lot but cant find a exact solution.
I can get access token using refresh token, ClientId and ClientSecret following this link :Using OAuth 2.0 for Web Server Applications - offline.
But after that how can I get user credential using that AccessToken? Or any direct way for getting credential using refresh token. Any example or suggestion.
Thanks!
You might want to try using the Client Lib for this instead of that. All you need to do is run the following code once. The refresh token will be created by FileDataStore and stored in your %appData% directory. The next time it runs it wont prompt you for authentication because it will have it already. You could also create your own implementation of iDataStore to store the refresh token where ever you like. I like current directory LocalFileDatastore.cs.
//Scopes for use with the Google Drive API
string[] scopes = new string[] { DriveService.Scope.Drive,
DriveService.Scope.DriveFile};
// here is where we Request the user to give us access, or use the Refresh Token that was previously stored in %AppData%
UserCredential credential =
GoogleWebAuthorizationBroker
.AuthorizeAsync(new ClientSecrets { ClientId = CLIENT_ID
, ClientSecret = CLIENT_SECRET }
,scopes
,"SingleUser"
,CancellationToken.None
,new FileDataStore("Daimto.GoogleDrive.Auth.Store")
).Result;
Code ripped from Google Drive API C# tutorial.
I have been struggling with Google Calendar Api (V3) for quite a while, but I can now create events and list events for a given timespan. I am doing this in C# to create a desktop app.
I have two different google accounts, and I want to be able to post to each of those calendars separately. Using the code below (for the first google account) I am able to connect and post to the one calendar, but when I use the same code on a different form with the .json file from the 2nd google account, it comes back with error [404] not found when I attempt to list the events in that particular calendar. It is able to show a list of calendars BUT the ones listed are from the 1st google account. I have logged out of my google accounts in my web-browser, but my program consistently things I am working with the 1st google account.
PS: for the 2nd google account, I have a differntly named .json file, downloaded from the developer site while logged in with the 2nd google account. The app name for the 2nd google account is also named differently.
public async Task<int> testZZquery()
{
UserCredential credential;
using (var stream = new FileStream("CMgcal_client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { CalendarService.Scope.Calendar },
"user", CancellationToken.None);
}
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "mygcal",
});
It's the Oauth tokens that decide which account will be accessed, it's not the client secret or the project you are using. You can happily use the same project in the console for retrieving data from both the accounts. However, you will need to request a separate OAuth token for each of them and then use it for accessing the data.
The Oauth2 documentation is here: https://developers.google.com/accounts/docs/OAuth2
I am able to authenticate and perform actions on google drive using credential I got after authentication but this token is there for long long time. it says expires-in : 3600 so it should expire in 1hour but when I tried it after a month it uses that token and it worked.
My requirement is after authentication and whatever task is being performed get complete, it should again ask for authentication to user if user initiate the program again. so basically I don't want token to be stored in client's system. Expires-in is not working for me as token get refreshed and is not asking again for Authentication.
below is my code which I am using :
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "<myid>.apps.googleusercontent.com",
ClientSecret = "<Mysecret>"
},
new[] { DriveService.Scope.Drive },
"user",
CancellationToken.None).Result;
// Create the service using the client credentials.
DriveService service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "sampleapp"
});
*****some task performed*********
now after this "some task" I want token to be destroy.
Please help.
From release 1.8.2 (http://google-api-dotnet-client.blogspot.com/2014/05/announcing-release-of-182.html) which was just released earlier today, we support token revocation. It revokes the token and also deletes it form the data store.
All you have to do is the following:
await credential.RevokeTokenAsync(CancellationToken.None);
As simple as that.
UPDATE:
Read more about token revocation in the Google APIs client library for .NET in this blogpost: http://peleyal.blogspot.com/2014/06/182-is-here.html
The reason that you user is not getting asked again is because you are passing a refresh token, you just didn't know it.
Normal when I do this I use the following code:
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "<myid>.apps.googleusercontent.com",
ClientSecret = "<Mysecret>"
},
new[] { DriveService.Scope.Drive },
"user",
CancellationToken.None,
FileDataStore("Drive.Auth.Store")).Result;
What happens then is a file with my refresh token is stored in the user %AppData% directory with the name Drive.auth.store.
{
"access_token":"ya29.IgA23NyW3rF0xxoAAACFPgYzOm9Bm1Vixr-ti9crN5LvEr0W_gjtUQWOCy9QHw",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"1/OGUwUcl92Abo-7LAsuC0tsp_FWxhOW_freUyKncNalI",
"Issued":"2014-05-26T20:34:07.447+02:00"
}
Now your code is slightly diffrent you arent sending FileDataStore("Drive.Auth.Store"). I hadn't tried not sending it before so I had to test this. It appears that by default GoogleWebAuthorizationBroker.AuthorizeAsync stores the refresh token for you just like it would if you used FileDataStore. The name appears to be a default Tasks.Auth.Store.
So what is happening is that every time your user runs your application the Client lib is auto loading that file for you.
How to fix it:
The ugly way would be to randomly change "User" (timestamp or something), if that is different then it will automatically prompt for authentication again. You will need to check the file in %appdata% i have no idea if its going to create a new one every time they run your application or if its just going to over wright the old one. Its probably not a good idea to keep creating crap files on the users PC.
The nice way. Create your own implementation of Idatastore that just doesn't save it. You can find a very basic example of that Google Oauth C# at the bottom called stored refresh token Just don't store it anyplace.