Getting access token and refresh token without asking for user permission - c#

I want to access Google Drive to upload files using Google.Apis.Drive.v3.
Here is my code:
protected async void btnConnectGoogleDrive_Click(object sender, EventArgs e)
{
string[] Scopes = { DriveService.Scope.Drive };
UserCredential credential;
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "",
ClientSecret = ""
},
Scopes,
"user",
CancellationToken.None);
InsertGoogleDriveToken(credential.Token.AccessToken, areaID, "accesstoken");
InsertGoogleDriveToken(credential.Token.RefreshToken, areaID, "refreshtoken");
// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "SocialLadder",
});
GoogleDriveUpload(service, areaID);
}
Here I am able to get the AccessToken and RefreshToken but user is not redirected to permission page, so when I try to upload images to drive it gives me error that "permission_not_granted". Used same thing in MVC and that works great.
Please help me with this issue.

I suspect that you have changed your scopes. You need to authenticate the user. Do one of the following
Go to %appdata% and delete the creditlas file for this user.
change "user" to something else say "user1"
Your application should then require the user to authenticate again.

Related

How to get email address of a user using Google Oauth .NET library

I would like to get the email address of a user after successful sign-in. Google Plus APIs will be depreciated by Google. Any other way to access just email address of the user? Using the below code, I'll have access access token and id_token of the user.
UserCredential credential =
GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
, scopes
, userName
, CancellationToken.None
, new FileDataStore(fileDataStorePath)).Result;
Update: The following code worked.
var gmailService = new Google.Apis.Gmail.v1.GmailService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = "App name"
});
var gmailProfile = gmailService.Users.GetProfile("me").Execute();
string EmailAddress = gmailProfile.EmailAddress;
Make sure that you have include the "email" scope as part of your scopes.
create a service object.
var service = new PeopleService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Peopleservice Oauth2 Authentication Sample"
});
Then make a request to the people api.
var results = service.People.Get("person/me").ExecuteAsync();

Google.Apis.Requests.RequestError Request had insufficient authentication scopes. [403] in GCP for Firebase Management Api

i am try to create a new project using resourcemanager.projects.create But got an error like :(
Google.Apis.Requests.RequestError
Request had insufficient authentication scopes. [403]
Errors [
Message[Request had insufficient authentication scopes.] Location[ - ] Reason[forbidden] Domain[global]
]
Can anyone please tell me What i am doing wrong.
Here is my code :
private async void GoogleClick(object sender, RoutedEventArgs e)
{
try
{
var cr = new PromptCodeReceiver();
var result = await GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets { ClientId = GoogleClientId,ClientSecret = GoogleSecretKey },
new[] { "email", "profile" },
"user",
CancellationToken.None);
if (result.Token.IsExpired(SystemClock.Default))
{
await result.RefreshTokenAsync(CancellationToken.None);
}
CloudResourceManagerService cloudResourceManagerService = new CloudResourceManagerService(new BaseClientService.Initializer
{
HttpClientInitializer = GetCredential(result.Token.AccessToken, FirebaseAuthType.Google),
ApplicationName = "Kapiling",
//ApiKey = "apikey"
});
// TODO: Assign values to desired properties of `requestBody`:
Data.Project requestBody = new Data.Project();
requestBody.Name = "TESTING";
requestBody.ProjectNumber = 415104041262;
requestBody.ProjectId = "tokyo-rain-123";
requestBody.CreateTime = "2014-10-02T15:01:23.045123456Z";
ProjectsResource.CreateRequest request = cloudResourceManagerService.Projects.Create(requestBody);
}
I am try to access using public static GoogleCredential FromAccessToken(string accessToken, IAccessMethod accessMethod = null); method
public static GoogleCredential GetCredential(string accessToken, FirebaseAuthType authType)
{
GoogleCredential credential = GoogleCredential.FromAccessToken(accessToken, null);
return credential;
}
Thanks for everyone who help me i Solved this issues.
Thanks again. :)
This trouble is caused by incorrect scopes of authorization, that's correct. The solution for this particular case is to authorize only once with correct scopes(preferred) or to authorize at every such situation when you need to write/update/append.
However, the author only commented that the problem is solved but not described the solution. In many cases which guided by official API documentation, you can see this code
const string credPath = "token.json";
credential = GoogleWebAuthorizationBroker
.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true))
.Result;
In those examples, you're specifying the last parameter to save some auth data to the folder defined by the credPath variable. Note that if you want to change your scopes after you run the app once, this auth data won't be overwritten so you have to:
delete this existing data every time before running the app
change credPath
or simply remove this parameter, but in this case, you'll have to confirm your auth every time you start the app.
You first have to set your scope to Calendar (as this is the one with most permissions, you also have: CalendarEvents, CalendarEventsReadonly, CalendarReadonly,CalendarSettingsReadonly choose which one you need depending on your needed permission level) like this :
static string[] Scopes = {CalendarService.Scope.Calendar};
But this is not done, as you need to delete your credentials path that was already created or change its name , in the documentation his name was "token.json" as if you leave this one the user had already agreed on specific access to his data but now if you delete this file or changed he'll be prompted to a new window on his browser to accept the new access to his data (in the case of Scope.Calendar scope, he'll be prompted to accept that we have the right to get, insert, update and delete his events on his calendar among others)
From looking at the GCP documentation, it seems like you (also) need the https://www.googleapis.com/auth/cloud-platform scope. See https://cloud.google.com/resource-manager/docs/authorizing
Change your code for GetCredential(). Note: I am not sure what you are trying to do with FirebaseAuthType so I have left authType as an unused parameter.
public static GoogleCredential GetCredential(string accessToken, FirebaseAuthType authType)
{
GoogleCredential credential = GoogleCredential.FromAccessToken(accessToken, null);
// The following line is no longer needed
// credential = credential.CreateScoped("https://www.googleapis.com/auth/cloud-platform");
return credential;
}
[EDIT]: Additional code to change due to the comment createScopedRequired = false
You received this message because you already authenticated with scopes. To change the scopes requires another authorization. In this case request the correct scopes. Note, you do not need the other scopes (email and profile). Put them back in later if you do.
string[] scopes = new string[] { "https://www.googleapis.com/auth/cloud-platform" };
var result = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets {
ClientId = GoogleClientId,
ClientSecret = GoogleSecretKey },
scopes,
"user",
CancellationToken.None).Result;

