Configuración de la autenticación JWT personalizada (Okta, Auth0)

Data API Builder admite proveedores de identidades de terceros a través del proveedor de autenticación personalizado mediante la validación de JSON Web Token (JWT). Use este enfoque cuando su organización use Okta, Auth0 u otro proveedor de identidades compatible con OAuth 2.0/OpenID Connect.

Flujo de autenticación

Con un proveedor de identidades personalizado, la aplicación cliente controla la autenticación de usuario y, a continuación, envía el token de acceso a Data API Builder:

Diagrama que muestra el flujo de autenticación JWT personalizado con un proveedor de identidades de terceros.

Fase ¿Qué ocurre?
Autenticación de usuario El usuario inicia sesión a través del proveedor de identidades (Okta, Auth0, etc.)
Adquisición de tokens La aplicación cliente recibe un token de acceso del IdP
Llamada API El cliente envía el token a DAB en el Authorization encabezado
Validación DAB valida el JWT (emisor, audiencia, firma)
Autorización DAB extrae roles y evalúa los permisos.

Prerrequisitos

  • Una cuenta con su proveedor de identidades digitales (Okta, Auth0, etc.)
  • Una aplicación registrada en el proveedor de identidades
  • CLI de Data API Builder instalada (guía de instalación)
  • Un dab-config.json existente con al menos una entidad

Referencia rápida

Configuración Importancia
Provider Custom
Obligatorio para la validación iss, aud, exp, firma válida
Obligatorio para la autorización roles reclamación que contiene el rol seleccionado
Encabezado de token Authorization: Bearer <token>
Tipo de declaración de rol roles (fijo, no configurable)
Encabezado de selección de roles X-MS-API-ROLE

Paso 1: Configuración del proveedor de identidades

Los pasos exactos dependen del proveedor. Estos son los valores clave que necesita:

Valores que se van a recopilar

Importancia Dónde encontrarla Se usa para
Dirección URL del emisor Documentación del proveedor o punto de conexión de metadatos de OAuth DAB jwt.issuer (se usa como autoridad JWT)
Audiencia Identificador de cliente de la aplicación o un identificador de API personalizado DAB jwt.audience

Nota:

DAB utiliza el elemento configurado jwt.issuer como la autoridad de JWT. Las claves de firma se detectan automáticamente a través de los metadatos estándar de OpenID Connect (normalmente <issuer>/.well-known/openid-configuration).

Ejemplo de Okta

  1. Inicie sesión en la consola de administración de Okta.
  2. Vaya a Aplicaciones>Aplicaciones.
  3. Cree o seleccione una aplicación.
  4. Anote el Identificador de Cliente (úselo como audiencia).
  5. El emisor suele ser https://<your-domain>.okta.com.

Ejemplo de Auth0

  1. Inicie sesión en el panel de Auth0.
  2. Vaya a Aplicaciones>APIs.
  3. Cree o seleccione una API.
  4. Tenga en cuenta el identificador (úselo como destinatario).
  5. El emisor es https://<your-tenant>.auth0.com/.

Importante

Data API Builder utiliza un tipo de reclamación fijo de roles para la autorización basada en roles. Este valor no se puede configurar. Si el proveedor de identidades emite roles en una declaración diferente (como groups o permissions), configúrelo para que también emita una declaración roles. Los usuarios de Auth0 deben revisar el conflicto conocido de espacios de nombres antes de continuar.

Paso 2: Configuración de Data API Builder

Establezca el proveedor de autenticación en Custom y configure las opciones de JWT.

CLI

# Set the authentication provider
dab configure \
  --runtime.host.authentication.provider Custom

# Set the expected audience
dab configure \
  --runtime.host.authentication.jwt.audience "<your-api-identifier>"

# Set the expected issuer
dab configure \
  --runtime.host.authentication.jwt.issuer "https://<your-issuer>/"

Configuración resultante

