Nota:
- Este tutorial requiere acceso a Oracle Cloud. Para registrarse en una cuenta gratuita, consulte Introducción a la capa gratuita de Oracle Cloud Infrastructure.
- Utiliza valores de ejemplo para las credenciales, el arrendamiento y los compartimentos de Oracle Cloud Infrastructure. Al finalizar el laboratorio, sustituya estos valores por otros específicos de su entorno en la nube.
Utilice el gateway de API de Oracle Cloud para crear un servicio de descarga seguro del almacenamiento de objetos con autenticación de función
Introducción
El almacenamiento de objetos de Oracle Cloud es una forma muy barata y eficaz de almacenar archivos grandes o pequeños. El almacenamiento de objetos permite trabajar en una arquitectura basada en eventos, lo que hace que la ejecución del proceso esté cerca de tiempo real. Puede configurar eventos en Object Storage para disparar eventos, y también puede crear servicios REST para escribir o leer archivos de Object Storage de forma segura, rápida y económica.
Si está interesado en ver cómo implantar una arquitectura basada en eventos, consulte Procesar archivos grandes en Autonomous Database y Kafka con Oracle Cloud Infrastructure Data Flow.
Arquitectura

Integración de Oracle API Gateway

En este tutorial, mostramos cómo configurar Oracle API Gateway para implantar un servicio REST mediante una función que permita, de forma flexible, autenticar un token de JWT mediante un proveedor de identidad externo u Oracle Cloud Infrastructure (OCI) en sí (Oracle Identity Cloud Service). Independientemente del proceso, puede validar el token de JWT (ya que un atributo puede formar parte del nombre de archivo), utilizar los servicios de OCI a través de su SDK y otros procesos personalizables.
Objetivos
- Muestre un servicio REST de API para descargar un archivo del almacenamiento de objetos de una forma segura.
- Uso de la autenticación de OCI API Gateway con funciones de OCI
- Devolver un enlace autenticado previamente con un tiempo de límite de 60 segundos para la descarga
- Configurar una configuración de Observability para supervisar la escritura y lectura de archivos
Requisitos
-
Cubo de OCI Object Storage creado y configurado con políticas necesarias para escribir y leer archivos. Consulte Seguridad de almacenamiento de objetos.
-
Un inquilino operativo de Oracle Cloud: puede crear una cuenta gratuita de Oracle Cloud con $ 300.00 durante un mes para probar este tutorial. Consulte Creación de una cuenta gratuita de Oracle Cloud.
-
Interfaz de línea de comandos de Oracle Cloud (CLI de OCI)) instalada en la máquina local: este es el enlace para instalar la CLI de OCI.
-
Funciones de OCI y políticas configuradas para desarrollo. Este ejemplo se implanta en Python. Para obtener más información, consulte las guías de las funciones QuickStart.
-
Una instancia de gateway de API de OCI creada y expuesta a Internet. Consulte Creación de su primer gateway de API en Oracle Cloud.
-
Acceso a Oracle Identity Cloud Service.
Tarea 1: Configurar una aplicación en Oracle Identity Cloud Service
Puede configurar cualquier proveedor de identidad externo de API de REST para que funcione con JWT, como Auth0 y Oracle Identity Cloud Service.
En este tutorial, trabajaremos con Oracle Identity Cloud Service y llamaremos a la autenticación dentro de la función.
-
Cree una aplicación en Oracle Identity Cloud Service, en este ejemplo, denominada my-client-app.
-
Seleccione las opciones Credenciales de cliente y Afirmación JWT.
-
Para obtener detalles de configuración, consulte Protección de API con gateway de API mediante Oracle Identity Cloud Service/IAM JWT con ámbitos y reclamaciones.
Nota: este ejemplo de autenticación solo refleja una situación hipotética para identificar al usuario y otra información sobre el cubo. Puede que esto no refleje la mejor manera de autenticar y autorizar una aplicación y se recomienda que se evalúe según los estándares de la compañía.

-
Guarde y active la aplicación. Puede obtener clientID y secretID para usar en la siguiente sección.

