GAE detect running place at localhost or appspot - java

I have GAE Application. It uses Oauth 2.0 protocol. I use Java library at the moment.
At the moment, I manually switch the redirect URL.
When I'm testing on localhost I use localhost:8888/oauth2callback
And when I deploy app, I set example.appspot.com/oauth2callback.
So how can I detect, if the app is running on the localhost or is deployed ?

As per the documentation, you can do the following
You can check the value of the System property com.google.appengine.runtime.environment to determine if it is "Production" or "Development".
Sample code from docs:
if (SystemProperty.environment.value() ==
SystemProperty.Environment.Value.Production) {
// The app is running on App Engine...
}
and so on.
On the Python side of things, check out the following documentation snippet:
SERVER_SOFTWARE: In the development web server, this value is "Development/X.Y" where "X.Y" is the version of the runtime. When running on App Engine, this value is "Google App Engine/X.Y.Z".

You can use oAuthService methods to detect localhost environment
OAuth for Java Overview
[...]
On the local development server, oauth.getCurrentUser() always returns
a User object with email set to "example#example.com" and user ID set
to 0 regardless of whether or not a valid OAuth request was made.
[...]

Related

How to add service account credentials to Google App Engine when debugging with IntelliJ IDEA?

I am developing a Google App Engine (Standard environment) application which uses Google Cloud Storage. I have used App Engine APIs for Cloud Storage until now, which provides a local emulation for the Cloud Storage using Datastore. As those APIs are getting obsolete now, I have decided to use the recommended APIs, however I am struggling with the credentials when running on the Local Server (I am already using the new Cloud Code plugin, not the old App Engine one).
I have created a service account and I have created and downloaded the key for it. If I would be running a normal Java app, I would be able to specify enviroment variables for the VM and I could provide the necessary -DGOOGLE_APPLICATION_CREDENTIALS=xxxxx.json parameters. The server provided by the Cloud Code does not seem to have any way how to provide environment variables, I can only provide VM options, therefore I do not know how can I provide the necessary environment to it, or how to pass the credentials to it in some other way. The only way I got it kind of working was using
gcloud auth application-default login
which has saved credentials in D:\Users\xxxx\AppData\Roaming\gcloud\application_default_credentials.json. This works, but any time I am debugging my application, I get following warning:
com.google.auth.oauth2.DefaultCredentialsProvider warnAboutProblematicCredentials
WARNING: Your application has authenticated using end user credentials from Google Cloud SDK. We recommend that most server applications use service accounts instead. If your application continues to use end user credentials from Cloud SDK, you might receive a "quota exceeded" or "API not enabled" error.
I am not sure how serious this warning is, but it sure sounds scary to me.
In my application I use this code (Scala, Java would be very similar) to create the service with the credentials:
val credentials = GoogleCredentials.getApplicationDefault
val storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService
What is the proper way to pass service account credentials when running on a local Google App Engine server?
The issue with the big warning is that Google does not want you to use User Credentials in place of Service Account credentials. Google is locking down (restricting) what scopes/data third-party services (you) can request. My advice is to not use User Credentials anymore as they will eventually no longer work.
There are several methods to solve this.
Method 1: Setup the CLI to use a service account:
gcloud auth activate-service-account test#development.iam.gserviceaccount.com --key-file=test_google_account.json
Use the correct email address for the service account. This can be found in the Google Cloud console and also in the JSON file. Google libraries will find these credentials. On my website, I have written several articles on the details of services accounts, Application Default Credentials (ADC), etc.
Method 2: Specify the service account in your code
credentials = GoogleCredentials.fromStream(new FileInputStream(service_account_filename))
Create a flag or environment variable so that your code can if-else decide when running on your desktop to process credentials.
Method 3:
If the system (not the VM command line) environment variable GOOGLE_APPLICATION_CREDENTIALS is set, the libraries will use the filename that the variable points to for service account credentials. This file is a Google Cloud Service Account credentials file in JSON format.
Set this environment variable before you launch your IntelliJ.
My Document Links:
https://www.jhanley.com/google-cloud-application-default-credentials/
https://www.jhanley.com/google-cloud-setting-up-gcloud-with-service-account-credentials/
https://www.jhanley.com/google-cloud-creating-and-authorizing-service-account-credentials-with-the-cli/

Cannot set default App Identity Service Account on Google App Engine for local development

Following this tutorial: https://cloud.google.com/solutions/using-firebase-real-time-events-app-engine#securedata
I've got it working except that when I authenticate the custom token with Firebase, I get the following error:
Error: The custom token format is incorrect. Please check the documentation.
I have isolated the problem to the App Identity token signing. This is because the code works fine deployed to app-engine. It's just an issue when I try on devserver/localhost.
I have following the AppEngine documentation about setting up the default Service Account locally.
Setting the GOOGLE_APPLICATION_CREDENTIALS environment variable to the path of the .json service account keys. I've triple checked the variable is being set.
I tried the alternative method using the gcloud sdk, logging in as my owner account: gcloud beta auth application-default login. Still no luck.
To check I actually changed account, I use this method to get: AppIdentityServiceFactory.getAppIdentityService().getServiceAccountName();. In both configurations I detailed about, this method returns appname#localhost. I was expecting this to be the service account ID given in the .json. ie appname#appspot.gserviceaccount.com.
So I'm a bit at a loss how to debug this problem further, I assume the check I'm doing above is actually proving the validity of the configured service account. Perhaps its something unique to my setup?
Using App Engine Java, latest SDK 1.9.54
Run configuration launched with Maven 3 + IntelliJ
ArchLinux environment

