appengine access via oauth2 python script (replacing ClientLogin) - google-app-engine

I have an App Engine project which:
uses google.appengine.api.get_current_user() to handle users (and login:required)
has a URL to collect some data (which requires login)
has Google users but on a custom domain
I used to have a script to pull the data using the old https://www.google.com/accounts/ClientLogin interface, but now that interface is deprecated, I'm trying to work out what I need to do to get OAuth2 working to access my App Engine URL with a user value set.
I have worked my way through OAuth2 for devices to get myself an access key for my script (i.e. I can run it, authenticate in a web browser, then poll for the access key), as described in OAuth2 For Devices.
But I'm not sure:
what scope I should be using to request the access_token compatible with get_current_user(),
how to pass this in my request to App Engine so that it can create the the user header, and
whether I need to modify my app to use this access_token, eg adding callbacks etc
With regards to the last point, user was set by google's front end infrastructure so I’m hoping that that same infrastructure can somehow convert my OAuth access_token into a login name without me needing to update my app to do the callback part, because it should all be in appengine's infrastructure right and user is set before the request comes to my app.

Related

Forwarding OAuth 2 credentials from an authenticated request (in GCP specifically)

I have an AppEngine application that is behind an IAP (identity-aware proxy), so it receives requests that are authenticated and include a JWT token. From the AppEngine application I want to make a request to the Google Sheets API. That also requires an authenticated connection, but given that I want that connection to be made under the same user that accessed the application via the IAP, does anyone know how to create a request from inside the AppEngine application that will forward the token to Google Sheets? Cannot find any information on the subject... I am using Java, so any Java pointers would be appreciated, but general/other language help is good too...
I will describe the 2 approach proposed in the comment
The first one, to reuse the IAP proxy token to access Google Sheet is impossible, and dangerous.
Impossible because you receive an identity token from IAP (at least the requester/browser send an identity token to IAP) and you need an access token to request Sheet APIs.
Dangerous because, if you are able to reuse the IAP token to request the Google Sheet, that means the user is authorized to access to the Google Sheet. And I'm sure that you build an app to prevent any direct access/modification to the Google Sheet.
The second one, is to use a technical account (typically a service account) and generate an access token to access the Sheet API.
This second approach is the best one (don't forget to correctly log the user request and the subsequent sheet API calls in your AppEngine app to have the end to end traceability). BUT, and it's for that you ask this question, it's impossible with the App Engine default service account.
In fact, to access to the Sheet API, you need to scope your access token with the Sheet API. Sadly, you can't do this with App Engine. You can do this with Cloud Run, Cloud Functions, Compute Engine (without the default service account, else you need an extra config to achieve this with the Compute Engine default service account). But not with App Engine.
So, you have 2 solutions:
Either you use another hosting platform (Cloud Run for example), but you loose the IAP capacity (for now)
You continue to use App Engine but you need to request an access token to another service account (it's not required to have a service account key file). You can use the Service Account Credential API for this. I wrote an article on this API
Note: later in 2021, App Engine should be able to accept custom service account, and thus the issue should be solved

Authorizing google cloud endpoints API access without user sign in

I understand how the authorization process with Oauth works but is it somehow possible to authorize my access to my endpoints API without the user having to sign in? So what I'm trying to do is to restrict access to my API so that only certain websites, that I allow, have access to it and no others.
In Google APIs console I have created a 'client ID for web applications'.
In your described use case, the preferred solution is to use OAuth. In following the examples in the documentation, you'll be limiting the web sites (via the "JavaScript origins" value for the keys you obtained in the APIs Console).
Sites not listed in the origins will not be able to display the required authentication prompt (the client ID and origin are checked before Google will provide tokens). Developers will not be able to create their own client IDs with their preferred JavaScript origins, because your backend will be checking the client ID of the request is on a whitelist that is part of your code.

Authenticate to Google AppEngine application which use federated login from Windows Client Application

I'm plan on deploy a Java application to Google AppEngine and use federated login (still experimental according to Google). The application is pretty simple Java EE application which expose RESTful interface for simple CRUD operations.
I then want to be able to authenticate to this application using Windows Client Application written in C#.
I think the application should be able to open a window with a browser in ti which will present the login page of my web application and after successful authentication I should be able to get the login token or a cookie to use in the rest of my HTTP requests.
Is it possible to do such thing using federated login? I've found a post explain how to do it using google proprietary login.
Thank you,
Ido.
I've manage to make this work much easier then I thought it would be.
When I send HTTP request to my web service I get 302 Found response with response header name Location which point to the login page.
I use WebBrowser control, register to it Navigated even and navigate to the URL in the Location header.
When the Navigated even fire I use the code from this answer to get the cookies container.
I check each cookie until I find one with the name ACSID and store it.
For every web request to my service I add cookie name ACSID with the value saved at step 4.
This is not the most secure way of doing this. I will add check for the domain of the cookie but this looks good.

SalesForce to emulate a google session login

I'm pretty new to SalesForce and their Apex language. I've been reading some documentation and tried the integration between Google and SalesForce.
I'm wondering is it possible to emulate an auth token from google to SalesForce?
I'm trying to read a google spreadsheet and then fill up a SalesForce object automatically. The user login will always be the same/universal for this spreadsheet, so I have the credentials required to login.
I am working off of the sample that requires a visualforce, and I'm wondering how would I automatically do the session id token that the google spreadsheet API requires.
Any ideas?
The old-school, hard way would be to send a login() call to the API (available through SOAP messages). Salesforce API is well documented and plenty of examples are available (both in programming languages and for raw XML requests/responses).
But I have no idea what possibilities you have from Google side, if it's only JavaScript then you might not be able to send and retrieve AJAX-like calls to another domain...
Recently another option emerged and that is REST API (no SOAP needed). Looks more promising and easier in my opinion. Quick intro is available here and you'll find more documentation on the bottom of the page.
Last but not least - 2 interesting links:
http://code.google.com/apis/gdata/articles/salesforce.html for some integration tutorial
and built-in integration offered by Salesforce: http://www.salesforce.com/assets/pdf/datasheets/SalesforceGoogleApps.pdf
I've used custom settings to do this. Use OAuth to get a token for Google, then store that token in Salesforce custom settings (Setup-Develop-Custom Settings). You can then retrieve the token for callouts to Google from that custom setting for any user needing access to Google Apps. The downside is, every user will authenticate as your custom setting token user. The upside is that they won't need to individually authenticate. Custom settings are retrievable via Apex using a simple getter, and live as Apex-like objects.
Also keep in mind, Google requires each service to use it's own token. So, if your user wants to use Calendars and Spreadsheets, that's two separate tokens that will need to be stored and retrieved for the callout.
I generally allow users to create their own authenticated session tokens via OAuth if they want to do that, then failover to the custom settings to get the general admin token if necessary.
Are you trying to log into Google Apps from SFDC? There are options for Google Apps within Salesforce, go to Setup > Administration Setup > Google Apps > Settings. I've not used this and it requires some setup, but thought I'd point it out. Aside from that I can only blurt out OAuth (getting users to authenticate with Google from within Salesforce when trying to access Google Apps) and SSO (which I know can be used to authenticate from an external system, though not sure if it works the other way).
Look into the "Named Credentials" menu in salesforce setup.
There, you can store auth credentials for the services accessed via Apex:
"A named credential specifies a callout endpoint and its required authentication parameters. When setting up callouts, avoid setting authentication parameters for each callout by referencing named credentials."
a username/pass combo can be used, or a certificate, or an AWS signature, and there is a JWT option..
Help docs: https://help.salesforce.com/articleView?id=named_credentials_about.htm&type=5

Can I use browser authentication to make RESTful calls to GAE?

We're writing a Desktop application that relies on Google Appengine to authenticate the user and retrieve and store data associated to it.
The way we'd like to authenticate the user is that on launching the application the browser is launched at the login url for our application. Then the user logins there, and then the application makes restful calls without any OAUTH object, but re-using the browser session. I'm questioned that this won't work, since we cannot so transparently use the browser session. Is that correct?
Any alternatives beside authenticating from within the app using the ClientLoginApi?
I'm aware of:
How do you access an authenticated Google App Engine service from a (non-web) python client?
The only way to do this is if you can capture the authentication cookie used by the browser, and send it yourself. Obviously, there's no browser- or platform- independent way to do this.
A better option would be to use OAuth, with OAuth for installed apps to obtain the original token.

Resources