Tarea 2: Revisar el código
Este es el código de Python que se utiliza en un despliegue de gateway de API para autorizar un enlace de autenticación previa para descargar un archivo en Object Storage.
Puede descargar el código de Python aquí: Python fn Project.
python
import io
import json
import logging
import datetime
import jwt
import requests
import base64
import oci
from datetime import timedelta
from fdk import response
from py_zipkin import Encoding #import Zipkin package
from py_zipkin.zipkin import zipkin_span #import Zipkin package
from transport import http_transport #import Zipkin transport
@zipkin_span(service_name='Status: Load File', span_name='statusGetFile')
def auth(ctx, data: io.BytesIO = None):
auth_token = "invalid"
token = "invalid"
apiKey = "invalid"
expiresAt = (datetime.datetime.utcnow() + timedelta(seconds=60)).replace(tzinfo=datetime.timezone.utc).astimezone().replace(microsecond=0).isoformat()
config = oci.config.from_file("config")
object_storage = oci.object_storage.ObjectStorageClient(config)
namespace = object_storage.get_namespace().data
try:
auth_token = json.loads(data.getvalue())
secretID = auth_token.get("secretID")
clientID = auth_token.get("clientID")
details = oci.object_storage.models.CreatePreauthenticatedRequestDetails(name="data", access_type="AnyObjectReadWrite", bucket_listing_action="ListObjects", time_expires=expiresAt)
preauth = object_storage.create_preauthenticated_request(namespace_name=namespace, bucket_name="data", create_preauthenticated_request_details=details)
preauthstr = str(preauth.data)
auth = clientID + ":" + secretID
auth_bytes = auth.encode("ascii")
auth_base64_bytes = base64.b64encode(auth_bytes)
auth_base64_message = auth_base64_bytes.decode("ascii")
headers = {"Authorization": "Basic " + auth_base64_message, "Content-Type": "application/x-www-form-urlencoded"}
scope = "cihxxxxxxxxxxxxxxxxxowu.apigateway.us-ashburn-1.oci.customer-oci.com/super-scope"
grant_type = "client_credentials"
body = {"scope": scope, "grant_type": grant_type}
url_post = "https://Oracle Identity Cloud Service-4fxxxxxxxxxxxxxxxxxxxxxx9.identity.oraclecloud.com/oauth2/v1/token"
post_response = requests.post(url_post, headers=headers, data=body)
jwtTokenDecoded = jwt.decode(post_response.json()['access_token'], options={"verify_signature": False})
return response.Response(
ctx,
status_code=200,
response_data=json.dumps({"active": True, "principal": "foo", "scope": "bar", "clientId": "1234", "expiresAt": expiresAt, "context": {"username": "wally", "token":
post_response.json()['access_token'], "jwtTokenDecoded": jwtTokenDecoded, "objectID": preauthstr}})
)
except (Exception, ValueError) as ex:
logging.getLogger().info('error parsing json payload: ' + str(ex))
pass
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": "API-key"})
)
@zipkin_span(service_name='Status: Load File', span_name='statusGetFile')
def handler(ctx, data: io.BytesIO = None):
with zipkin_span(
service_name="Status: Load File", #You can change it as you need
span_name="statusGetFile", #You can change it as you need
transport_handler=http_transport, #zipkin transport, will use it to upload trace data to OCI APM
encoding = Encoding.V2_JSON,
binary_annotations = {"status":"Load File", "objectID":json.loads(data.getvalue()).get("objectID")}, #Custom tag
sample_rate=100 # this is optional and can be used to set custom sample rates
):
return auth(ctx, data)
Analicemos el código en partes para comprender cómo:
- Siga los procesos de OCI Observability
- Configure un enlace de autenticación previa para descargar un archivo en Object Storage
- Autenticar con un proveedor de identidad y obtener un token de JWT
- Decodificar un token de JWT y utilizar la información del proceso
- Devolver un estado correcto o fallido en el despliegue de gateway de API
Esta parte del código guarda una posición de estado en OCI Observability. Utiliza el marco Zipkin para publicar en OCI APM Observability
python
@zipkin_span(service_name='Status: Load File', span_name='statusGetFile')
def handler(ctx, data: io.BytesIO = None):
with zipkin_span(
service_name="Status: Load File", #You can change it as you need
span_name="statusGetFile", #You can change it as you need
transport_handler=http_transport, #zipkin transport, will use it to upload trace data to OCI APM
encoding = Encoding.V2_JSON,
binary_annotations = {"status":"Load File", "objectID":json.loads(data.getvalue()).get("objectID")}, #Custom tag
sample_rate=100 # this is optional and can be used to set custom sample rates
):
Esta es la vista Consola de OCI APM del código y puede encontrar sus archivos con consultas como:
**ServiceName** = 'Status: Load File' and **objectID** = '50 - DR-HA OIC.pdf'