Authentication required pop-up when loading JNLP for internal website

Recently we started to upgrade our clients from Java 6u31 to 8u121.
Here we see an impact on our internal web application written in Java.
Client(s) connects to a web-server which has the JNLP and JARs locally.
However now with the new Java 8u121 we get a pop-up from java : Authentication required.
We can click on cancel and the Java app will load but this is not acceptable for our users.
Is this a Java problem or a Proxy problem?
We started to do a trace with wire-shark to see what happens when the Java pop-up "authentication required" occurs. Here we could see that our proxy server blocks a global-sign site to validate a certificate. Here we made an exception for that site. Now we have no issue anymore and the pop-up is not occurring anymore.
You can prevent that authentication window by setting the property deployment.security.authenticator value to false in the deployment.properties
Normally Plug-in and Web Start install an Authenticator to handle
communication with Authenticating web pages or Authenticating proxies.
This is the default behavior (true). This option can be used to turn
the normal behavior off if, for example, an application communicates
directly with an authenticating web page and needs to install its own
Authenticator.
Location of the deployment.properties
in Windows - \LocalLow\Sun\Java\Deployment\deployment.properties
in Linux - ${user.home}/.java/deployment/deployment.properties
in OS X - ~/Library/Application Support/Oracle/Java/Deployment/deployment.properties

How to integrate google api Spreadsheet callback url on my production server

I am reading data from google spreadsheet API using java. I am able to read on my local machine and the URL getting below for auth2:
https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=679281701678-iacku5po12k0if70abstnthne9ia57kg.apps.googleusercontent.com&redirect_uri=http://localhost:39740/Callback&response_type=code&scope=https://www.googleapis.com/auth/spreadsheets
My callback URL is
http://localhost:62238/Callback?code=4/k6rwrqBFTJ310Yhy9EBpIA7eH9PqL-HXwC3hi9Q0How#
However, when I am deploying my war on the production server so I am not able to see callback function.
If any one knows about this please suggest to me how to integrate on the production server.
Whenever you integrate with any OAUTH enabled google api. You need to provide the restrictions on google dev console like authorized origins and authorized redirect uris. I think you might have provided different port from your local than what is running in your production in your authorized origins, that is why it is not able to connect from your production server but it is able to connect from your local. you can cross check once.

Why is GetServerAuthCodeResult Deprecated? How can I do something equivalent in an Installed Application?

Following this post: http://android-developers.blogspot.com/2016/01/play-games-permissions-are-changing-in.html I have obtained a single use authorization code for use on my backend server as follows:
import com.google.android.gms.games.Games;
//later
Games.GetServerAuthCodeResult result = Games.getGamesServerAuthCode(gameHelper.getApiClient(), server_client_id).await();
if (result.getStatus().isSuccess()) {
String authCode = result.getCode();
// Send code to server...
This seems to works fine, but it presents a question:
1) getGamesServerAuthCode and GetServerAuthCodeResult are marked as deprecated. Why? Should I be using something else instead?
2) How would I do something equivalent in an non-Android installed Java application? I am able to obtain a token on the client application, but I also need to obtain a single use code to pass to my backend server like above. I can't find an equivalent function to get a Server Auth Code. (using com.google.api.client.extensions.java6.auth.oauth2)
I am basically trying to follow this flow: https://developers.google.com/games/services/web/serverlogin but in Java, NOT Javascript. I am attempting to do this in an Android app and a desktop Java app.
1) Yes, in Android use GetServerAuthCodeResult although it is still marked as deprecated. It is the recommended way from Google and it seems they have only forgot to remove the deprecation annotation when releasing to general public.
2) For desktop applications you can follow the instructions here: https://developers.google.com/identity/protocols/OAuth2InstalledApp
Basically from your app you open the system browser (embedded webviews are discouraged) and make a https request to the https://accounts.google.com/o/oauth2/v2/auth endpoint. In the request you supply a local redirect URI parameter i.e. http://127.0.0.1:9004 (you should query your platform for the relevant loopback IP, and start a HTTP listener on a random available port). The authorization code will be sent to your local HTTP listener when the user has given consent or an error such as error=access_denied if the user declined the request. Your application must be listening on this local web server to retrieve the response with the authcode. You also have the option to redirect to a server URI directly claimed by your app, see docs on link above. When your app receives the authorization response, for best usability, it should respond with an HTML page, instructing the user to close the browser tab and return to your app. Also, if you want the Games-scope make sure you are using the https://www.googleapis.com/auth/games as scope in the request, example below, with line breaks and spaces for readability.
https://accounts.google.com/o/oauth2/v2/auth?
scope=https://www.googleapis.com/auth/games&
redirect_uri=http://127.0.0.1:9004&
response_type=code&
client_id=812741506391-h38jh0j4fv0ce1krdkiq0hfvt6n5amrf.apps.googleusercontent.com
Please note that I think you'll have to create and link an app of type other, in the Google Play Developer Console linked-app, for the localhost redirection to work. Use type Web if you plan to redirect to server URI directly, add your server URI to Authorized redirect URIs in the API Manager under section Credentials.
Browser screenshot:
There is finally a proper answer to part 1) of this question!
In the release notes of gms 10.2.0
https://developers.google.com/android/guides/releases#february_2017_-_v102
the new method of obtaining a server code is described. A good example of how to do this is provided here:
https://github.com/playgameservices/clientserverskeleton
I ended up updating Google's baseGameUtils to follow the example above.
Still not sure the proper way to do this for part 2) of the question, at the moment I am sending the token to the server which works but is probably unsafe.

Categories