DEV Community

César M. Cristóbal for CallePuzzle Dev

Posted on • Originally published at dev.callepuzzle.com

Autenticar nginx mediante el método service-to-service en GCP

Imaginad que estamos montado una serie de microservicios en Cloud Run donde el endpoint es un nginx y no queremos tener el resto de servicios públicos.

Cloud run diagram

Google nos provee de un método de autenticación service-to-service. Perfecto, ¿cómo hacemos eso en nginx? Pues usando el módulo ngx_http_auth_request_module y el njs scripting language.

El código que necesitamos en nginx es el siguiente:

js_include conf.d/auth.js;

server {
    listen 80 default_server;
    server_name _;

    location / {
        auth_request /_oauth2;
        auth_request_set $authorization $sent_http_authorization;
        proxy_set_header Authorization $authorization;
        proxy_pass https://patinando-int-api-tfezajqgva-ew.a.run.app;
    }


    location = /_oauth2 {
        internal;
        js_content introspectAccessToken;
    }

    location = /_oauth2_send_request {
        internal;
        proxy_set_header  Metadata-Flavor Google;
        proxy_pass http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://patinando-int-api-tfezajqgva-ew.a.run.app;
    }
}
Enter fullscreen mode Exit fullscreen mode
function introspectAccessToken(r) {

    r.subrequest("/_oauth2_send_request",
                 function(reply) {
                     if (reply.status == 200) {
                         r.headersOut['AUTHORIZATION'] = 'Bearer ' + reply.responseBody
                         r.status = 204;
                         r.sendHeader();
                         r.finish();
                     } else {
                         r.return(401);
                     }
                 }
                );
}
Enter fullscreen mode Exit fullscreen mode

En nuestro caso nuestro servicio interno es https://patinando-int-api-tfezajqgva-ew.a.run.app y si lanzamos un wget obtenemos un bonito 403:

HTTP request sent, awaiting response… 
 HTTP/1.1 403 Forbidden
 Date: Sun, 03 May 2020 11:36:33 GMT
 Content-Type: text/html; charset=UTF-8
 Server: Google Frontend
 Content-Length: 295
2020–05–03 11:36:33 ERROR 403: Forbidden
Enter fullscreen mode Exit fullscreen mode

Lo que estamos haciendo con este código es decir que toda petición se tiene que autorizar con /_oauth2 que es una llamada interna y contiene el código de la función en javascript.

El código javascript a su vez llama a /_oauth2_send_request para obtener el token.

Para poder usar la cabecera que seteamos en javascript con

r.headersOut[‘AUTHORIZATION’] = ‘Bearer ‘ + reply.responseBody
Enter fullscreen mode Exit fullscreen mode

es necesario añadir estas líneas en el location principal

auth_request_set $authorization $sent_http_authorization;
proxy_set_header Authorization $authorization;
Enter fullscreen mode Exit fullscreen mode

Si ahora hacemos peticiones al nginx la api nos devolverá un 200:

HTTP/1.1 200 OK
 Server: nginx/1.17.10
 Date: Sun, 03 May 2020 11:44:56 GMT
 Content-Type: application/json
 Content-Length: 5436
 Connection: keep-alive
 vary: Authorization
 x-powered-by: PHP/7.4.5
 cache-control: no-cache, private
Enter fullscreen mode Exit fullscreen mode

Referencias:

Top comments (0)