El siguiente código establece una fecha y hora de caducidad para el archivo de Object Storage. Se generará una autenticación previa y se utilizará el atributo expiresAt para este objetivo. timedelta agregue 60 segundos desde la hora actual para descargar el archivo.
python
expiresAt = (datetime.datetime.utcnow() + timedelta(seconds=60)).replace(tzinfo=datetime.timezone.utc).astimezone().replace(microsecond=0).isoformat()
Ahora, debemos inicializar el marco de OCI Object Storage en función de las credenciales guardadas en la instalación de la CLI de OCI. La configuración de la CLI de OCI utiliza ~/.oci/config y el archivo .pem del certificado. Por lo tanto, puede instalar la CLI de OCI localmente y configurar un usuario para acceder al almacenamiento de objetos (consulte la documentación de OCI para instalar la CLI de OCI y las políticas de almacenamiento de objetos en la sección Enlaces relacionados) y, a continuación, copiar estos 2 archivos en este proyecto fn.
python
config = oci.config.from_file("config")
object_storage = oci.object_storage.ObjectStorageClient(config)
namespace = object_storage.get_namespace().data
El siguiente paso procederá de los valores de parámetros Cuerpo: secretID, clientID y objectID.
#secretID = the Oracle Identity Cloud Service secretID from the application created to validate the JWT Token
#clientID = the Oracle Identity Cloud Service clientID from the application created to validate the JWT Token
#objectID = the file name in the Object Storage
python
try:
auth_token = json.loads(data.getvalue())
secretID = auth_token.get("secretID")
clientID = auth_token.get("clientID")
objectID = auth_token.get("objectID")
El SDK de OCI puede soportar Object Storage para muchos servicios, como leer y/o escribir un archivo, mostrar el contenido de un cubo y otros. Por ejemplo, puede activar que el consumidor muestre todo el contenido de un cubo con una URL autenticada previamente que se generará en esta parte del código. La variable bucket_name contiene el nombre del cubo en el Object Storage creado anteriormente y time_expires representa la fecha y la hora de caducidad para descargar el archivo.
python
details = oci.object_storage.models.CreatePreauthenticatedRequestDetails(name="data", access_type="AnyObjectReadWrite", bucket_listing_action="ListObjects", time_expires=expiresAt)
preauth = object_storage.create_preauthenticated_request(namespace_name=namespace, bucket_name="data", create_preauthenticated_request_details=details)
preauthstr = str(preauth.data)
Esta parte del código llama a Oracle Identity Cloud Service para validar clientID y secretID para obtener el token JWT. Un JWT se puede descodificar en una cadena JSON, en este caso, sin firma, pero la firma se puede verificar fácilmente con un certificado.
python
auth = clientID + ":" + secretID
auth_bytes = auth.encode("ascii")
auth_base64_bytes = base64.b64encode(auth_bytes)
auth_base64_message = auth_base64_bytes.decode("ascii")
headers = {"Authorization": "Basic " + auth_base64_message, "Content-Type": "application/x-www-form-urlencoded"}
scope = "xxxxxxxxxxxxxxxxxxxx.apigateway.us-ashburn-1.oci.customer-oci.com/super-scope"
grant_type = "client_credentials"
body = {"scope": scope, "grant_type": grant_type}
url_post = "https://Oracle Identity Cloud Service-xxxxxxxxxxxxxxxxxxxxxxx.identity.oraclecloud.com/oauth2/v1/token"
post_response = requests.post(url_post, headers=headers, data=body)
jwtTokenDecoded = jwt.decode(post_response.json()['access_token'], options={"verify_signature": False})
Esta es la parte final, donde se devolverán todos los datos con el código 200. Puede devolver toda la información necesaria a la aplicación y esta parte del código valida la autenticación, lo que da como resultado el código 200 (autorizado/correcto) o 401 (no autorizado).
python
return response.Response(
ctx,
status_code=200,
response_data=json.dumps({"active": True, "principal": "foo", "scope": "bar", "clientId": "1234", "expiresAt": expiresAt, "context": {"username": "wally", "token": post_response.json()['access_token'], "jwtTokenDecoded": jwtTokenDecoded, "objectID": preauthstr}})
)
except (Exception, ValueError) as ex:
logging.getLogger().info('error parsing json payload: ' + str(ex))
pass
return response.Response(
ctx,
status_code=401,
response_data=json.dumps({"active": False, "wwwAuthenticate": "API-key"})
)
Tarea 3: Configurar el gateway de API de OCI para autenticarse con fn
El gateway de API de OCI puede desplegar una API como función de OCI. Como ha visto anteriormente, el código utiliza el cuerpo que contiene la información de clientID, secretID y objectID transferida por la configuración de gateway de API. Puede configurar el despliegue:



