Google consent screen not showing up while integrating Google Drive - c#

I am having trouble integrating Google Drive in my ASP.NET web application. It is not showing up the consent screen where user can enter his/her Google credentials to authorize my application.
Below is my code:
String CLIENT_ID = "XXXXXX";
String CLIENT_SECRET = "XXXXXX";
String APP_USER_AGENT = "<Application - Name>";
string[] scopes = new string[] { DriveService.Scope.Drive };
DriveService service=null;
try
{
var dbDataStore = new DatabaseDataStore("<DBServer>", "<DBUser>", "<Pwd>", "<DataBase>");
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = CLIENT_ID, ClientSecret = CLIENT_SECRET },
scopes, Convert.ToString(Session["UserId"]), CancellationToken.None, dbDataStore).Result;
service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = APP_USER_AGENT,
});
}
catch (Exception ex)
{
}

My understanding for every google api calls we should get permission
https://developers.google.com/identity/protocols/OpenIDConnect#consentpageexperience
You could use https://admin.google.com/AdminHome?chromeless=1#OGX:ManageOauthClients for overriding the permission

Related

How to refresh a Google OAuth2 AccessToken

I have seen a lot of questions about this with varying answers. Some are for different languages. It is not clear to me the correct way to handle this issue.
This is what I have come up with:
public bool Init()
{
UserCredential credential;
ClientSecrets secrets = new ClientSecrets()
{
ClientId = m_ClientID,
ClientSecret = m_ClientSecret
};
if (!m_LogFilePathSet)
return false;
try
{
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
secrets,
m_Scopes,
"user",
CancellationToken.None,
new FileDataStore("MSAToolsSoftware.GMail.Application")).Result;
if (credential.Token.IsExpired(Google.Apis.Util.SystemClock.Default))
{
var refreshResult = credential.RefreshTokenAsync(CancellationToken.None).Result;
}
var initializer = new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = m_ApplicationName
};
m_Service = new GmailService(initializer);
}
catch(Exception ex)
{
SimpleLog.Log(ex);
return false;
}
return true;
}
Is this the correct way to refresh the access token (if required)?
Thank you.

Google APIs - Calendar API is working but Gmail API returns ''unauthorized_client"

I have a project in Google Apps for which I've enabled Calendar API and Gmail API (generated a '.p12' key for server-to-server authentication). I've managed to read/write my Google Calendar account with the following:
private CalendarService GetCalendarService()
{
var certificate = new X509Certificate2(_googleCredentialsFilePath, "notasecret", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
var serviceEmail = "599172797645-dthli52ji7j0j53gacmqigvs694bu7vs#developer.gserviceaccount.com";
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceEmail)
{
Scopes = new[] { CalendarService.Scope.Calendar, CalendarService.Scope.CalendarReadonly }
}.FromCertificate(certificate));
var applicationName = ConfigurationManager.AppSettings["ApplicationName"];
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = applicationName,
});
return service;
}
With the service object I can create events in my calendars like so:
var newEvent = new Event()
{
Summary = calendarEvent.Summary,
Description = calendarEvent.Description,
Start = new EventDateTime()
{
DateTime = calendarEvent.StartDateTime,
TimeZone = _ianaTimezone,
},
End = new EventDateTime()
{
DateTime = calendarEvent.EndDateTime,
TimeZone = _ianaTimezone,
}
};
var request = _calendarService.Events.Insert(newEvent, googleCalendarId);
var result = request.Execute(); // CREATE EVENT SUCCESSFULLY
Now, for the Gmail API client I'd like to send emails using the service account owner email (the same I use to login Google Dev Console -- "mypersonalemail#gmail.com"
private GmailService GetGmailService()
{
var certificate = new X509Certificate2(_googleCredentialsFilePath, "notasecret", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
var serviceEmail = "599172797645-dthli52ji7j0j53gacmqigvs694bu7vs#developer.gserviceaccount.com";
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceEmail)
{
Scopes = new[] { GmailService.Scope.MailGoogleCom, GmailService.Scope.GmailCompose, GmailService.Scope.GmailModify, GmailService.Scope.GmailSend },
User = "mypersonalemail#gmail.com"
}.FromCertificate(certificate));
var applicationName = ConfigurationManager.AppSettings["ApplicationName"];
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = applicationName,
});
return service;
}
But when I try to test this client requesting the list of drafts:
ListDraftsResponse draftsResponse = _gmailService.Users.Drafts.List("mypersonalemail#gmail.com").Execute();
Then I get the error:
"Error:\"unauthorized_client\", Description:\"Unauthorized client or scope in request.\", Uri:\"\"" string
I've logged in to Google Developers Console with mypersonalemail#gmail.com and in
API Manager > Permissions > Add service account owner added "mypersonalemail#gmail.com" as the service email owner (probably redundantly)
Do I need a Google Apps for Work to send/read emails from my own gmail account via service account? My app is currently hosted in Azure as a web application.
Check This
And make sure that you access the google.Admin account for referencing the service account Client ID of the app you created and the time zone is in the following format "America/Phoenix".

youtube Add Subscription via C#

