API App Identity per servizi in bundle legacy

ID regione

REGION_ID è un codice abbreviato assegnato da Google in base alla regione selezionata al momento della creazione dell'app. Il codice non corrispondono a un paese o a una provincia, anche se potrebbero essere visualizzati alcuni ID regione in modo simile ai codici paese e provincia di uso comune. Per le app create dopo il giorno Febbraio 2020, REGION_ID.r è incluso in URL di App Engine. Per le app esistenti create prima di questa data, l'ID regione è facoltativo nell'URL.

Scopri di più sugli ID regione.

L'API App Identity consente a un'applicazione di rilevare il proprio ID applicazione (anche denominato ID progetto). Utilizzo l'ID, un'applicazione App Engine può affermare la propria identità ad altro App Engine App, API di Google e applicazioni e servizi di terze parti. La l'ID applicazione può essere utilizzato anche per generare un URL o un indirizzo email oppure una decisione in fase di runtime.

Recupero dell'ID progetto

Puoi trovare l'ID progetto utilizzando ApiProxy.getCurrentEnvironment().getAppId().

Recuperare il nome host dell'applicazione

Per impostazione predefinita, le app di App Engine vengono fornite da URL nel formato https://PROJECT_ID.REGION_ID.r.appspot.com, dove l'ID progetto fa parte del nome host. Se un'app viene pubblicata da un dominio personalizzato, potrebbe essere necessario recuperare il l'intero nome host. Puoi farlo utilizzando l'attributo com.google.appengine.runtime.default_version_hostname dell'attributo CurrentEnvironment.

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

Dichiarazione dell'identità per altre app di App Engine

Se vuoi determinare l'identità dell'app di App Engine che sta eseguendo una all'app App Engine, puoi utilizzare l'intestazione della richiesta X-Appengine-Inbound-Appid. Questa intestazione viene aggiunta alla richiesta dall'URL e non è modificabile dall'utente, perciò indica in modo sicuro dell'ID progetto dell'applicazione, se presente.

Requisiti:

  • Solo le chiamate effettuate al dominio appspot.com della tua app conterranno l'intestazione X-Appengine-Inbound-Appid. Chiamate a domini personalizzati non contengono l'intestazione.
  • Le richieste devono essere impostate in modo da non seguire i reindirizzamenti. Se utilizzi URLFetchService, nell'app deve essere specificato doNotFollowRedirect. Le app in esecuzione nel runtime Java 8 non utilizzano Servizio URLFetch per impostazione predefinita. Per attivare URLFetch segui queste istruzioni.
  • Se la tua app utilizza java.net, aggiorna il codice per non seguire i reindirizzamenti:
    connection.setInstanceFollowRedirects(false);

Nel gestore delle applicazioni, puoi controllare l'ID in entrata leggendo l'evento X-Appengine-Inbound-Appid e lo confronta con un elenco di ID consentiti per effettuare richieste.

Dichiarazione dell'identità alle API di Google

Le API di Google utilizzano il protocollo OAuth 2.0 per l'autenticazione e autorizzazione. La L'API App Identity può creare token OAuth da utilizzare per affermare che l'origine di una richiesta è l'applicazione stessa. Il metodo getAccessToken() restituisce un token di accesso per un ambito o un elenco di ambiti. Questo token può quindi essere impostato nelle intestazioni HTTP di una chiamata per identificare l'applicazione chiamante.

L'esempio seguente mostra come utilizzare l'API App Identity per effettuare una chiamata REST all'API Google URL Shortener.

/**
 * Returns a shortened URL by calling the Google URL Shortener API.
 *
 * <p>Note: Error handling elided for simplicity.
 */