Después de guardar el despliegue, puede obtener el punto final de REST aquí. Recuerde que el punto final completo de su servicio de API de REST de Object Storage es este punto final más "/" al final (declaró / como su ruta de acceso anteriormente).

Tarea 4: Prueba del despliegue de gateway de API
Puede probar la aplicación con CURL o en Postman:
bash
curl --location 'https://xxxxxxxxxxxxxxxxxxx.apigateway.us-ashburn-1.oci.customer-oci.com/dummyauthorizer/' \
--header 'Content-Type: text/plain' \
--data '{"clientID": "e3exxxxxxxxxxxxxxxxxc2f", "secretID": "8exxxxxxx-fa5e-xxcf-8xxxc-xxxxxxxxxxx87", "objectID": "any-file.txt"}'
Nota: El atributo
objectIDse utiliza aquí solo para ilustrar la observabilidad y cómo mostrar el estado en el Explorador de rastreo de la consola de OCI.

Si todo está bien, puede ver el código de éxito 200:

Se generará una URL para el almacenamiento de objetos autenticado previamente y podrá descargar el archivo durante los próximos 60 segundos. Puede descargar el archivo siguiendo el ejemplo aquí:
https://objectstorage.us-ashburn-1.oraclecloud.com + [access_uri]
or
https://objectstorage.us-ashburn-1.oraclecloud.com/p/eL5C0R0luN_cTNn-vUF7_Dx_z2N4w7IXemKr5y61cSRxZZPRXcR2Yj1dNCaJBDK8/n/idavixsf5sbx/b/data/o/calico.yaml
Puede descargar, cargar o ver los archivos del cubo con esta línea de comandos:
- TO UPLOAD A FILE: `curl https://objectstorage.us-ashburn-1.oraclecloud.com/p/HoPudIF45Bj6J5-Qy3J1D9dOplLuKtECRFhvOTkKAtBjJXkOTDx0Pt8gXbOOEoRx/n/idavixsf5sbx/b/data/o/ --upload-file func.py`
- TO DOWNLOAD A FILE: `curl https://objectstorage.us-ashburn-1.oraclecloud.com/p/3ZyXd6PchrTFrp1oxmedamSG1ojwQa3BxPUyonAA-q1mf3QAe5STpDrt89eYITPf/n/idavixsf5sbx/b/data/o/func.py`
- TO LIST BUCKET: `curl https://objectstorage.us-ashburn-1.oraclecloud.com/p/ODVRMB71kD0SHWuoY4ojVd93nmIiy8u0zrxA56T7FBaohAgA7k8KOLAIlhxjcveE/n/idavixsf5sbx/b/data/o/``
Tarea 5: Configurar panel de control de observabilidad
Básicamente, cada recurso de OCI puede mostrar métricas en un panel de control y muchos eventos en estos recursos pueden disparar una acción. En esta demostración, puede configurar un panel de control para mostrar cuántos archivos se han escrito o leído en Object Storage:

Puede configurar la consulta del panel de control de la siguiente manera:
- Archivos de cubo = ObjectCount[1d].groupby(resourceID).count()
- Escrituras de cubo = PutRequests[5m].grouping().count()
- Lecturas de cubo = GetRequests[5m].grouping().count()
Enlaces relacionados
- Instalación de la CLI de OCI
- Seguridad de Object Storage
- Creación de su primer gateway de API en Oracle Cloud
- Guías de Functions QuickStart
- Ejemplos de Oracle Functions
- Transferencia de tokens a funciones de autorizador para agregar autenticación y autorización a despliegues de API
- Creación de un token de JWT en Java para Oracle Identity Cloud Service
- Métricas de almacenamiento de objetos
- Referencia de lenguaje de consulta de supervisión (MQL)
- Protección de las API con API Gateway mediante Oracle Identity Cloud Service/IAM JWT con ámbitos y reclamaciones
- Procese archivos de gran tamaño en Autonomous Database y Kafka con Oracle Cloud Infrastructure Data Flow
- Almacenamiento de objetos - Límites y uso de cargas de varias partes
Acuses de recibo
- Autor: Cristiano Hoshikawa (ingeniero de la solución Oracle LAD A-Team)
Más recursos de aprendizaje
Explore otros laboratorios en docs.oracle.com/learn o acceda a más contenido de aprendizaje gratuito en el canal YouTube de Oracle Learning. Además, visite education.oracle.com/learning-explorer para convertirse en un explorador de Oracle Learning.
Para obtener documentación sobre los productos, visite Oracle Help Center.
Use Oracle Cloud API Gateway to create a secure Object Storage download service with function authentication
F84019-01
July 2023
Copyright © 2023, Oracle and/or its affiliates.