standard google features engine classes change app google-app-engine google-cloud-endpoints

google app engine - features - ¿Cómo protejo mi API creada con Google Cloud Endpoints?



google app engine standard environment (3)

La documentación es solo para el cliente. Lo que necesito es documentación sobre cómo proporcionar la funcionalidad de Cuenta de servicio en el lado del servidor.

Esto podría significar un par de cosas diferentes, pero me gustaría abordar lo que creo que está haciendo la pregunta. Si solo desea que su cuenta de servicio acceda a su servicio, puede agregar el ID de cliente de la cuenta de servicio a sus anotaciones @ Api / @ ApiMethod, crear un GoogleCredential e invocar su servicio como lo haría normalmente. Específicamente...

En la consola del desarrollador de Google, crea una nueva cuenta de servicio. Esto creará un archivo .p12 que se descargará automáticamente. Esto es utilizado por el cliente en la documentación a la que se ha vinculado. Si no puede mantener el .p12 seguro, entonces esto no es mucho más seguro que una contraseña. Supongo que es por eso que esto no está explícitamente establecido en la documentación de Cloud Endpoints.

Agregue la ID de CLIENTE que se muestra en la consola del desarrollador de Google a los ID de cliente en su anotación @Api o @ApiMethod

import com.google.appengine.api.users.User @ApiMethod(name = "doIt", scopes = { Constants.EMAIL_SCOPE }, clientIds = { "12345678901-12acg1ez8lf51spfl06lznd1dsasdfj.apps.googleusercontent.com" }) public void doIt(User user){ //by convention, add User parameter to existing params // if no client id is passed or the oauth2 token doesn''t // match your clientId then user will be null and the dev server // will print a warning message like this: // WARNING: getCurrentUser: clientId 1234654321.apps.googleusercontent.com not allowed //.. }

Cree un cliente de la misma forma que lo haría con la versión no segura, la única diferencia es que crea un objeto GoogleCredential para pasarlo a MyService.Builder de su servicio.

HttpTransport httpTransport = new NetHttpTransport(); // or build AndroidHttpClient on Android however you wish JsonFactory jsonFactory = new JacksonFactory(); // assuming you put the .p12 for your service acccount // (from the developer''s console) on the classpath; // when you deploy you''ll have to figure out where you are really // going to put this and load it in the appropriate manner URL url = getClass().class.getResource("/YOURAPP-b12345677654.p12"); File p12file = new File(url.toURI()); GoogleCredential.Builder credentialBuilder = new GoogleCredential.Builder(); credentialBuilder.setTransport(httpTransport); credentialBuilder.setJsonFactory(jsonFactory); //NOTE: use service account EMAIL (not client id) credentialBuilder.setServiceAccountId("12345678901-12acg1ez8lf51spfl06lznd1dsasdfj@developer.gserviceaccount.com"); credentialBuilder.setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/userinfo.email")); credentialBuilder.setServiceAccountPrivateKeyFromP12File(p12file); GoogleCredential credential = credentialBuilder.build();

Ahora invoque su cliente generado de la misma manera que lo haría con la versión no segura, excepto que el constructor toma nuestra credencial de Google desde arriba como el último argumento

MyService.Builder builder = new MyService.Builder(httpTransport, jsonFactory, credential); builder.setApplicationName("APP NAME"); builder.setRootUrl("http://localhost:8080/_ah/api"); final MyService service = builder.build(); // invoke service same as unsecured version

La API es un back-end para una aplicación móvil. No necesito autenticación de usuario. Simplemente necesito una forma de asegurar el acceso a esta API. Actualmente, mi backend está expuesto.

La documentation parece solo hablar sobre autenticación y autorización de usuario, que no es lo que necesito aquí. Solo necesito asegurarme de que solo mi aplicación móvil pueda hablar con este backend y con nadie más.


Lamento decir que Google no proporciona una solución para su problema (que también es mi problema). Puede usar su mecanismo de clave API (consulte https://developers.google.com/console/help/new/#usingkeys ), pero esta estrategia ofrece un gran vacío gracias al explorador de API propio de Google (consulte https://developers.google.com/apis-explorer/#p/ ), que es una excelente herramienta de desarrollo para probar las API, pero expone todas las API de Cloud Endpoint, no solo las API de servicios de Google. Esto significa que cualquier persona con el nombre de su proyecto puede navegar y llamar a su API en su tiempo libre ya que el explorador de API elude la seguridad de la clave API. Encontré una solución alternativa (basada en la gran respuesta de bossylobster a esta publicación: API de acceso simple (clave de desarrollador) con Google Cloud Endpoint (Python) ), que es pasar un campo de solicitud que no forma parte de la definición de solicitud de mensaje en su API de cliente , y luego léelo en tu servidor de API. Si no encuentra el campo no documentado, genera una excepción no autorizada. Esto cerrará el agujero creado por el explorador API. En iOS (que estoy usando para mi aplicación), agrega una propiedad a cada clase de solicitud (las creadas por la herramienta generadora de API de Google) de esta manera:

@property (copy) NSString *hiddenProperty;

y establece su valor a la clave que elijas. En su código de servidor (Python en mi caso), compruebe su existencia y barf si no lo ve o no está configurado en el valor que su servidor y el cliente acordarán:

mykey,keytype = request.get_unrecognized_field_info(''hiddenProperty'') if mykey != ''my_supersecret_key'': raise endpoints.UnauthorizedException(''No, you dont!'')

Espero que esto te ponga en el camino correcto


Sí, puedes hacer eso: usa la autenticación para proteger tus puntos finales sin hacer autenticación de usuario.

He descubierto que esta forma de hacerlo no está bien documentada, y en realidad no lo he hecho yo mismo, pero tengo la intención de hacerlo, así que presté atención cuando vi que se discutía en algunos de los videos de IO13 (creo que ahí es donde Lo ví):

Aquí está mi entendimiento de lo que está involucrado:

  • Cree un proyecto de la API de Google (aunque esto realmente no involucra sus API, aparte de la autenticación misma).
  • Cree los ID de cliente OATH que están vinculados a su aplicación a través del nombre del paquete y la huella digital SHA1 del certificado con el que firmará la aplicación.

Agregará estos ID de cliente a la lista de ID aceptables para sus endpoints. Agregará el parámetro de usuario a sus puntos finales, pero será nulo ya que no se especifica ningún usuario.

@ApiMethod( name = "sendInfo", clientIds = { Config.WEB_CLIENT_ID, Config.MY_APP_CLIENT_ID, Config.MY_DEBUG_CLIENT_ID }, audiences = { Config.WEB_CLIENT_ID } // Yes, you specify a ''web'' ID even if this isn''t a Web client. ) public void sendInfo(User user, Info greeting) {

Existe documentación decente sobre lo anterior, aquí: documentation

La aplicación de cliente especificará estas ID de cliente al formular la llamada al servicio de punto final. Todos los detalles de OATH serán atendidos tras bambalinas en su dispositivo cliente de manera que las identificaciones de sus clientes se traduzcan en tokens de autenticación.

HttpTransport transport = AndroidHttp.newCompatibleTransport(); JsonFactory jsonFactory = new JacksonFactory(); GoogleAccountCredential credential = GoogleAccountCredential.usingAudience( ctx, Config.WEB_CLIENT_ID ); //credential.setSelectedAccountName( user ); // not specify a user Myendpoint.Builder builder = new Myendpoint.Builder( transport, jsonFactory, credential );

Este código de cliente es mi mejor estimación, lo siento. Si alguien más tiene una referencia para ver exactamente cómo debería ser el código del cliente, entonces yo también estaría interesado.