El complemento hmac-auth genera firmas imposibles de falsificar para las solicitudes HTTP mediante el algoritmo HMAC. Estas firmas se utilizan para la autenticación de identidad.
Tipo de complemento
Autenticación y autorización.
Campos
Configuración de autenticación
|
Campo |
Tipo de dato |
Obligatorio |
Valor predeterminado |
Descripción |
|
consumers |
array of object |
Sí |
- |
Los invocadores del servicio, que se usan para autenticar las solicitudes. |
|
date_offset |
number |
No |
- |
La desviación máxima de tiempo del cliente permitida, en segundos. El sistema analiza sintácticamente la hora UTC del cliente a partir del encabezado de solicitud |
|
global_auth |
array of string |
No (obligatorio solo para configuraciones a nivel de instancia) |
- |
Solo a nivel de instancia. Si se establece en true, la autenticación surte efecto de forma global. Si se establece en false, aplica únicamente a los nombres de dominio y rutas configurados. Cuando no se configura, la autenticación surte efecto global solo si no hay nombres de dominio ni rutas definidos. |
Campos dentro de consumers:
|
Campo |
Tipo de dato |
Obligatorio |
Valor predeterminado |
Descripción |
|
key |
string |
Sí |
- |
La clave de acceso del consumidor. |
|
secret |
string |
Sí |
- |
El secreto que se usa para generar la firma. |
|
name |
string |
Sí |
- |
El nombre del consumidor. |
(Opcional) Configuración de autorización
|
Campo |
Tipo de dato |
Obligatorio |
Valor predeterminado |
Descripción |
|
allow |
array of string |
No (obligatorio para configuraciones que no son a nivel de instancia) |
- |
Se configura únicamente a nivel de ruta o de nombre de dominio. Especifica qué consumidores tienen permitido acceder a las solicitudes coincidentes para lograr un control de permisos detallado. |
Las configuraciones de autorización y de autenticación no pueden coexistir en la misma regla.
En las solicitudes autenticadas, se añade el encabezado
X-Mse-Consumerpara identificar al invocador.
Ejemplos
Configurar la autenticación de forma global y definir la autorización para rutas
El siguiente ejemplo habilita la autenticación hmac-auth para rutas o dominios específicos. El campo key debe ser único.
Aplique a continuación las configuraciones del complemento a nivel de instancia:
global_auth: false
consumers:
- key: appKey-example-1
secret: appSecret-example-1
name: consumer-1
- key: appKey-example-2
secret: appSecret-example-2
name: consumer-2
Aplique a continuación la configuración del complemento a las rutas route-a y route-b:
allow:
- consumer1
Aplique a continuación la configuración del complemento a los nombres de dominio *.example.com y test.com:
allow:
- consumer2
En este ejemplo, las rutas
route-ayroute-bcorresponden a las que se especificaron al crear las rutas de la puerta de enlace. Si una solicitud del cliente coincide con alguna de ellas, se permite el acceso a la puerta de enlace al invocador cuyonameesconsumer1. Los demás invocadores no tienen acceso.Los nombres de dominio
*.example.comytest.comsirven para hacer coincidir los dominios de las solicitudes. Cuando una petición del cliente coincide con uno de ellos, se autoriza el acceso a la puerta de enlace al invocador cuyonameesconsumer2. El resto de los invocadores no puede acceder.
Habilitar el complemento traffic-tag para puertas de enlace
global_auth: true
consumers:
- key: appKey-example-1
secret: appSecret-example-1
name: consumer-1
- key: appKey-example-2
secret: appSecret-example-2
name: consumer-2
Mecanismo de firma
Preparativos de configuración
Configure las siguientes credenciales para generar y validar firmas:
key: se utiliza en el encabezado de solicitud
x-ca-key.secret: sirve para generar la firma de la solicitud.
Generar una firma en el cliente
Proceso
El cliente genera una firma mediante estos pasos:
Extraiga los datos clave de la solicitud original para generar una cadena de firma.
Cifre la cadena de firma con el
secretconfigurado para obtener la firma.Agregue todos los encabezados relacionados con la firma a la solicitud HTTP original.
Extraer una cadena de firma
El cliente extrae los datos clave de la solicitud HTTP y los combina en una cadena de firma con el formato a continuación:
HTTPMethod
Accept
Content-MD5
Content-Type
Date
Headers
PathAndParameters
Estos campos se separan con \n. Si el campo Headers está vacío, no se requiere \n. Para los demás campos vacíos, se debe conservar \n. La firma distingue entre mayúsculas y minúsculas.
Reglas de extracción para cada campo:
HTTPMethod: el método HTTP, como POST. Debe estar en mayúsculas.
Accept: el valor del encabezado de solicitud Accept. Puede estar vacío. Se recomienda establecer explícitamente el encabezado Accept, ya que algunos clientes HTTP usan
*/*de manera predeterminada, lo cual provoca errores en la comprobación de la firma.-
Content-MD5: el valor del encabezado Content-MD5. Puede estar vacío. Se calcula únicamente cuando la solicitud contiene un cuerpo que no es de formulario. Ejemplo en Java:
String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8"))); Content-Type: el valor del encabezado Content-Type. Puede estar vacío.
Date: el valor del encabezado Date, que se usa para comprobar la desviación de tiempo. Puede estar vacío si no se configura
date_offset.-
Headers: los encabezados incluidos en la firma. Reglas de concatenación:
-
Ordene las claves de los encabezados alfabéticamente y concaténelas de la siguiente manera:
HeaderKey1 + ":" + HeaderValue1 + "\n"\+ HeaderKey2 + ":" + HeaderValue2 + "\n"\+ ... HeaderKeyN + ":" + HeaderValueN + "\n" Si el valor de un encabezado está vacío, use HeaderKey + ":" + "\n" para la firma. Debe conservar la clave y los dos puntos (:).
Las claves de encabezado utilizadas para la firma se separan con comas (,) y se colocan en el encabezado
X-Ca-Signature-Headers.Los siguientes encabezados no se pueden usar en el cálculo de la firma: X-Ca-Signature, X-Ca-Signature-Headers, Accept, Content-MD5, Content-Type y Date.
-
-
PathAndParameters: contiene la ruta y los parámetros de consulta y de formulario.
Path + "?" + Key1 + "=" + Value1 + "&" + Key2 + "=" + Value2 + ... "&" + KeyN + "=" + ValueN
Las claves de los parámetros de consulta y de formulario se ordenan alfabéticamente y luego se concatenan como se describió anteriormente.
Si los parámetros de consulta y de formulario están vacíos, utilice únicamente la ruta sin agregar información de firma.
En los parámetros de arreglo que comparten la misma clave pero tienen valores distintos, solo se usa el primer valor para calcular la firma.
Ejemplo de extracción de una cadena de firma
Solicitud HTTP inicial:
POST /http2test/test?param1=test HTTP/1.1
host:api.alibabacloud.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
content-length:33
username=xiaoming&password=123456789
Cadena de firma generada:
POST
application/json; charset=utf-8
application/x-www-form-urlencoded; charset=utf-8
Wed, 09 May 2018 13:30:29 GMT+00:00
x-ca-key:203753385
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-signature-method:HmacSHA256
x-ca-timestamp:1525872629832
/http2test/test?param1=test&password=123456789&username=xiaoming
Calcular una firma
Una vez generada la cadena de firma, el cliente la cifra y la codifica para producir la firma final.
En este código, stringToSign es la cadena de firma extraída, secret proviene de la configuración del complemento y sign es la firma final.
Mac hmacSha256 = Mac.getInstance("HmacSHA256");
byte[] secretBytes = secret.getBytes("UTF-8");
hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA256"));
byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
String sign = Base64.encodeBase64String(result);
La cadena stringToSign se decodifica en un arreglo de bytes UTF-8, se cifra con el algoritmo HMAC y después se codifica en Base64 para generar la firma.
Agregar una firma
Incluya los siguientes encabezados en las solicitudes enviadas a Cloud-native API Gateway para que se compruebe la firma:
x-ca-key: el AppKey. Obligatorio.
x-ca-signature-method: el algoritmo de firma. Opcional. Valores válidos: HmacSHA256 y HmacSHA1. Valor predeterminado: HmacSHA256.
x-ca-signature-headers: todas las claves de encabezado de firma, separadas por comas (,). Opcional.
x-ca-signature: la firma. Obligatorio.
Ejemplo de solicitud HTTP con firma:
POST /http2test/test?param1=test HTTP/1.1
host:api.alibabacloud.com
accept:application/json; charset=utf-8
ca_version:1
content-type:application/x-www-form-urlencoded; charset=utf-8
x-ca-timestamp:1525872629832
date:Wed, 09 May 2018 13:30:29 GMT+00:00
user-agent:ALIYUN-ANDROID-DEMO
x-ca-nonce:c9f15cbf-f4ac-4a6c-b54d-f51abf4b5b44
x-ca-key:203753385
x-ca-signature-method:HmacSHA256
x-ca-signature-headers:x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method
x-ca-signature:xfX+bZxY2yl7EB/qdoDy9v/uscw3Nnj1pgoU+Bm6xdM=
content-length:33
username=xiaoming&password=123456789
Comprobar la firma en el servidor
Proceso
El servidor comprueba la firma del cliente mediante estos pasos:
Extraiga los datos clave de la solicitud para obtener una cadena de firma.
Lea el
keyde la solicitud y busque elsecretcorrespondiente.Cifre la cadena de firma con el
secretpara generar una firma.Compare la firma generada en el servidor con la firma del cliente incluida en la solicitud.
Solucionar errores de firma
Cuando falla la comprobación de la firma, el servidor devuelve el StringToSign generado en su lado dentro del encabezado de respuesta X-Ca-Error-Message. Compárelo con el StringToSign del cliente para identificar la discrepancia.
Si ambos valores coinciden, compruebe el AppSecret utilizado para calcular la firma.
Los encabezados HTTP no admiten saltos de línea, por lo que los saltos de línea en StringToSign se reemplazan con #.
X-Ca-Error-Message: Server StringToSign:`GET#application/json##application/json##X-Ca-Key:200000#X-Ca-Timestamp:1589458000000#/app/v1/config/keys?keys=TEST`
Códigos de error
|
Código de estado HTTP |
Mensaje de error |
Motivo |
|
400 |
Invalid Signature. |
La firma en x-ca-signature no coincide con la firma calculada por el servidor. |
|
400 |
Invalid Content-MD5. |
El encabezado de solicitud Content-MD5 no es válido. |
|
400 |
Invalid Date. |
La desviación de tiempo del encabezado de solicitud Date supera el valor configurado en date_offset. |
|
401 |
Invalid Key. |
Falta el encabezado de solicitud x-ca-key o no es válido. |
|
401 |
Empty Signature. |
El encabezado de solicitud x-ca-signature está vacío. |
|
403 |
Unauthorized Consumer. |
El invocador de la solicitud no tiene permisos de acceso. |
|
413 |
Request Body Too Large. |
El cuerpo de la solicitud supera los 32 MB. |
|
413 |
Payload Too Large. |
El cuerpo de la solicitud supera el límite DownstreamConnectionBufferLimits configurado para la puerta de enlace. Puede aumentar DownstreamConnectionBufferLimits en la página de configuración de parámetros. |
Aumentar DownstreamConnectionBufferLimits incrementa significativamente el uso de memoria de la puerta de enlace. Proceda con precaución.