DEV Community

César M. Cristóbal for CallePuzzle Dev

Posted on • Originally published at dev.callepuzzle.com

1 1

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:

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay