Autentica usuarios finales de los servicios de Cloud Run for Anthos con Istio y Identity Platform

En este instructivo, se muestra cómo autenticar usuarios finales de aplicaciones implementadas en Cloud Run for Anthos en Google Cloud con políticas de autenticación de Istio y, también, Identity Platform. Usar Istio para autenticar significa que la lógica de autenticación no necesita ser parte del código de la aplicación. Esta separación permite que los diferentes equipos sean responsables del código de la aplicación y de la política de autenticación, y estas pueden aplicarse en varias aplicaciones o servicios.

Introducción

Cloud Run for Anthos proporciona una experiencia centrada en el desarrollador para implementar y entregar aplicaciones y funciones que se ejecutan en GKE. Ofrece a los equipos de desarrollo una experiencia sin servidores, que admite el ajuste de escala automático a pedido, el enrutamiento y la administración del tráfico para implementaciones azul-verde y mucho más. Cloud Run for Anthos se basa en los proyectos de código abierto Istio y Knative, y se integra a productos de Google Cloud, como Cloud Logging.

Istio puede autenticar solicitudes entrantes mediante la validación de tokens web JSON (JWT) de acuerdo con las políticas de autenticación. Las políticas de autenticación se pueden aplicar a todos los servicios en un espacio de nombres o a servicios con nombres específicos. Una política puede incluir y excluir rutas de acceso de solicitud HTTP específicas, por ejemplo, para permitir el acceso no autenticado a recursos de sitios web públicos y extremos de verificación de estado. En este instructivo, la puerta de enlace de entrada de Istio aplica la política de autenticación.

En el siguiente diagrama, se muestra el flujo de autenticación en el que se basa este instructivo.

Istio autentica las solicitudes entrantes

En este instructivo, se usa Identity Platform para que accedan a los usuarios finales, pero puedes adaptar la solución a otros proveedores que admitan OpenID Connect, como Acceso con Google, Firebase Authentication, ofertas de terceros como Auth0, Gluu, Okta, Ping Identity o tu propia implementación de OpenID Connect.

Objetivos

  • Crear un clúster de GKE con el complemento de Cloud Run
  • Configurar Identity Platform
  • Implementar una aplicación de muestra que consista en un frontend público y una API de backend
  • Agregar una política de autenticación para la API de backend
  • Verificar la autenticación

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud sean aptos para obtener una prueba gratuita.

Cuando finalices este instructivo, podrás borrar los recursos creados para evitar que se te siga facturando. Para obtener más información, consulta cómo hacer una limpieza.

Antes de comenzar

  1. Accede a tu Cuenta de Google o, si no tienes una, regístrate para obtener una cuenta nueva.
  2. En Cloud Console, ve a la página Selector de proyectos.

    Ir a la página de selección de proyectos

  3. Selecciona o crea un proyecto de Cloud.

  4. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud. Obtén información sobre cómo confirmar que tienes habilitada la facturación para tu proyecto.

  5. Habilita las API de Cloud Build, Cloud Run, Container Analysis, Google Kubernetes Engine y Cloud.

    HABILITA LAS API

Inicializa el entorno

En esta sección, estableces variables de entorno y valores predeterminados de gcloud que usarás más adelante en el instructivo.

  1. En el menú desplegable Seleccionar un proyecto de Cloud Console, selecciona el proyecto que deseas usar.

  2. Abre Cloud Shell:

    IR A Cloud Shell

    Usa Cloud Shell para ejecutar todos los comandos de este instructivo.

  3. Define las variables de entorno y los valores predeterminados de gcloud para la zona de Compute Engine y el nombre del clúster de GKE que deseas usar en este instructivo:

    ZONE=us-central1-c
    CLUSTER=cloud-run-gke-auth-tutorial
    
    gcloud config set compute/zone $ZONE
    gcloud config set run/cluster $CLUSTER
    gcloud config set run/cluster_location $ZONE
    

    Puedes cambiar la zona y el nombre del clúster según lo necesites.

Crea un clúster de GKE con Cloud Run habilitado

  • Crea un clúster de GKE con el complemento de Cloud Run:

    gcloud beta container clusters create $CLUSTER \
        --addons HorizontalPodAutoscaling,HttpLoadBalancing,CloudRun \
        --enable-ip-alias \
        --enable-stackdriver-kubernetes \
        --machine-type n1-standard-2
    

