Authentication using Google OAuth2 from MVC5 Website Failing (GetExternalLoginInfo always null) - asp.net-mvc

I’m following these instructions to create a simple MVC5 website that allows external authentication using Google and Facebook via OAuth2:
http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on
I'm using Visual Studio 2015 Professional, targeting .Net 4.5.2, and all my nuget packages are up to date with the latest stable builds (as of 08/18).
Additionally, my project’s been set up to use https/SSL throughout.
I’ve got to the section ‘Creating a Google app for OAuth 2 and connecting the app to the project’ and have created a sample Web Application project in the Google developer console, with the Google+ API enabled - my list of enabled APIs are:
BigQuery API
Cloud Debugger API
Debuglet Controller API
Google Cloud Logging API
Google Cloud SQL
Google Cloud Storage
Google Cloud Storage JSON API
Google+ API
... basically the default ones with Google+ added.
I’ve added the Authorized redirect URI (https://localhost:44300/signin-google) Authorized Javascript origins (per previous with /signin-google removed) and to the Google project. I’ve also set a product name in the OAuth Consent Screen (but nothing else apart from my email).
I’ve not touched the generated code in the solution, other than to do the following:
In Startup.Auth.cs, uncomment the app.UseGoogleAuthentication section and add the client ID and secret from the Google project (Credentials section)
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = "xxxxx.apps.googleusercontent.com",
ClientSecret = "xxxxx"
});
Added Session["Workaround"] = "workaround"; to AccountController in the Post version of ExternalLogin
So I run the application and attempt to login via Google (using the button that appears on-screen). I get taken to enter my Google credentials, which I do successfully. However, on returning to my application what I’m seeing is:
The querystring returned from Google has error=access_denied attached to it (confirmed via Fiddler)
(Consequently?) the call to AuthenticationManager.GetExternalLoginInfoAsync(); in AccountManager always returns null, and I’m redirected to the login page again
I therefore never get the chance to associated the Google login with my application
I’ve also noticed in the Google developer console that there are zero default quota requests, and zero sign-in quota requests in the Google+ API usage section (even though I’ve been hammering this over the last couple of days).
I don’t know what to try next. I've taken a tour of the web looking at this and almost everything I’ve read has said that enabling the Google+ API, and/or setting a placeholder in the session should solve this, but neither option has worked for me.
Any ideas welcome.
Thanks
fiveeuros

So - I should have mentioned that I'm doing this at work, and sitting behind my corporate firewall.
Because this is what's causing the issue.
Further examination of the Fiddler logs showed a whole bunch of 407 Proxy Authentication Required responses.
So I deployed the app to Azure without making any code changes (I did change the google credentials to add the Azure URIs), and it worked straight up.
There are a bunch of other things to workaround with the proxy (remote debugging the Azure app, or connecting to the Azure database from my local SQL Server), but they're for me and the firewall team to work out. What I'm doing is really at conceptual stage so I can live with it as it is for now.
//fiveeuros

Related

Setting up oAuth with the Google AdWords API

