Google OAuth on Windows Phone Fails - c#

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?

Related

HttpListenerException "access is denied" using GoogleWebAuthorizationBroker.AuthorizeAsync

I'm trying to do OAuth2 using Azure hosted web apps, and I can't use service accounts (there is a number of solutions available here, but they all stick to service accounts/certs), while I need the user to authenticate and authorize by Google.
Code:
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets { ClientId = _clientId, ClientSecret = _clientSecret },
scopes,
User.Identity.Name,
CancellationToken.None,
new FileDataStore("GA.Auth.Store")) /* tried this to be null as well */
.Result;
var service = new AnalyticsService(
new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Analytics API Sample"
});
It works locally but gives this exception when deployed as an Azure web app:
[HttpListenerException (0x5): Access is denied]
Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +82
Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task) +76
Google.Apis.Auth.OAuth2.<AuthorizeAsync>d__1.MoveNext() +233
I am guessing that GoogleWebAuthorizationBroker.AuthorizeAsync is trying to establish an http listener which is not (?) possible within Azure web apps.
I tried using Azure web apps authentication. This does authenticate user, but how can I retrieve the authenticated user to authorize him against Google?
BTW: Because I need GA Real-Time, I am stuck with GA Reporting v3 library.
GoogleWebAuthorizationBroker.AuthorizeAsync is designed for installed applications it will not work hosted as it will attempt to open the web browser window for consent on the server.
You should be following the web example.
public void ConfigureServices(IServiceCollection services)
{
...
// This configures Google.Apis.Auth.AspNetCore3 for use in this app.
services
.AddAuthentication(o =>
{
// This forces challenge results to be handled by Google OpenID Handler, so there's no
// need to add an AccountController that emits challenges for Login.
o.DefaultChallengeScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
// This forces forbid results to be handled by Google OpenID Handler, which checks if
// extra scopes are required and does automatic incremental auth.
o.DefaultForbidScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme;
// Default scheme that will handle everything else.
// Once a user is authenticated, the OAuth2 token info is stored in cookies.
o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogleOpenIdConnect(options =>
{
options.ClientId = {YOUR_CLIENT_ID};
options.ClientSecret = {YOUR_CLIENT_SECRET};
});
}

.NET gmail API Authentication (without user interaction)

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);

Get UserCredential of Google Drive API using Refresh token, ClientId and ClientSecret in ASP.net/C#

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.

c# Google Calendar API V3 is ignoring my other account (multiple account authorization)

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

Google Sign-in in ASP.Net MVC Application to use Gmail API

I have followed the tutorial from here to Sign-in with Google and access GMail API within an ASP.Net MVC application.
But at this line my program is stuck, i mean there is no response, i suppose from google server.
var result = await new AuthorizationCodeMvcApp(this, new AppAuthFlowMetadata()).
AuthorizeAsync(cancellationToken);
I have no idea why it is taking time to Authorize the user request.
The main issue is with the async and await keywords. These
keywords though supported in VS2010 as CTP, don't actually work in VS
2010 with .Net Framework 4.
These keywords are released finally with .Net Framework 4.5 and
fully support VS 2012.
Hence to make this work, I have to port my solution to VS 2012.
Pretty simple solution, i guess, i should have figured out earlier :(
I'm not sure what your particular issue is. I've used the following to access the Gmail API.
// Create OAuth Credential.
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "CLIENT_ID",
ClientSecret = "CLIENT_SECRET"
},
new[] { GmailService.Scope.GmailModify },
"me",
CancellationToken.None).Result;
// Create the service.
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Draft Sender",
});
ListDraftsResponse draftsResponse = service.Users.Drafts.List("me").Execute();
IList<Draft> drafts = draftsResponse.Drafts;

Categories

Resources