Always prompt user to select an account on application start - c#

I'm using the code from the code samples to authenticate user on application start.
UserCredential credential;
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { YouTubeService.Scope.Youtube },
"user",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
}
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
Everything works fine except that I want to force the Select Account screen to show every time (now it only shows the first time, and then after that the user is remembered) because the application is supposed to allow different users to log in.
Looks like that I'm supposed to set the prompt request parameter to select_account, but I don't know how am I supposed to do this, AuthorizeAsync method doesn't accept any additional arguments.

You are correct that this is currently not possible to do in a simple way.
I've filed a bug to fix this: https://github.com/googleapis/google-api-dotnet-client/issues/1322

Related

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;

"Google.GoogleApiException: Google.Apis.Requests.RequestError Request is missing required authentication credential" when using ScriptService

Using .net, I'm trying to make a request to the Google ScriptService, however I keep getting this error "Request is missing required authentication credential", although I am including the credential. In fact I use the same credential not too long before to successfully make a request to the YoutubeService.
Below is my code, it actually used to work, so I'm not sure what has changed:
Scopes = new string[] { ScriptService.Scope.Forms, ScriptService.Scope.Spreadsheets,
ScriptService.Scope.Drive, YouTubeService.Scope.YoutubeUpload, YouTubeService.Scope.Youtube };
UserCredential credential;
using (var stream = new FileStream(#"Resources\client_secret.json", FileMode.Open, FileAccess.Read))
{
var credPath = Path.Combine(parentDir, ".credentials/" + folderName);
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
}
// Create Google Apps Script Execution API service.
var service = new ScriptService(new BaseClientService.Initializer()
{
HttpClientInitializer = this.credential,
ApplicationName = Properties.Resources.ApplicationName,
});
// Create an execution request object.
ExecutionRequest request = new ExecutionRequest();
request.Function = "createForm";
request.Parameters = new List<object>();
request.Parameters.Add(this.id);
request.Parameters.Add(name);
request.Parameters.Add(email);
request.Parameters.Add(this.link);
ScriptsResource.RunRequest runReq = service.Scripts.Run(request, Globals.Script_ID);
try
{
// Make the API request.
Operation op = runReq.Execute();
catch (Google.GoogleApiException e)
{
Debug.WriteLine("Error calling API:\n{0}", e.ToString());
}
I have enabled the API and generated OAuth 2.0 credentials for my platform in the developer console. The client_secret.json is the OAuth 2.0 credential that I downloaded from my console.
Any thoughts on what could be going wrong? I recall having a similar issue after updating my google packages, however in this instance I did not do so. I also tried updating the packages and still got the same issue.
The issue was that I did not have the correct authorization scopes. Originally I had:
Scopes = new string[] { ScriptService.Scope.Forms, ScriptService.Scope.Spreadsheets,
ScriptService.Scope.Drive, YouTubeService.Scope.YoutubeUpload, YouTubeService.Scope.Youtube };
However, upon checking the "Scopes" tab in my apps script Project Properties, I was missing the "userinfo.email" scope. And so, I updated my code in the following way:
Scopes = new string[] { ScriptService.Scope.Forms, ScriptService.Scope.Spreadsheets,
ScriptService.Scope.Drive, ScriptService.Scope.UserinfoEmail, YouTubeService.Scope.YoutubeUpload, YouTubeService.Scope.Youtube };
My guess is that the API had been updated since I originally wrote my script some months ago, as I was able to successfully run it at that time with the three original authorizations that I had.

Google Spreadsheets Api Key example

I'm developing an application wich needs to access a "simple database" (google spreadsheet) with users IDs.
I try with Oauth2.0 But that's not what I need.
I'm using this code to get access to the sheet:
private static SheetsService AuthorizeGoogleApp()
{
UserCredential credential;
using (var stream =
new FileStream("client_secret.json", FileMode.Open, FileAccess.Read))
{
string credPath = System.Environment.GetFolderPath(
System.Environment.SpecialFolder.Personal);
credPath = Path.Combine(credPath, ".credentials/sheets.googleapis.com-dotnet-quickstart.json");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Google Sheets API service.
var service = new SheetsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
return service;
}
But with this code the C# application open a browser to ask the user to login in his google account.
I need to have access via API, so it will be transparent to the user.
I already have the api key, but I don't know how to use and I don't find any documentation on Google sites.
Can you help me with some kind of example to read a simple column?
Thanks in advance!
Here is the documentation for the API.
It also covers authorization.

Youtube api get live broadcast ID with C#

I want to tried to get youtube live broadcast id. But I can't get this.
Here is my code:
UserCredential credential;
Response.Write("AAA");
var stream2 = new FileStream("c:/users/gislap/documents/visual studio 2012/Projects/youtube/secrect.json", FileMode.Open, FileAccess.Read);
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream2).Secrets,
new[] { YouTubeService.Scope.Youtube },
"user",
CancellationToken.None,
new FileDataStore(this.GetType().ToString())
);
Response.Write("DDD");
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = this.GetType().ToString()
});
var my_video_request = youtubeService.LiveBroadcasts.ToString();
Label1.Text = my_video_request.ToString();
Or any way to get all videos list?
You may refer on this thread. If you want to retrieve information on another channel's current live broadcasts, you have to use the standard Search/list endpoint:
part -> snippet
channelId -> [channelId of the channel/user with the live event]
eventType -> live
type -> video (required when setting eventType to live)
HTTP GET https://www.googleapis.com/youtube/v3/search?part=snippet&channelId={channelId}&eventType=live&type=video&key={YOUR_API_KEY}
Also, based from this documentation, try to use this HTTP request to return a list of YouTube broadcasts that match the API request parameters.
GET https://www.googleapis.com/youtube/v3/liveBroadcasts
Here are examples which might help:
https://developers.google.com/youtube/v3/live/code_samples/
https://github.com/search?l=C%23&q=LiveBroadcasts&type=Code&utf8=%E2%9C%93

Oauth 2.0 for Fusion Tables API in .NET

To automate updating a Google Fusion Table, we have created a .NET console application to which we have attached the file clientsecrets.json generated and downloaded from the Google administration console.
When I run the application locally, a browser window opens to authorize the use of the API with OAuth 2.0. Once it authorized the process executed properly.
However, when we run the application on the server where we want to schedule your daily execution, does not open the browser window and stating "One or more errors ocurred".
The server is a Windows Server 2012. The application is built on the .NET 4.5.1 and authorizing the code is as follows:
...
var service = new FusiontablesService(new BaseClientService.Initializer
{
ApplicationName = "Fusion Tables Sample",
HttpClientInitializer = Utils.Google.GetCredential().Result
});
...
public static async Task<UserCredential> GetCredential()
{
using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
{
return await GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
new[] { FusiontablesService.Scope.Fusiontables },
"XXXXXXXXXXXX[user]", CancellationToken.None);
}
}
Seems you need a service account that can be created from Google "IAM and Admin' Console: https://console.cloud.google.com/iam-admin/serviceaccounts. Once the service account is created, save its private key locally (preferably as JSON-file) and then create BaseClientService.Initializer from the credentials obtained from this file. Something like:
var scopes = new[] { FusiontablesService.Scope.Fusiontables };
using (var stream = new FileStream(keyFilePath, FileMode.Open, FileAccess.Read))
{
return GoogleCredential.FromStream(stream)
.CreateScoped(scopes);
}
Having such Initializer, just create the instance of FusiontablesService almost as you did:
service = new FusiontablesService(
new BaseClientService.Initializer()
{
HttpClientInitializer = creds,
ApplicationName = "Street Parking",
});

Categories