2

I want to secure an API on App Engine, so that it can only be accessed from another server (which is hosted off App Engine).

Google explains this here https://cloud.google.com/appengine/docs/java/endpoints/consume_js#adding_authentication_support_with_oauth_20 but only shows how I can use a client id to secure my API for proprietary access by Android, iOS and Webbrowsers/Javascript gapi.

I assume that if I want to access the API server-to-server using REST, I will need to create a "Client ID for web application" in the App Engine console, then specify the client id in the endpoint annotation...

@Api(
        name = "api",
        description = "API",
        namespace = @ApiNamespace(ownerDomain = "domain.com", ownerName = "Ownername")
        clientIds = { "clientidgoeshere" }
)

... and add the user parameter to the endpoint:

public void restMethodName(

        @Named("serverurl") String serverUrl, // whatever parameters

        final com.google.appengine.api.users.User auth
) throws ServiceException, OAuthRequestException {
    if (auth == null) throw new OAuthRequestException("Unauthorized error message.");

// ...

}

I believe this is fine so far. If the server-side implementation is incorrect, tell me why.

Now my problem: I don't have any idea how I must prepare and pass the user parameter to the App Engine cloud endpoints framework for authentication.

I am looking for a solution which I can generically use from any language, without using the generated Cloud Endpoints jar library which is typically used on Android, only.

Please describe what I need to wrap or sign (probably the client secret) and where I need to place it in my https request (probably in the parameters), or tell me where the whole Cloud Endpoints security workflow is properly documented.

Oliver Hausler
  • 4,900
  • 4
  • 35
  • 70
  • How are you using the Cloud Endpoints client library for accessing your App Engine app from an external server? Is there a guide for this use case? – Price Feb 01 '15 at 07:24
  • I am accessing App Engine from another server via REST, any library that speaks https, nothing specific. – Oliver Hausler Feb 01 '15 at 15:01

1 Answers1

1

You should create a Client-Id for web applications from the Developer Console based on the SHA fingerprint of the system on which you are building the application that is hosted on an external server.

Then include it in the list of allowed Client-Ids for an endpoint API method to allow the external application to access your endpoint API using the @apiMethod annotation before the method definition:

@ApiMethod(name = "myEndpointMethod",
        clientIds = {"clientid1", "clientid2"})

public void myEndpointMethod(){
...
}

If you want to authenticate another App Engine application, you can check the Application ID of an incoming request by reading the X-Appengine-Inbound-Appid header and comparing it to a list of IDs allowed to make requests.

EDIT: It seems that it may be possible to use the User object injected by App Engine in the endpoint method to authenticate non-Google account users as well, but I have never done this.

Price
  • 2,683
  • 3
  • 17
  • 43
  • According to this `http://stackoverflow.com/questions/25365858/google-cloud-endpoints-and-users-authentication` I can use Users API to authenticate anything. Not very well documented elsewhere, but it is possible to grab the User object and do my own authentication by implementing Authenticator. Less documented, there also is a class called PeerAuthenticator. – Oliver Hausler Feb 01 '15 at 14:59
  • Just realized the link has accidentially been converted to text. Here's the same link again, clickable: http://stackoverflow.com/questions/25365858/google-cloud-endpoints-and-users-au‌​thentication – Oliver Hausler Feb 01 '15 at 21:07