English

Google App Engine

App Identity Java API Overview

Applications sometimes need to reference their own identity and assert this identity to others. App Engine includes an Application Identity service for this purpose.

Identifying Itself

Application Id

Applications sometimes need to determine the Application Identitifer with which the code is executing. This may be to generate a URL or email address, or possibly to make some run-time decision.

The Application ID can be found in the ApiProxy.Environment.getAppId() method.

Versioned hostnames

A related operation is the need to get the hostname part of a URL to the application. You can use the com.google.appengine.runtime.default_version_hostname attribute of the CurrentEnvironment for this purpose. This is useful in certain scenarios when the application is not available at http://your_app_id.appspot.com.

public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  resp.setContentType("text/plain");
  Environment env = ApiProxy.getCurrentEnvironment();
  resp.getWriter().println("default_version_hostname: "
      + env.getAttributes().get("com.google.appengine.runtime.default_version_hostname"));
}

Asserting Identity to Google APIs

Experimental!

App Identity is an experimental, innovative, and rapidly changing new feature for App Engine. Unfortunately, being on the bleeding edge means that we may make backwards-incompatible changes to App Identity. We will inform the community when this feature is no longer experimental.

Many Google APIs support OAuth assertions to identify the source of the request. The App Identity API provides a service that creates tokens that can be used to assert that the source of a request is the application itself. The getAccessToken() method returns an access token for a scope, or list of scopes. This token can then be set in the HTTP headers of a call to identify the calling application.

The following illustrates a REST call to the Google URL Shortener API. Note that the Google Data Client Libraries can also manage much of this for you automatically.

import com.google.appengine.api.appidentity.AppIdentityService;
import com.google.appengine.api.appidentity.AppIdentityServiceFactory;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
// Note that any JSON parser can be used; this one is used for illustrative purposes.
import org.json.JSONObject;
import org.json.JSONTokener;


public String createShortUrl(String longUrl) throws Exception {
    try {
        ArrayList scopes = new ArrayList();
        scopes.add("https://www.googleapis.com/auth/urlshortener");
        AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
        AppIdentityService.GetAccessTokenResult accessToken = appIdentity.getAccessToken(scopes);
        // The token asserts the identity reported by appIdentity.getServiceAccountName()
        JSONObject request = new JSONObject();
        request.put("longUrl", longUrl);

        URL url = new URL("https://www.googleapis.com/urlshortener/v1/url?pp=1");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.addRequestProperty("Content-Type", "application/json");
        connection.addRequestProperty("Authorization", "OAuth " + accessToken.getAccessToken());

        OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
        request.write(writer);
        writer.close();

        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            // Note: Should check the content-encoding.
            JSONTokener response_tokens = new JSONTokener(connection.getInputStream());
            JSONObject response = new JSONObject(response_tokens);
            return (String) response.get("id");
        } else {
            throw new Exception();
        }
    } catch (Exception e) {
        // Error handling elided.
        throw e;
    }
}

Note that the application's identity is represented by the service account name, which is typically applicationid@appspot.gserviceaccount.com. You can get the exact value by using the getServiceAccountName() method. For services which offer ACLs, you can grant the application access by granting this account access.

Asserting Identity to Other Systems

The token generated by getAccessToken() only works against Google systems. However you can use the underlying signing technology to assert the identity of your application to other systems. The signForApp() method will sign bytes using a private key unique to your application, and the getPublicCertificatesForApp() method will return certificates which can be used to validate the signature. Note that the certificates may be rotated from time to time, and the method may return multiple certificates, all of which are currently valid.