I am building a YouTube app for windows 8.1.
I am having a trouble with, add(Insert) subscription is fail
my code:
var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
new Uri("ms-appx:///Assets/client_secrets.json"),
new[] { Uri.EscapeUriString(YouTubeService.Scope.Youtube) },
"user",
CancellationToken.None);
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
HttpClientInitializer = credential,
ApplicationName = "AppName"
});
Subscription body = new Subscription();
body.Snippet = new SubscriptionSnippet();
body.Snippet.ChannelId = "UC-kezFAw46x-9ctBUqVe86Q";
try
{
var addSubscriptionRequest = youtubeService.Subscriptions.Insert(body, "snippet");
var addSubscriptionResponse = await addSubscriptionRequest.ExecuteAsync();
}
catch (Exception e)
{
throw e;
}
When I set a breakpoint at the first line.
when execute to last line, breaks this function
Update(2015-11-14):
Error Message:
The subscription resource specified in the request must use the snippet.resorceId property to identify the channel that is being subscribed to [400]
Successful Code:
var credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
new Uri("ms-appx:///Assets/client_secrets.json"),
new[] { Uri.EscapeUriString(YouTubeService.Scope.Youtube) },
"user",
CancellationToken.None);
var youtubeService = new YouTubeService(new BaseClientService.Initializer()
{
//ApiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
HttpClientInitializer = credential,
ApplicationName = "4GameTV"
});
try
{
Subscription body = new Subscription();
body.Snippet = new SubscriptionSnippet();
body.Snippet.ResourceId = new ResourceId();
body.Snippet.ResourceId.ChannelId = "UC-kezFAw46x-9ctBUqVe86Q"; //replace with specified channel id
var addSubscriptionRequest = youtubeService.Subscriptions.Insert(body, "snippet");
var addSubscriptionResponse = await addSubscriptionRequest.ExecuteAsync();
}
catch (Exception e)
{
throw e;
}
Your authentication seems a bit off from what I normally use. Also ApiKey is only needed if you want to access public data.
string[] scopes = new string[] { YouTubeService.Scope.Youtube };
// 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 = clientId, ClientSecret = clientSecret }
, scopes
, "test"
, CancellationToken.None
, new FileDataStore("Daimto.YouTube.Auth.Store")).Result;
YouTubeService service = new YouTubeService(new YouTubeService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "YouTube Data API Sample",
});

GoogleWebAuthorizationBroker.AuthorizeAsync throws an error

i was trying to create and run the sample project given in this link.
here is the code:
namespace GmailQuickstart
{
class Program
{
static string[] Scopes = { GmailService.Scope.GmailReadonly };
static string ApplicationName = "Gmail API Quickstart";
static void Main(string[] args)
{
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");
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
"user",
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
// Create Gmail API service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
// Define parameters of request.
UsersResource.LabelsResource.ListRequest request = service.Users.Labels.List("me");
// List labels.
IList<Label> labels= request.Execute().Labels;
Console.WriteLine("Labels:");
if (labels != null && labels.Count > 0)
{
foreach (var labelItem in labels)
{
Console.WriteLine("{0}", labelItem.Name);
}
}
else
{
Console.WriteLine("No labels found.");
}
Console.Read();
}
}
}
after i have done everything stated in google's documentation, including issuing a secrets.json file for my application/product, i ran it.
It fails with an exception, containing a "An invalid argument was supplied" inner exception.
I have retried everything with a new acocunt given new api credentials, etc., and still same error occurs. what am i doing wrong?
Try this
ClientSecrets secrets = new ClientSecrets()
{
ClientId = CLIENT_ID,
ClientSecret = CLIENT_SECRET
};
var token = new TokenResponse { RefreshToken = REFRESH_TOKEN };
var credentials = new UserCredential(new GoogleAuthorizationCodeFlow(
new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = secrets
}),
"user",
token);
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credentials,
ApplicationName = "ApplicationName"
});

Google api authorization raises the browser

I'm writing a small desktop app that will upload file to google drive. So everything is fine when I'm sign in my google account, but when I'm not, program raises browser on this page "https://accounts.google.com/ServiceLogin". I'm using this code:
ClientSecrets secret = new ClientSecrets();
secret.ClientId = "my_client_id";
secret.ClientSecret = "my_client_secret";
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(secret, new[] { DriveService.Scope.Drive }, "user", CancellationToken.None).Result;
var service = new DriveService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "TestUpload" });
File body = new File();
body.Title = "Title123";
body.Description = "Decription123";
body.MimeType = "image/png";
byte[] arr = System.IO.File.ReadAllBytes(fileName);
System.IO.MemoryStream stream = new System.IO.MemoryStream(arr);
FilesResource.InsertMediaUpload request = service.Files.Insert(body, stream, "image/png");
request.Upload();
So how can I authorize programmatically with out raising the browser?
Most of your problem is the fact that you are not saving the Authentication. You are requesting access but not saving it. In the following example fileDataStore stores the authentication information in a file on your pc in %AppData% this way next time you run the program no authentication will be needed, and it also wont require that you are logged into Google at the time.
//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
,Environment.UserName
,CancellationToken.None
,new FileDataStore("Daimto.GoogleDrive.Auth.Store")
).Result;
DriveService service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Drive API Sample",
});
public static File uploadFile(DriveService _service, string _uploadFile, string _parent) {
if (System.IO.File.Exists(_uploadFile))
{
File body = new File();
body.Title = System.IO.Path.GetFileName(_uploadFile);
body.Description = "File uploaded by Diamto Drive Sample";
body.MimeType = GetMimeType(_uploadFile);
body.Parents = new List<ParentReference>() { new ParentReference() { Id = _parent } };
// File's content.
byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
System.IO.MemoryStream stream = new System.IO.MemoryStream(byteArray);
try
{
FilesResource.InsertMediaUpload request = _service.Files.Insert(body, stream, GetMimeType(_uploadFile));
request.Upload();
return request.ResponseBody;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
return null;
}
}
else {
Console.WriteLine("File does not exist: " + _uploadFile);
return null;
}
}
This code is ripped from the Google Drive C# upload tutorial, if you want more information on what its doing and how it works you may want to check that. There is also a working Sample project in the Google-Dotnet-Samples project on GitHub. The tutorial is based upon that sample project.

Categories

Resources