Encuentra la dirección IP pública

Cloud Run for Anthos en Google Cloud expone servicios externos en la dirección IP pública de la puerta de enlace de entrada de Istio.

  1. Verifica el estado de la creación de una dirección IP externa para el servicio de Kubernetes istio-ingress:

    kubectl get services istio-ingress -n gke-system --watch
    

    Espera hasta que el valor EXTERNAL-IP cambie de <pending> a una dirección IP. Si recibes un error NotFound, espera un minuto y vuelve a ejecutar el comando. Para dejar de esperar, presiona Control + C.

  2. Crea una variable de entorno para almacenar la dirección IP pública de la puerta de enlace de entrada de Istio:

    export EXTERNAL_IP=$(kubectl get services istio-ingress \
        --namespace gke-system \
        --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
    
  3. Muestra la dirección IP pública de la puerta de enlace de entrada de Istio. Necesitarás esta dirección más tarde.

    echo $EXTERNAL_IP
    

Nota: En este instructivo, accedes a los servicios con una dirección IP y HTTP sin encriptar. Para una configuración de producción, te recomendamos que hagas lo siguiente:

Configura Identity Platform

  1. Deja Cloud Shell abierto y visita Google Cloud Marketplace para habilitar Identity Platform en una ventana nueva del navegador web.

    Ir a Identity Platform en Google Cloud Marketplace

  2. En el menú desplegable Seleccionar un proyecto, selecciona el proyecto de Google Cloud en el que deseas configurar Identity Platform. Puedes configurar el clúster de GKE y Identity Platform en proyectos diferentes de Google Cloud. Para simplificar, usa el mismo proyecto en este instructivo.

  3. Haz clic en Habilitar Identity Platform.

    Ahora te encuentras en la página Identity Platform > Proveedores de Cloud Console.

  4. En la página Proveedores, haz clic en Agregar un proveedor.

  5. En el menú desplegable Seleccionar un proveedor, desplázate hacia abajo y selecciona Correo electrónico/Contraseña. Para tu propia aplicación, puedes elegir los proveedores que desees habilitar.

  6. Asegúrate de que esté seleccionado Habilitado.

  7. Borra Permitir acceso sin contraseña.

  8. Haz clic en Guardar.

  9. Ve a la página Identity Platform > Configuración.

  10. Haz clic en la pestaña Seguridad.

  11. Haz clic en Agregar dominio. Se abrirá el cuadro de diálogo Agregar dominio autorizado.

  12. En el cuadro Dominio, ingresa la dirección IP pública de la puerta de enlace de entrada de Istio de la sección anterior ($EXTERNAL_IP).

  13. Haz clic en Agregar. Esto cierra el cuadro de diálogo. La dirección IP que ingresaste se encuentra en la tabla Dominios autorizados.

  14. En la página Identity Platform > Configuración, haz clic en Guardar.

Crea un usuario de prueba

  1. En Cloud Console, dirígete a la página Identity Platform > Usuarios.
  2. Haz clic en Agregar usuario para agregar un usuario de prueba a este instructivo. Se abrirá el cuadro de diálogo Agregar usuario.
  3. En el cuadro Correo electrónico, ingresa la dirección de correo electrónico de un usuario final. Para realizar pruebas, esta dirección de correo electrónico no tiene que ser real. En este instructivo, usa user@example.com:
  4. En el cuadro Contraseña, ingresa una contraseña para el usuario de prueba. Recuerda esta contraseña porque la necesitarás más adelante.
  5. Haz clic en Agregar para terminar de agregar al usuario. Esto cierra el cuadro de diálogo y te dirige nuevamente a la página Identity Platform > Usuarios.

Crea una aplicación de muestra

Implementa una aplicación de muestra que tenga dos servicios. Un servicio es una interfaz de usuario de frontend pública; el otro servicio es una API de backend.

  1. En la página Identity Platform > Usuarios, haz clic en el vínculo Detalles de configuración de la aplicación en el lado derecho de la ventana. Esto abrirá el cuadro de diálogo Configurar tu aplicación.

  2. Destaca y copia el valor de apiKey en tu portapapeles (Control + C en el Sistema operativo Chrome/Linux/Windows, Comando + C en macOS).

  3. Haz clic en Cerrar para cerrar el cuadro de diálogo Configurar tu aplicación.

  4. En Cloud Shell, crea una variable de entorno para almacenar apiKey, en el que api-key es la apiKey del cuadro de diálogo Configurar tu aplicación:

    export AUTH_APIKEY=api-key
    
  5. Crea una variable de entorno para authDomain:

    export AUTH_DOMAIN=$GOOGLE_CLOUD_PROJECT.firebaseapp.com
    
  6. Clona el repositorio de muestras de Cloud Run desde GitHub:

    git clone https://github.com/GoogleCloudPlatform/cloud-run-samples.git
    
  7. Cambia al directorio que contiene los archivos de este instructivo:

    cd cloud-run-samples/identity-platform/gke
    
  8. Sustituye las variables de Identity Platform en el archivo JavaScript de frontend:

    envsubst < frontend/index.template.js > frontend/index.js
    

Implementa la aplicación de muestra

  1. Usa Cloud Build a fin de crear dos imágenes de contenedor para la aplicación de muestra, una en el caso del frontend y otra del backend:

    gcloud builds submit -t gcr.io/$GOOGLE_CLOUD_PROJECT/cloud-run-gke-auth-frontend frontend
    
    gcloud builds submit -t gcr.io/$GOOGLE_CLOUD_PROJECT/cloud-run-gke-auth-backend backend
    

    Cloud Build almacena las imágenes en Container Registry.

  2. En el clúster de GKE, crea dos espacios de nombres llamados public y api:

    kubectl create namespace public
    
    kubectl create namespace api
    
  3. Implementa la imagen de contenedor de frontend en Cloud Run for Anthos en Google Cloud como un servicio en el espacio de nombres public:

    gcloud run deploy frontend \
        --namespace public \
        --image gcr.io/$GOOGLE_CLOUD_PROJECT/cloud-run-gke-auth-frontend \
        --platform gke
    
  4. Implementa la imagen de contenedor de backend en Cloud Run for Anthos en Google Cloud como un servicio en el espacio de nombres api:

    gcloud run deploy backend \
        --namespace api \
        --image gcr.io/$GOOGLE_CLOUD_PROJECT/cloud-run-gke-auth-backend \
        --platform gke
    
  5. Crea un servicio virtual de Istio que enrute las solicitudes por ruta de acceso de URI:

    kubectl apply -f istio/virtualservice.yaml
    

    Este servicio virtual enruta las solicitudes en las que la ruta de acceso de URI comienza con /api/ a la API de backend y enruta todas las demás solicitudes a la interfaz de usuario de frontend.

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: cloud-run-gke-auth
    spec:
      gateways:
      - gke-system-gateway.knative-serving.svc.cluster.local
      hosts:
      - "*"
      http:
      - match:
        - uri:
            prefix: "/api/"
        rewrite:
          authority: backend.api.svc.cluster.local
        route:
        - destination:
            host: cluster-local-gateway.gke-system.svc.cluster.local
      - match:
        - uri:
            prefix: "/"
        rewrite:
          authority: frontend.public.svc.cluster.local
        route:
        - destination:
            host: cluster-local-gateway.gke-system.svc.cluster.local
  6. Verifica que las solicitudes no autenticadas a la API de backend se ejecuten correctamente:

    curl -si $EXTERNAL_IP/api/secure.json | head -n1
    

    Si el resultado no es HTTP/1.1 200 OK, espera un minuto y vuelve a intentarlo.

Agrega una política de autenticación de Istio

  1. Crea una política de autenticación de Istio:

    envsubst < istio/authenticationpolicy.template.yaml | kubectl apply -f -
    
    apiVersion: authentication.istio.io/v1alpha1
    kind: Policy
    metadata:
      name: api-origin-auth
      namespace: gke-system
    spec:
      targets:
      - name: istio-ingress
        ports:
        - number: 80
        - number: 443
      origins:
      - jwt:
          issuer: "https://securetoken.google.com/$GOOGLE_CLOUD_PROJECT"
          audiences:
          - "$GOOGLE_CLOUD_PROJECT"
          jwksUri: "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com"
          trigger_rules:
          - excluded_paths:
            - exact: /api/healthz
            included_paths:
            - prefix: /api/
      principalBinding: USE_ORIGIN

    Esta política autentica las solicitudes en las que la ruta de acceso de URI comienza con /api/, excepto la ruta de acceso /api/healthz. Debido a las reglas de enrutamiento del servicio virtual de Istio implementado en la sección anterior, esta política autentica las solicitudes a la API de backend.

  2. Puede que la política tome un momento en entrar en efecto. Ejecuta el siguiente comando y espera hasta que veas HTTP/1.1 401 Unauthorized en la consola:

    while sleep 2; do
      curl -si $EXTERNAL_IP/api/secure.json | head -n1
    done
    

    En principio, es posible que veas la salida alternativa entre HTTP/1.1 200 OK y HTTP/1.1 401 Unauthorized. Esto se debe a la coherencia eventual en Istio y el proxy de Envoy.

    Cuando veas que solo se muestra HTTP/1.1 401 Unauthorized en la consola, presiona Control + C para dejar de esperar.

Prueba la solución

  1. Abre una ventana del navegador con la dirección http://$EXTERNAL_IP/api/secure.json, en la que $EXTERNAL_IP es la dirección IP pública de la puerta de enlace de entrada de Istio que encontraste en la sección Encuentra la dirección IP pública.

    Esta es una solicitud directa a la API de backend. La ventana del navegador muestra Error en la autenticación de origen porque la solicitud no incluía las credenciales que satisfacían la política de autenticación de Istio.

  2. Abre una ventana del navegador con la dirección $EXTERNAL_IP. Deberías ver un formulario de acceso.

  3. Accede con el usuario de prueba que creaste en la sección Crea un usuario de prueba.

    La página muestra la dirección de correo electrónico del usuario de prueba y el texto El mensaje secreto es: Hello World. El mensaje puede tomar un momento en aparecer.

    El navegador recupera el mensaje con una solicitud HTTP a la API de backend (/api/secure.json) con un token obtenido de Identity Platform cuando se accede. Inspecciona el archivo frontend/index.js para ver la implementación y consulta la biblioteca de FirebaseUI a fin de obtener más documentación.

Soluciona problemas

Si tienes problemas con este instructivo, te recomendamos que revises los siguientes documentos:

Realiza una limpieza

Para evitar que se generen costos en tu cuenta de Google Cloud por los recursos que se usaron en este instructivo, sigue estos pasos:

  1. En Cloud Console, ve a la página Administrar recursos.

    Ir a la página Administrar recursos

  2. En la lista de proyectos, selecciona el proyecto que deseas borrar y haz clic en Borrar .
  3. En el cuadro de diálogo, escribe el ID del proyecto y haz clic en Cerrar para borrar el proyecto.

Borra los recursos

Si deseas conservar el proyecto Google Cloud que usaste en este instructivo, borra los recursos individuales:

  1. Borra el clúster de GKE:

    gcloud container clusters delete $CLUSTER --async --quiet
    
  2. Borra las imágenes del contenedor de la aplicación de muestra en Container Registry:

    gcloud container images delete gcr.io/$GOOGLE_CLOUD_PROJECT/cloud-run-gke-auth-frontend \
        --force-delete-tags --quiet
    
    gcloud container images delete gcr.io/$GOOGLE_CLOUD_PROJECT/cloud-run-gke-auth-backend \
        --force-delete-tags --quiet
    
  3. Borra el proveedor de identidad de Correo electrónico/Contraseña en Identity Platform.

    1. En Cloud Console, ve a la página Identity Platform > Proveedores:

      IR A LA PÁGINA PROVEEDORES

    2. Busca el proveedor de identidad de Correo electrónico/Contraseña en la tabla de proveedores y haz clic en .

    3. En el cuadro de diálogo que aparece, haz clic en Borrar para confirmar.

  4. Borra el usuario de prueba.

    1. Ve a la página Identity Platform > Usuarios:

      IR A LA PÁGINA USUARIOS

    2. Busca user@example.com en la tabla de usuarios y haz clic en .

    3. En el cuadro de diálogo que aparece, haz clic en Borrar para confirmar.

  5. Borra el dominio autorizado.

    1. Ve a la página Identity Platform > Configuración:

      IR A LA PÁGINA DE CONFIGURACIÓN

    2. En la tabla de dominios autorizados, busca la dirección IP que agregaste en la sección Configura Identity Platform ($EXTERNAL_IP) y haz clic en .

    3. Haz clic en Guardar.

Próximos pasos