How to Sync Database with Google Calender

I am using this code and it works and allows my app to get the Calendar List from the used google account.
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "xxx",
ClientSecret = "xxxx-xxxx",
},
new[] { CalendarService.Scope.Calendar },
"support#xxx.com",
CancellationToken.None).Result;
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "xxx",
});
CalendarListResource.ListRequest cal = service.CalendarList.List();
cal.MaxResults = 10;
var calresult = cal.Execute().Items;
My question is when i do this i than import all the Calender's And Events to my local database so after an hour i need to run a script to update the Database with the latest Calendar and Event info as they might have added new Events or deleted some same goes with Calender's.
Not sure where to look for any suggestion?
For others:
The answer is here:
How to access users calendar list and events from google api using access token and refresh token
Basically you save the token and later user it for that Calendar.

Access to the path Google.Apis.Auth is denied

I was trying to implement google calender event sync functionality to schedule event from my local application to google calendar. its working fine in local system but whenever I deployed it on server, it throws the following error.
System.UnauthorizedAccessException: Access to the path 'Google.Apis.Auth' is denied
Below is the code which I am using for same.
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "xxx-9khdjsqifkj2amsji2jce37p8lfn0166.apps.googleusercontent.com",
ClientSecret = "ZdsrCa-uwG3GmpVLTfYDli-S",
},
new[] { CalendarService.Scope.Calendar },
"user",
CancellationToken.None).Result;
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = Summary,
});
By default the Google .Net client library uses FileDatastore() file datastore by default stores the credentials in %appData%. When you run your application under what ever user it is you are running you don't apperntly have access to %appData%
string credPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "xxx4671204-9khdjsqifkj2amsji2jce37p8lfn0166.apps.googleusercontent.com",
ClientSecret = "ZdsrCa-uwG3GmpVLTfYDli-S",
},
new[] { CalendarService.Scope.Calendar },
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Make sure that credPath is some place that you have access to write to. I have a sample on GitHub for Google calendar Oauth2 and I have a tutorial on how filedatastore works FileDatastore demystified

GmailService create Watch() getting User not authorized error

this this code snniped:
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,//read from client secret.json file
Scopes,
"user",
CancellationToken.None).Result;
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
UsersResource.LabelsResource.ListRequest request = service.Users.Labels.List("me");
WatchRequest body = new WatchRequest()
{
TopicName = "projects/push-notifications-ver3/topics/mytopic",
LabelIds = new[] {"INBOX"}
string userId = "me";
UsersResource.WatchRequest watchRequest = service.Users.Watch(body, userId);
WatchResponse test = watchRequest.Execute();
Getting Error:
Error sending test message to Cloud PubSub projects/push-notifications-ver3/topics/mytopic : User not authorized to perform this action. [403]
Topic was created with subscription, permission was given to current user as owner of topic
Any suggestion why user not authorized ?
Have you completed the OAuth process for the given user? Also, are you replacing the word "user" in the method AuthorizeAsync() with your authenticated user? If yes, then try to do it with new client secrets file and also check if PubSub Scope is present in the variable scope.
I face a similar issue and it turned out to be one of these issues. Might work for you as well.

Categories