OpenSearch autentica cada solicitud de API mediante cifrado simétrico basado en pares de AccessKey. Cada par consta de un AccessKey ID y un AccessKey secret: el AccessKey ID identifica al solicitante y el AccessKey secret firma la solicitud. Mantenga su AccessKey secret en estricta confidencialidad.
OpenSearch proporciona SDK para Java, PHP, Python y C#. Los SDK de PHP, Python y C# incluyen implementaciones de firma integradas. Si hay un SDK disponible para su lenguaje, úselo y omita este tema. Si necesita implementar la firma manualmente o depurar un error de firma, siga los pasos que se muestran a continuación.
OpenSearch no mantiene los SDK implementados a partir de este tema ni el código fuente de los SDK oficiales. Los usuarios deben mantener estos SDK por su cuenta.
Requisitos previos
Antes de empezar, asegúrese de tener:
Un AccessKey ID y un AccessKey secret obtenidos desde la consola de Alibaba Cloud
Una aplicación de OpenSearch (Advanced o Standard)
Cómo funciona
La firma de una solicitud incluye seis pasos:
Construya la cadena
CanonicalizedOpenSearchHeadersa partir de todos los encabezados de solicitudX-Opensearch-*.Construya la cadena
CanonicalizedResourcea partir de la ruta de solicitud y los parámetros de consulta.Ensamble la cadena para firmar a partir del método HTTP, los encabezados y los componentes canonizados.
Calcule la firma HMAC-SHA1 sobre la cadena para firmar con el AccessKey secret.
Codifique en Base64 el resumen HMAC para obtener el valor final de la firma.
Establezca el encabezado
Authorizationcon el AccessKey ID y la firma.
Protocolos y métodos de solicitud compatibles
OpenSearch API V3 usa solo HTTP.
Envíe solicitudes
GETpara buscar datos.Envíe solicitudes
POSTpara insertar datos.
Paso 1: Construya CanonicalizedOpenSearchHeaders
CanonicalizedOpenSearchHeaders contiene todos los encabezados de solicitud que tienen el prefijo X-Opensearch- (por ejemplo, X-Opensearch-Nonce). Si la solicitud no tiene encabezados X-Opensearch-*, omita este componente por completo de la cadena para firmar.
Para construir la cadena:
Asigne valores a todos los encabezados
X-Opensearch-*. Omita cualquier encabezado cuyo valor esté vacío.Ordene alfabéticamente por nombre los encabezados restantes.
Convierta cada nombre de encabezado a minúsculas (por ejemplo,
X-Opensearch-Noncese convierte enx-opensearch-nonce).Quite todos los espacios alrededor del delimitador
:en cada par encabezado-valor (por ejemplo,x-opensearch-nonce : valuese convierte enx-opensearch-nonce:value).Una todos los pares encabezado-valor con
\ny agregue\ndespués del último par.
Al agregar los encabezadosX-Opensearch-*a la solicitud HTTP real, use el formato original con mayúsculas y minúsculas (X-Opensearch-Nonce), no la forma en minúsculas que se usa para firmar.
Formato de X-Opensearch-Nonce: una marca de tiempo de 10 dígitos concatenada con un valor aleatorio de 6 dígitos en el rango 100000–999999 (por ejemplo, 155108**********).
Paso 2: Construya CanonicalizedResource
El formato depende del tipo de solicitud:
Solicitudes de búsqueda:
path + ? + querySolicitudes de inserción: solo
path
Construya la ruta
Codifique la cadena de ruta sin procesar, reemplace %2F con / y reemplace app_schema_demo por el nombre de su aplicación:
|
Tipo de solicitud |
Formato de ruta |
|
Búsqueda de datos |
|
|
Búsqueda por sugerencia |
|
|
Búsqueda por ID de aplicación |
|
|
Inserción de datos |
|
Construya la cadena de consulta (solo solicitudes de búsqueda)
Asigne un valor a cada parámetro de consulta. Omita los parámetros con valores vacíos.
Ordene los parámetros alfabéticamente, primero por clave y después por valor.
Codifique cada clave y valor como URL conforme a RFC 3986. Una cada par con
=.Una todos los pares con
&.Concatene las cláusulas de consulta dentro del parámetro
querycon&&antes de codificar.
Ejemplo de CanonicalizedResource para una solicitud de búsqueda:
/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson
Paso 3: Ensamble la cadena para firmar
"Authorization: OPENSEARCH " + AccessKeyId + ":" + Signature
Signature = base64(hmac-sha1(AccessKeySecret,
VERB + "\n"
+ Content-MD5 + "\n"
+ Content-Type + "\n"
+ Date + "\n"
+ CanonicalizedOpenSearchHeaders
+ CanonicalizedResource))
Todos los parámetros deben aparecer en el orden que se muestra arriba. La cadena para firmar debe estar codificada en UTF-8. Si la cadena contiene caracteres chinos, codifíquelos en UTF-8 antes de calcular el HMAC.
Incluya un espacio después deOPENSEARCHen el valor del encabezadoAuthorization.
Parámetros
|
Parámetro |
Obligatorio |
Descripción |
|
|
Sí |
Su AccessKey ID. Se incluye en el encabezado |
|
|
Sí |
Su AccessKey secret. Se usa para calcular el HMAC. Nunca se incluye en la solicitud. |
|
|
Sí |
Método HTTP: |
|
|
Condicional |
El valor MD5 del cuerpo de la solicitud HTTP (ejemplo: |
|
|
— |
Tipo de medio del cuerpo de la solicitud (ejemplo: |
|
|
Sí |
Marca de tiempo de la solicitud en formato ISO 8601: |
|
|
Condicional |
Todos los encabezados |
|
|
Sí |
La ruta de solicitud y la cadena de consulta canonizadas. |
Paso 4: Calcule la firma HMAC-SHA1
Use HMAC-SHA1 tal como se define en RFC 2104 para calcular la firma sobre la cadena para firmar, con el AccessKey secret como clave.
Paso 5: Codifique en Base64 el resumen
Codifique en Base64 los bytes del resumen HMAC-SHA1 sin procesar para generar el valor final de la firma.
Paso 6: Establezca el encabezado Authorization
Authorization: OPENSEARCH <AccessKeyId>:<Signature>
Ejemplo en Python 3:
headers['Authorization'] = 'OPENSEARCH ' + 'LTAI****************' + ':' + '1P7tfE****'
Encabezados obligatorios por tipo de solicitud
Solicitudes de búsqueda
|
Parámetro de firma |
Obligatorio |
Encabezado de solicitud |
Obligatorio |
|
|
Sí |
|
Sí |
|
|
Sí |
|
Sí |
|
|
Sí |
|
Sí |
|
|
Sí |
||
|
|
Sí |
Solicitudes de inserción
|
Parámetro de firma |
Obligatorio |
Encabezado de solicitud |
Obligatorio |
|
|
Sí |
|
Sí |
|
|
Sí |
|
Sí |
|
|
Sí |
|
Sí |
|
|
Sí |
||
|
|
Sí |
Los valores de encabezado enviados en la solicitud HTTP deben coincidir exactamente con los valores usados durante el cálculo de la firma. Incluya los encabezados Content-MD5, Content-Type, Date, CanonicalizedOpenSearchHeaders y Authorization en todas las solicitudes para evitar errores.
Ejemplo completo
Este ejemplo firma una solicitud de búsqueda con los valores que se muestran a continuación:
|
Componente |
Valor |
|
Método de solicitud |
|
|
AccessKey secret |
|
|
Content-MD5 |
(en blanco; la solicitud de búsqueda no tiene cuerpo) |
|
Content-Type |
|
|
Date |
|
|
CanonicalizedOpenSearchHeaders |
|
|
CanonicalizedResource |
|
Cadena para firmar (use este valor intermedio para que compruebe su implementación):
GET\n
\n
application/json\n
2019-02-25T10:09:57Z\n
x-opensearch-nonce:1551089397451704\n
/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson
Cálculo de la firma (Python 3):
import hmac
import base64
signature_string = '\n'.join([
'GET',
'',
'application/json',
'2019-02-25T10:09:57Z',
'x-opensearch-nonce:1551089397451704',
'/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson'
])
signature_hmac = hmac.new(
'yourAccessKeySecret'.encode('utf-8'),
signature_string.encode('utf-8'),
'sha1'
)
signature = base64.b64encode(signature_hmac.digest())
Firma final: 1P7tfE****
Encabezados de solicitud:
Content-MD5:
Content-Type: application/json
Authorization: OPENSEARCH LTAI****************:1P7tfE****
X-Opensearch-Nonce: 1551089397451704
Date: 2019-02-25T10:09:57Z
Formato de la cadena de solicitud
Una URL de solicitud completa tiene el formato host + CanonicalizedResource. En una cadena de solicitud, host especifica el endpoint de la API de OpenSearch.
|
Tipo de solicitud |
URL de ejemplo |
|
Búsqueda de datos |
|
|
Búsqueda por sugerencia |
|
|
Búsqueda por ID de aplicación |
|
|
Inserción de datos |
|
Plantilla de esquema de aplicación
{
"name": "app_schema_demo",
"type": "standard",
"schema": {
"indexes": {
"search_fields": {
"id": {
"fields": ["id"]
},
"name": {
"fields": ["name"],
"analyzer": "chn_standard"
},
"phone": {
"fields": ["phone"],
"analyzer": "fuzzy"
},
"int_arr": {
"fields": ["int_arr"]
},
"literal_arr": {
"fields": ["literal_arr"]
},
"cate_id": {
"fields": ["cate_id"]
}
},
"filter_fields": ["id", "int_arr", "literal_arr", "float_arr", "cate_id"]
},
"tables": {
"tab": {
"name": "tab",
"fields": {
"id": { "name": "id", "type": "INT", "primary_key": true },
"name": { "name": "name", "type": "TEXT", "primary_key": false },
"phone": { "name": "phone", "type": "SHORT_TEXT", "primary_key": false },
"int_arr": { "name": "int_arr", "type": "INT_ARRAY", "primary_key": false },
"literal_arr": { "name": "literal_arr", "type": "LITERAL_ARRAY", "primary_key": false },
"float_arr": { "name": "float_arr", "type": "FLOAT_ARRAY", "primary_key": false },
"cate_id": { "name": "cate_id", "type": "INT", "primary_key": false }
},
"primary_table": true
}
},
"route_field": null
},
"data_sources": [],
"first_ranks": {},
"second_ranks": {},
"summary": [],
"fetch_fields": ["id", "name", "phone", "int_arr", "literal_arr", "float_arr", "cate_id"],
"quota": {
"qps": 6,
"doc_size": 0.3
}
}
Solución de problemas
Error HTTP 403 en todas las solicitudes
La causa más común es una marca de tiempo fuera de la ventana de tolerancia de 15 minutos. Asegúrese de que el encabezado Date use la hora UTC actual en formato ISO 8601 (YYYY-MM-DDThh:mm:ssZ) y de que el reloj de su sistema esté sincronizado.
La firma no coincide
Compruebe los puntos que se indican a continuación, en orden:
Compruebe que la cadena para firmar coincide con el valor intermedio del ejemplo anterior: calcule la cadena para firmar de su solicitud y regístrela antes de calcular el hash.
Confirme que
Content-MD5está en blanco para las solicitudesGET.Confirme que los nombres de encabezado de
CanonicalizedOpenSearchHeadersestán en minúsculas y ordenados alfabéticamente.Confirme que las cláusulas del parámetro
queryse concatenan con&&antes de codificar la URL.Confirme que la cadena para firmar y el AccessKey secret están codificados en UTF-8 antes de calcular el HMAC.