{
  "runtime": {
    "host": {
      "authentication": {
        "provider": "Custom",
        "jwt": {
          "audience": "<your-api-identifier>",
          "issuer": "https://<your-issuer>/"
        }
      }
    }
  }
}

Paso 3: Configuración de permisos de entidad

Defina permisos para los roles que asigna el proveedor de identidades:

CLI

# Allow authenticated users to read
dab update Book \
  --permissions "authenticated:read"

# Allow users with 'admin' role full access
dab update Book \
  --permissions "admin:*"

Configuración resultante

{
  "entities": {
    "Book": {
      "source": "dbo.Books",
      "permissions": [
        {
          "role": "authenticated",
          "actions": ["read"]
        },
        {
          "role": "admin",
          "actions": ["*"]
        }
      ]
    }
  }
}

Paso 4: Configuración de roles en el proveedor de identidades

DAB espera roles en una roles reclamación. Configure el proveedor de identidades para incluir esta declaración.

Okta: Agregar grupos como roles

  1. En la consola de administración de Okta, vaya a Api de seguridad>.
  2. Seleccione el servidor de autorización.
  3. Vaya a la pestaña Notificaciones .
  4. Agregue una notificación:
    • Nombre: roles
    • Incluir en el tipo de token: Token de acceso
    • Tipo de valor: Grupos
    • Filtro: seleccione los grupos que desea incluir.

Auth0: Agregar roles con una acción

