8

What I'm trying to do is to authenticate my Android app to the Google Cloud Endpoint. Basically the endpoints should only allow my Android app to access the methods and nothing else.

I have done these things -

  1. Create a client id using my SHA1 value in Eclipse in the Google Cloud Console.

  2. Create a web client id in the Google Cloud Console for my endpoint project.

  3. Add both these client id's in the "@Api" mentioned on each endpoint.

  4. Add an extra "user" parameter in the endpoint methods.

  5. Regenerate and deploy the backend to the cloud.

But when I'm running this the "user" is always coming as "null". I'm at my wits end trying to find a proper working method for doing all this.

I've searched many forums but no proper answers anywhere.

Here's another similar post Restrict access to google cloud endpoints to Android app

This is the reference I'm using - https://developers.google.com/appengine/docs/java/endpoints/auth

Has anyone here done this before? My main goal is to not allow unauthenticated apps and outside world to access the endpoints, for obvious security reasons. I don't want to use end-user based authentication since I want to keep my app very simple.

Community
  • 1
  • 1
user3034970
  • 171
  • 1
  • 8
  • Did you ever get this working as desired? I'm facing the same problem. – myanimal Jun 08 '14 at 00:55
  • This was a long time back, but if I remember correctly the short answer was "no" you cannot do a "allow just my app" thing unless you have a user being sent alongwith it.. If you had a user also being sent everything works perfect...and with IOS and Cloud endpoints it got even weirder .. I just moved away from GCL in the end – user3034970 Jun 09 '14 at 07:30
  • Any news info on this? I really am trying to do the same thing... – Micro Aug 09 '15 at 23:42
  • Not working on this anymore so no new info – user3034970 Aug 11 '15 at 09:09

3 Answers3

0

It sounds like it's working as intended. You control which client apps can call your endpoint methods via the client IDs as you have already done. The User parameter is coming in as null precisely because you aren't doing end-user authentication. The User parameter represents an actual real user (Google Account). So if you don't need end-user authenticated methods, you can just simply not define the User parameter, or else ignore the null value. You said your problem is that the User parameter is set null. What are you expecting it to be in this scenario?

Preston Landers
  • 460
  • 7
  • 18
  • 4
    even if we forget about the user coming as null, i noticed an invalid client app is also allowed access to enter the api methods. I tested this out by creating an invalid android client key (based on a sha1 that is not of my client) and adding that to the app engine backend.Meaning my app's key should not be valid to access the app engine anymore now.Then i ran the test but even then my app which has a diffrent sha1 is still able to accesss the methods and execute them. So basically api method access is allowed even if the keys dont match. – user3034970 Dec 06 '13 at 07:05
  • or is it something i need to do at the client end differently to get this "only app auth" scenario working. Currently my client code just calls the endpoint same as a normal app without auth. Do I need to send some dummy credential from the client ? – user3034970 Dec 06 '13 at 07:09
  • You didn't specifically say whether you removed the old keys, just that you added the new key. Assuming you removed the old keys from the API annotation, did you deploy to the live server or are you testing with the dev server? Did you regenerate the API discovery doc? (I'm not sure if that matters.) Have you tried accessing this API from Google's API explorer? If so, what happens when you remove the API Explorer key? – Preston Landers Dec 11 '13 at 16:25
0

You need to call authenticate on the client, then possibly the library you're using will 'inject' the user information.

0

Here's what worked for me :

Let's say you have the keys below :

static final String WEB_CLIENT_ID = "somekeyfor webclientid.apps.googleusercontent.com";

static final String ANDROID_CLIENT_ID = "somekeyfor androidclientid.apps.googleusercontent.com"; static final String ANDROID_AUDIENCE = WEB_CLIENT_ID;

Your Api anotation should look like this :

@Api(
        name = "yourapiname",
        clientIds = {CloudEndpoint.WEB_CLIENT_ID,CloudEndpoint.ANDROID_CLIENT_ID},
        audiences = {CloudEndpoint.ANDROID_AUDIENCE},
        version = "v1",
        namespace = @ApiNamespace(
                ownerDomain = "myapp.app.com",
                ownerName = "myapp.app.com",
                packagePath = ""
        )
)

In the annotation below, notice how your audience is the variable --> ANDROID_AUDIENCE which is equal to WEB_CLIENT_ID.

Now in your app side, when you create the googleAccountCredential object, you should pass in the Web Client Id like this :

mAccountCredentials = GoogleAccountCredential.usingAudience(getApplicationContext(),"server:client_id:" + "yourwebclientID");

Note that even if this is properly done, your user object in the endpoint might still coming out as Null if the account name you pass in mAccountCredentials.setSelectedAccountName("accontname") does not exist in the device. Therefore make sure the account name you pass does exist in the Android device by going to --> (Settings/Accounts)