public String createShortUrl(String longUrl) throws Exception {
  ArrayList<String> scopes = new ArrayList<>();
  scopes.add("https://www.googleapis.com/auth/urlshortener");
  final AppIdentityService appIdentity = AppIdentityServiceFactory.getAppIdentityService();
  final 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", "Bearer " + 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.
    //       Any JSON parser can be used; this one is used for illustrative purposes.
    JSONTokener responseTokens = new JSONTokener(connection.getInputStream());
    JSONObject response = new JSONObject(responseTokens);
    return (String) response.get("id");
  } else {
    try (InputStream s = connection.getErrorStream();
        InputStreamReader r = new InputStreamReader(s, StandardCharsets.UTF_8)) {
      throw new RuntimeException(
          String.format(
              "got error (%d) response %s from %s",
              connection.getResponseCode(), CharStreams.toString(r), connection.toString()));
    }
  }
}

Tieni presente che l'identità dell'applicazione è rappresentata dal nome dell'account di servizio, che in genere è applicationid@appspot.gserviceaccount.com. Puoi ottenere il valore esatto utilizzando il metodo getServiceAccountName(). Per i servizi che offrono ACL, puoi concedere l'accesso all'applicazione concedendo l'accesso a questo account.

Dichiarazione dell'identità a servizi di terze parti

Il token generato da getAccessToken() funziona solo con i servizi Google. Tuttavia, puoi utilizzare la tecnologia di firma sottostante per rivendicare l'identità della tua applicazione su altri servizi. Il metodo signForApp() firmerà i byte utilizzando una chiave privata univoca per l'applicazione e il metodo getPublicCertificatesForApp() restituirà i certificati che possono essere utilizzati per convalidare la firma.

Ecco un esempio che mostra come firmare un blob e convalidarne la firma:
// Note that the algorithm used by AppIdentity.signForApp() and
// getPublicCertificatesForApp() is "SHA256withRSA"

private byte[] signBlob(byte[] blob) {
  AppIdentityService.SigningResult result = appIdentity.signForApp(blob);
  return result.getSignature();
}

private byte[] getPublicCertificate() throws UnsupportedEncodingException {
  Collection<PublicCertificate> certs = appIdentity.getPublicCertificatesForApp();
  PublicCertificate publicCert = certs.iterator().next();
  return publicCert.getX509CertificateInPemFormat().getBytes("UTF-8");
}

private Certificate parsePublicCertificate(byte[] publicCert)
    throws CertificateException, NoSuchAlgorithmException {
  InputStream stream = new ByteArrayInputStream(publicCert);
  CertificateFactory cf = CertificateFactory.getInstance("X.509");
  return cf.generateCertificate(stream);
}

private boolean verifySignature(byte[] blob, byte[] blobSignature, PublicKey pk)
    throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
  Signature signature = Signature.getInstance("SHA256withRSA");
  signature.initVerify(pk);
  signature.update(blob);
  return signature.verify(blobSignature);
}

private String simulateIdentityAssertion()
    throws CertificateException, UnsupportedEncodingException, NoSuchAlgorithmException,
    InvalidKeyException, SignatureException {
  // Simulate the sending app.
  String message = "abcdefg " + Calendar.getInstance().getTime().toString();
  byte[] blob = message.getBytes();
  byte[] blobSignature = signBlob(blob);
  byte[] publicCert = getPublicCertificate();

  // Simulate the receiving app, which gets the certificate, blob, and signature.
  Certificate cert = parsePublicCertificate(publicCert);
  PublicKey pk = cert.getPublicKey();
  boolean isValid = verifySignature(blob, blobSignature, pk);

  return String.format(
      "isValid=%b for message: %s\n\tsignature: %s\n\tpublic cert: %s",
      isValid, message, Arrays.toString(blobSignature), Arrays.toString(publicCert));
}

Recupero del nome del bucket Cloud Storage predefinito

Ogni applicazione può avere un bucket Cloud Storage predefinito, include 5 GB di spazio di archiviazione gratuito e una quota gratuita per le operazioni di I/O.

Per ottenere il nome del bucket predefinito, puoi utilizzare l'API App Identity. Chiama AppIdentityService.getDefaultGcsBucketName.