I am attempting to get get a Ruby on Rails project that uses the Google AdWords API.
What I did so far, following the steps in this guide:
I created an AdWords Manager account.
I created a test account that is part of the AdWords Manager account.
I set up the Ruby client library in my Rails project.
I then attempted to set up OAuth2 authentication with the example code from the guide.
However since the guide was written (and the video version of the guide was made) it seems that the interface has changed. I am able to create a Client ID client_secrets.json-file, or a Service Account .json file. I am able to export these and read the settings from .
I added the required settings, using an OAUTH2_SERVICE_ACCOUNT .json file.
Now, when attempting to connect, I get back the AdwordsAPIException AuthenticationError.NOT_ADS_USER.
I therefore know that the actual authentication works. However, the authorization does not.
How can I turn on AdWords API support for the oAuth credentials from my google accounts? The Google Credentials Console lists many APIs that you can turn on, but the AdWords API is not in there. The AdWords guide does not mention turning on an API at all, and only tells you to create a new Credential.
What is going on here?
The Adwords API does not need to be added to your project in the Google Cloud console (it's always enabled)—as indicated by the error message, the actual problem lies in the fact that your service account does not have access to any Adwords accounts.
As a matter of fact, the only way to use service accounts to authenticate against the Adwords API is when you're also using a G Suite domain (see the corresponding documentation, section "Prerequisites".
If you have a G Suite domain, you'll need to
Enable "G Suite Domain-wide Delegation" on your service account key
Add the project ID of the Google cloud project to your G Suite domain's authorized API client list
Use your service account to impersonate any user from your G suite domain that has Adwords access
As you can see, it's quite an involved process. My recommendation (that is shared by the above article) is to use an OAuth2 installed application flow for any user that has Adwords access. This requires to store the obtained refresh token on your end, but is more flexible (and arguably safer) than a delegation-enabled service account and easier to set up.

Access Not Configured for Google OAUTH Login

I am building a wordpress woocommerce site and am trying to get the users to login using G+.
Everything was going just fine till I changed the plugin I was using and added new redirect URLs to the OAUTH 2.0 Client ID.
Now the users get the error:
Access Not Configured. Google+ API has not been used in project
1033299751186 before or it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/plus/overview?project=1033299751186
then retry. If you enabled this API recently, wait a few minutes for
the action to propagate to our systems and retry. Please notify about
this error to the Site Admin.
Any help would be appreciated.
Thanks
You need to go to google developer console as it says under the project 1033299751186 and enable the Google+ api.
Your project needs to have each of the different APIs enabled that it needs to access.
Look for API manager -> Enable APIs (its a tab at the top)

Google OAuth2 in distributed, self-hosted packages complaining about redirect_uri

I've taken over development of a Google Analytics API dashboard for a content management platform, and upgraded the code to use OAuth2 as the older oauth was disabled recently. The authentication flow and subsequent API calls are all working fine on my localhost for development.
The problem is when trying the code from a different domain. Google wants the redirect_uri to be whitelisted through the developer console, and if it isn't there, it throws Error: redirect_uri_mismatch
As this is a self-hosted (+ open source) package, people will be able of installing on their own servers, there is no way I'll be able of adding all possible redirect_uri values to the app key in the developer console.
After a bunch of Googling and trying to understand the docs, I get the impression there are 2 possible solutions.
Instruct users to go to the Google Developer console, and to create an app key of their own, before also going through the OAuth2 flow within the distributed app to provide the code access to the data in Google Analytics.
Use a redirect_uri value of urn:ietf:wg:oauth:2.0:oob with an Installed App key, instructing people to copy/paste the code back into the self-hosted app after authentication.
Neither of these are really appealing as it adds a bunch of complexity for the user (though option 2 sounds mostly doable). Are there other options, or am I simply overlooking something simple?
You actually don't have any choice in this matter. You must go with nr 1. When you state this is a dashboard and web application it leads me to believe this is some kind of scripting language. This means that the client id and client secret will be displayed to your users / customers. This is against googles terms of service.
Changes to the Google APIs Terms of Service Asking developers to
make reasonable efforts to keep their private keys private and not
embed them in open source projects.
You may not release your client id and client secret to your users they are going to have to create there own. Which nicely solvers your redirect URI problem they have to make there own.
Further reading Can I really not ship open source with Client ID?

Google Places API: iOS key: Request Denied [duplicate]

I'm trying to make an Autocomplete field which should fetch cities as the user types, by using the Google Places API as described in this tutorial:
https://developers.google.com/places/training/autocomplete-android
You've probably found this question around many times before as I did, but none of the answers helped me. Here are the things you should know:
The URL is
https://maps.googleapis.com/maps/api/place/autocomplete/json?sensor=false&key=myKey&components=country:ro&input=whatTheUserTypes
Please don't reply by saying you replaced the API key with your own and it worked - the API key which goes there must be Android specific and won't work from a browser.
So did I make the Android API key using the SHA1 fingerprint obtained from the keystore I signed the app with.
I turned on Maps and Places APIs from the console.
The quota isn't exceeded.
All those and it still gives me REQUEST_DENIED
What I didn't mention is that I have O2Auth activated - does that change anything? Shouldn't it be as simple as putting the API key in the app?
Thanks!
Although this has been answered, I think the community could do better.
I was tearing my hair out about this, it just didn't make sense to me.. I was making an iOS/Android App, so I made an iOS/Android Key...
Wrong.
With Google's Places API, your bundle identifier isn't even considered.
What you really want to do is this:
(I'm using the new User Interface)
1. Log into https://cloud.google.com/console#/project
Select your Project Name, then go into API's & Auth > APIs
Make sure you have Places API Turned on. This is the only thing that needs to be turned on for Places-API to work.
2. Go into Credentials
Click CREATE NEW KEY under Public API Access
3. Select BROWSER KEY
4. Click Create, Nothing Else
Leave the HTTP Refer box empty.
5. Use the Key Generated here
This key will allow ANY user from any device access to the API via your Developer login.
You can try it out here: (Be sure to replace YOUR_KEY_HERE with your generated Key)
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=Food%20Sh&sensor=false&radius=500&location=0,0&key=YOUR_KEY_HERE
6. Enjoy
Now you can use that URL above in your Android/iOS device.
The Google Places API does not currently support Android or iOS keys generated from the Google APIs Console. Only Server and Browser keys are currently supported.
If you would like to request this support, please file a Places API - Feature Request.
https://developers.google.com/places/training/autocomplete-android
Storing your API key
Although the above code demonstrates how to communicate directly
between an Android app and the Places Autocomplete service, you should
not store your Places API key with your app.
You should therefore build a web application that stores your API key
and proxies the Places API services. In order to secure communication
between your Android app and the proxy web service, you should require
user authentication to your proxy web service. Your Android app can
securely store user credentials and pass them to your web service, or
the user can log into your web app via an Android WebView.
For the latter approach, your web app should create and return a user
authentication token to your Android app, and your Android app should
subsequently pass this token to your proxy web service.
Go to google cloud platform console>Credentials click on edit by selected your YOUR_API_KEY>Application restrictions > select none option>save thats it.
If you select the android apps option from Application restrictions then google deny the place API with exception REQUEST_DENIED.
In Google dev console, you should be able to find both "Places API" and "Places API for Android"
Make sure to use "Places API for Android"
For some reason, "Places API for Android" is hidden in the API list, but can be accessed using search.
I had the same issue , I fix it by leaving
Accept requests from these HTTP referrers (web sites) (Optional)
in browser key Empty
I am still new, so I cannot comment, but to shed some light on Moe's answer, I resolved some similar Google Maps API issues regarding URL queries (for directions, using Volley) with the following steps:
Get Android API Key (including Google Maps Directions API in my case).
Get "Server" API Key (which seems to be created by using a key restriction of "HTTP referrers" these days - really, it's just used to issue URL queries through HTTP).
Store the Android API key as a meta-data tag in the application tag in AndroidManifest.xml with android:name="com.google.android.maps.v2.API_KEY" and android:value as your key. This is used for direct interaction with the Maps API (minus URL queries).
Use the server API key whenever issuing URL queries.
I am not sure if this also applies to URL queries for the Places API, if you only need the server API key, or if there is a better solution, but this worked for me.
I imagine that it works with just the first key - the one not restricted to Android.
Inside Google Cloud Console type Places and Activate it. Create an API Key and insert it onto your Android Studio App as you would do normally. That`s it.
I had the same problem. For me the key was to enable billing on project. I am still using "Applications for Android" restrictions. After setting up the payment method, Places Api started working.
Prior to using the Places SDK for Android, do the following:
Follow the Get an API Key guide to get, add, and restrict an API key.
Enable billing on each of your projects.
Enable the Places API for each of your projects.
See it there.
Be sure also to check out the billing plans for the Google Places API as it is not free!

Google APIs Console - missing client secret

I tried to create a testing client id for an android app which uses OAUTH 2.0 as login for retrieving user profile. I followed the steps to complete the creation of the client id on google console, but I do not see anywhere the client secret. I'm trying to help my employer with getting google credentials for it's app. I know how to implement OAUTH 2.0 in android, but I need client secret to exchange the code with access token.
First, I selected "Google+ API" from Services tab.
Then followed the on screen steps from API Access tab.
It seems that Google finally ditched the unnecessary client_secret for installable applications and is not yet up-to-date with their documentation.
You should check if you already get an access_token in the initial OAuth request like it's handled on Facebook.
Another possibility would be to fall back to using a Simple API Access key.
Update:
First method seems to not work with Google.
The recommended way for Android is to use AccountManager instead of baking your own requests. Follow this example to see how this is implemented and how you get an AuthToken using a Simple API Access key. Instead of using the Tasks API you can then include the OAuth2 API library to retrieve the userinfo.
Click on "Download JSON "
Is it what you're looking for ?
Since almost everything from the accepted answer has been deprecated, I thought I'd share what I've found.
I needed the People API which requires a client secret. What Google recommends for using People API with Android is,
Select the application type Other, enter the
name "People API Quickstart", and click the Create button.
Found here: https://developers.google.com/people/quickstart/java
(Step 1 part e)
So if you need a client secret, you might consider using the Other type. Of course, follow the documentation for your specific API first.
Just today I found out that on the new Cloud Console we can see the client secret for android apps - while in the old google console we just can't.
To use the new Cloud console, just click on the message "We are improving the experience. Try the new Cloud Console." Google will ask for a SMS confirmation. Now you'll be redirected to the new cloud console
Now, just select your project, click on "Registered Apps" on the left menu, selected your android app, and voilá, on oAuth 2.0 Client Id you'll see your client secret. No idea why on the old google console it's not displayed, but if you really need a client secret key, it's there.
Now that the type Other is unavailable, I used type Desktop since I wish to upload using Visual Studio which is a Desktop app. That worked, I got the client id and client secret.
When you update any changes in the credential, make sure you could see the client ID and secret in the dashboard before downloading.
Google cloud takes at the least 10 seconds to regenerate the client id and add it in the json.
Once json is downloaded you can check for client_secret to be present.
source said that :
Visit the Google Developers Console to obtain OAuth 2.0 credentials such as a client ID and client secret that are known to both Google and your application. The set of values varies based on what type of application you are building. For example, a JavaScript application does not require a secret, but a web server application does.
Another solution is that you have to create a client ID with the type of "Installed Application" then you will have the Client secret

Resources