Auth0 requiere que las claims personalizadas utilicen nombres con espacio de nombres resistentes a colisiones (por ejemplo, https://example.com/roles). Las declaraciones sin espacio de nombres que entran en conflicto con nombres reservados se excluyen silenciosamente del token. Para obtener más información, consulte Creación de notificaciones personalizadas en la documentación de Auth0.

Data API builder requiere el nombre exacto de la declaración roles, no una variante con un espacio de nombres. Que Auth0 acepte una reclamación roles no asociada a un espacio de nombres depende de la configuración de tu tenant.

  1. En el panel de Auth0, vaya a Acciones>Biblioteca.

  2. Cree una nueva acción (desencadenador posterior al inicio de sesión).

  3. Agregue código para incluir roles:

    exports.onExecutePostLogin = async (event, api) => {
      const roles = event.authorization?.roles || [];
      if (roles.length > 0) {
        api.accessToken.setCustomClaim('roles', roles);
      }
    };
    
  4. Implemente la acción y agréguela al flujo de inicio de sesión.

  5. Compruebe el token de acceso decodificado en jwt.io y confirme que la declaración roles está presente.

Warning

Auth0 puede omitir silenciosamente el claim roles sin espacio de nombres, según la configuración de tu tenant. Si falta la declaración en el token, compruebe Configuración>Avanzado en el Dashboard de Auth0 para comprobar la aplicación obligatoria del espacio de nombres. Los inquilinos que requieren notificaciones con espacios de nombres no son compatibles actualmente con la autorización basada en roles del generador de Data API para roles personalizados. Los roles integrados authenticated y anonymous siguen funcionando porque no dependen de una reclamación roles.

Sugerencia

Para obtener instrucciones detalladas sobre cómo configurar reclamaciones JWT con Okta, consulte Personalizar tokens devueltos por Okta.

Paso 5: Probar la configuración

  1. Inicie el generador de Data API:

    dab start
    
  2. Adquiera un token de su proveedor de identidad. Use el SDK del proveedor o una herramienta como Postman.

  3. Inspeccione el token en jwt.io para comprobar lo siguiente:

    • La aud afirmación coincide con la audiencia configurada.
    • La iss reclamación coincide con el emisor configurado.
    • La roles reclamación contiene los valores esperados.
  4. Llame a la API:

    curl -X GET "http://localhost:5000/api/Book" \
      -H "Authorization: Bearer <your-token>"
    
  5. Para usar un rol personalizado, incluya el X-MS-API-ROLE encabezado :

    curl -X GET "http://localhost:5000/api/Book" \
      -H "Authorization: Bearer <your-token>" \
      -H "X-MS-API-ROLE: admin"
    

Detalles de validación de JWT

Data API Builder valida estos aspectos del JWT:

Check Descripción
Signature Validado mediante claves de firma descubiertas a través de la autoridad configurada jwt.issuer (metadatos de OpenID Connect o conjunto de claves web JSON (JWKS))
Emisor Debe coincidir exactamente con la configuración jwt.issuer
Audiencia Debe coincidir exactamente con la configuración jwt.audience
Expiración El token no debe estar caducado (exp reclamo)
No antes El token debe ser válido (nbf declaración, si está presente)

Solución de problemas

Síntoma Causa posible Solución
401 Unauthorized Desajuste del emisor Compruebe que la afirmación coincide exactamente (incluida la barra diagonal final)
401 Unauthorized Desajuste de audiencia Compruebe que la reclamación coincide con su valor configurado aud
401 Unauthorized Token expirado Adquisición de un token nuevo
401 Unauthorized Metadatos no disponibles Asegúrese de que DAB pueda llegar <issuer>/.well-known/openid-configuration
403 Forbidden Rol no presente en el token Adición del rol a la configuración de IdP
403 Forbidden No se encontró ninguna roles reclamación Configura tu IdP para incluir una roles reclamación
403 Forbidden Nombre de notificación incorrecto DAB usa el tipo de reclamación roles (fijo, no configurable)
403 Forbidden Notificación personalizada de autenticación0 quitada silenciosamente Auth0 puede descartar claims personalizados sin namespace. Compruebe que la roles declaración existe en el token decodificado en jwt.io. Consulte Auth0: Adición de roles con una acción

Importante

El tipo de notificación roles está codificado de forma fija en todas las comprobaciones de roles y no se puede cambiar. Configure su proveedor de identidad para emitir una declaración con el nombre exacto roles. Los usuarios de Auth0 deben revisar el conflicto de espacios de nombres.

Formatos de emisor comunes

Provider Formato del emisor
Okta https://<domain>.okta.com o https://<domain>.okta.com/oauth2/default
Auth0 https://<tenant>.auth0.com/ (tenga en cuenta la barra diagonal final)
Azure AD B2C https://<tenant>.b2clogin.com/<tenant-id>/v2.0/
Keycloak https://<host>/realms/<realm>

Ejemplo de configuración completa

Configuración de Okta

{
  "$schema": "https://github.com/Azure/data-api-builder/releases/latest/download/dab.draft.schema.json",
  "data-source": {
    "database-type": "mssql",
    "connection-string": "@env('SQL_CONNECTION_STRING')"
  },
  "runtime": {
    "host": {
      "authentication": {
        "provider": "Custom",
        "jwt": {
          "audience": "0oa1234567890abcdef",
          "issuer": "https://dev-12345.okta.com"
        }
      }
    }
  },
  "entities": {
    "Book": {
      "source": "dbo.Books",
      "permissions": [
        {
          "role": "authenticated",
          "actions": ["read"]
        },
        {
          "role": "editor",
          "actions": ["create", "read", "update"]
        }
      ]
    }
  }
}

Configuración de Auth0

{
  "$schema": "https://github.com/Azure/data-api-builder/releases/latest/download/dab.draft.schema.json",
  "data-source": {
    "database-type": "mssql",
    "connection-string": "@env('SQL_CONNECTION_STRING')"
  },
  "runtime": {
    "host": {
      "authentication": {
        "provider": "Custom",
        "jwt": {
          "audience": "https://my-api.example.com",
          "issuer": "https://my-tenant.auth0.com/"
        }
      }
    }
  },
  "entities": {
    "Book": {
      "source": "dbo.Books",
      "permissions": [
        {
          "role": "authenticated",
          "actions": ["read"]
        },
        {
          "role": "admin",
          "actions": ["*"]
        }
      ]
    }
  }
}