JMeter HTTP Authorization Manager

La autenticación es el proceso de confirmar si un usuario o cliente es quien dice ser. El protocolo HTTP admite la autenticación como un medio para negociar el acceso a recursos de manera segura. Para hacer pruebas de performance con JMeter vamos a necesitar aprender a usar el JMeter HTTP Authorization Manager. En este post queremos explicar las básicas de la autenticación y cómo preparar una prueba con JMeter para poder manejarla adecuadamente. Gracias Belén Vignolo por la investigación y por escribir este artículo junto al equipo de performance de Abstracta.


Belen4.png
Belén Vignolo
Tester en Abstracta

¿Autenticación?

La solicitud HTTP inicial de un cliente suele ser una solicitud anónima, que no contiene ninguna información de autenticación. En este caso el servidor puede denegar la solicitud anónima, indicando que se requiere autenticación. Al rechazar una solicitud el servidor envía headers WWW-Authenticate para indicar el o los tipos de autenticación permitidos y así el cliente puede responder con la autenticación correcta. 

Una metáfora para intentar entender esto podría ser la siguiente:

  • Quiero entrar a una habitación, donde la puerta está cerrada. 
  • Primero intento abrir girando el pestillo de la puerta y empujando. La puerta solo se abre con la llave (la forma de autenticar que la persona es la correcta para entrar es en base a que esa persona posee algo, la llave). 
  • Ahí me doy cuenta que la puerta está cerrada (pero yo tenía que probar primero, porque no sabía que estaba cerrada). 
  • Entonces, tengo que usar una llave, que solo la tienen las personas autorizadas para entrar. 

Todo esto lo maneja el cliente, ya sea una app nativa, un sitio web, etc. En el caso de ser una web, lo maneja el browser automáticamente. O sea, yo pongo la URL a la que quiero acceder y ahí si el servidor me dice que necesito autenticarme, el browser me va a mostrar la página o ventana para ingresar la clave por ejemplo. 

Cuando vamos a hacer pruebas de performance vamos a tener que manejar todo este protocolo en nuestros scripts. Si querés ver cómo funcionan las herramientas de pruebas de performance, revisá este post.

A continuación vamos a ver cómo manejar 3 de los tipos de autenticación más populares con JMeter, entendiendo cómo funcionan y qué desafíos presentan. Estos son:

  • Basic
  • NTLM
  • Kerberos (Negotiate)

En todos los casos en JMeter agregamos el elemento de configuración HTTP Authorization Manager, pero teniendo diferentes configuraciones y consideraciones que explicaremos.

Basic

Es la forma más simple de autenticación web, pero también la menos segura ya que las credenciales se envían codificadas en base 64 y es fácilmente reversible. 

Cuando una aplicación utiliza esta autenticación, la respuesta de un pedido anónimo o con credenciales incorrectas incluirá el header WWW-Authenticate: Basic.

Si se quiere automatizar un flujo con un proceso de autenticación, en JMeter se puede usar preemptive authentication (autenticación anticipada), ya que podemos configurar el tipo de autenticación y no es necesaria la respuesta del servidor para saberlo. En este caso JMeter envía las credenciales directamente sin hacer el pedido anónimo antes.

Si quisiéramos desactivar este comportamiento para simular un usuario de forma más realista, se debería agregar httpclient4.auth.preemptive=false en el archivo jmeter.properties, pero actualmente no es posible ya que hay un issue abierto sobre esta funcionalidad. Otra opción es agregar un pedido http sin claves antes de la autenticación, tal como lo hace el browser.

Para autenticarse, una solicitud debe contener un header de la forma Authorization: Basic <credenciales>, donde “credenciales” es un string con el formato “usuario:contraseña” en base64.

Al enviar las credenciales no se utiliza cifrado ni hash, por esto es que se debe utilizar sobre HTTPS para que sea seguro, de otro modo el usuario y password viajaría por la red como texto plano. El header con las credenciales se debe enviar en cada pedido ya que no se utilizan cookies ni identificadores de sesión.

Para automatizar en JMeter, tal como ya mencionamos, agregamos el elemento de configuración HTTP Authorization Manager. Para el caso de autenticación Basic vamos a seguir los siguientes pasos:

Se debe especificar el usuario, la contraseña (si tiene) y el mecanismo (o sea el tipo de autenticación) debe ser Basic, opcionalmente se pueden especificar la URL base y el dominio:

URL base: nos permite utilizar diferentes credenciales para diferentes URLs agregando filas en el HTTP Authorization Manager.

JMeter utilizará las credenciales de la primera fila donde la URL base coincida con la URL utilizada en el pedido, por lo tanto si se quieren utilizar varias filas debemos ingresar más arriba las que utilicen URLs más específicas.

Dominio: es un contenedor lógico utilizado para administrar usuarios, computadoras y otros objetos.

A todos los pedidos que estén en el mismo thread group que el HTTP Authorization Manager, JMeter les agregará automáticamente un header de la forma Authorization: Basic usuario:contraseña (con usuario:contraseña en base 64), o si se ingresa un dominio: Authorization: Basic dominio\usuario:contraseña (con dominio\usuario:contraseña en base 64).

NTLM

La autenticación NT LAN Manager (NTLM) es un esquema challenge-response. Utiliza las credenciales de Windows para transformar los datos de challenge en lugar de enviar nombre de usuario y la contraseña no codificados. El challenge (también llamado nonce) es una cadena de números aleatorios que el servidor envía al cliente, este realiza una transformación que utiliza sus credenciales sobre el challenge, de esta forma se autentica y se evitan ataques de replay (se evita que alguien pueda autenticarse capturando el pedido y volviendolo a enviar, porque el challenge es diferente cada vez). 

La autenticación NTLM requiere múltiples intercambios entre cliente y servidor. Para esto, el servidor y cualquier proxy intermedio debe admitir conexiones persistentes (keep-alive) para completar con éxito la autenticación.

Si una aplicación utiliza este tipo de autenticación, al recibir un pedido no autenticado de un cliente incluirá el header WWW-Authenticate: NTLM en la respuesta.

Al automatizar en JMeter, en este caso se utilizan los mismos campos que en el anterior y el mismo mecanismo (Basic) ya que no existe un mecanismo específico para NTLM.

Al utilizar la implementación Java del http sampler, JMeter automáticamente utiliza las credenciales con las que se está logueado en Windows, ignorando el HTTP Authorization Manager. Reportamos este issue y nos respondieron que aunque no está especificado en la documentación se debe utilizar la implementación HttpClient4 para usar el HTTP Authorization Manager con este tipo de autenticación (NTLM). 

En un escenario real NTLM autentica cada conexión que hace el browser y no los pedidos, por eso no es necesario que el header de autenticación viaje en todos los pedidos de nuestro script. Entonces, podemos enviarlo solamente cuando comienza la conexión en el primer pedido.

Esto se puede hacer de 2 formas diferentes:

Opción 1) Moviendo el HTTP Authorization Manager para que solo afecte al primer pedido. Aunque esto fallaría si se corta la conexión, por ejemplo si hay una espera grande o si es un script largo.

Opción 2) Cambiando el mecanismo a Digest en el Authentication Manager.

En este caso si la conexión se corta vuelve a mandar las credenciales automáticamente.

Nota: hay sólo 4 mecanismos para seleccionar: Basic, Basic_Digest, Digest y Kerberos. Como no encontramos nada oficial que dijera cuál usar con NTLM acá planteamos cuál probamos y funcionó, considerando además que el tutorial en el blog de Blazemeter usaba Basic.

En las siguientes capturas se puede observar que el header de autorización lo envía solo en el primer pedido:

Pedidos siguientes:

JMeter no nos muestra que al intentar usar la autenticación anticipada envía las credenciales para la autenticación básica (usuario:contraseña en base 64). Esto puede producir un riesgo de seguridad ya que las credenciales no están encriptadas.

Kerberos (Negotiate)

Kerberos es un protocolo de autenticación que permite a dos ordenadores en una red insegura demostrar su identidad mutuamente de manera segura. Tanto cliente como servidor verifican la identidad uno del otro utilizando tickets y un tercero de confianza.

El cliente envía un pedido al KDC (Key Distribution Center) que contiene el ID del usuario, el KDC valida la existencia del usuario, genera una clave de sesión y responde con dos mensajes, uno está cifrado con la clave secreta del TGS (Ticket Granting Service) y el otro con la del cliente.

El cliente descifra la clave de sesión, envía un pedido al TGS y obtiene un ticket y una clave de sesión. Luego envía un pedido al servidor con el ticket y la clave de sesión y si es correcto el servidor permite el acceso.

Si una aplicación utiliza este tipo de autenticación, incluirá el header WWW-Authenticate: Negotiate en la respuesta cuando no se está autenticado.

Para automatizar con JMeter se deben modificar 3 archivos en la carpeta bin de JMeter:

  1. krb5.conf

Este archivo tiene la configuración de Kerberos. Un ejemplo de configuración mínima podría ser el siguiente:

[libdefaults]
default_realm = ABSTRACTA.LOCAL
[realms]
ABSTRACTA.LOCAL = {
kdc = 192.168.40.3
admin_server = 192.168.40.3
}
[domain_realm]
192.168.40.3=ABSTRACTA.LOCAL
.192.168.40.3=ABSTRACTA.LOCAL

default_realm: Define el realm por defecto. Un realm es una red lógica, similar al dominio, que define un grupo de sistemas bajo el mismo KDC (Key Distribution Center).

realms: Contiene secciones identificadas por el nombre del realm en las cuales se describe como encontrar los servidores de kerberos (KDC y servidor administrador) para ese realm.

domain_name: Contiene el mapeo de dominio o host al nombre del realm.

Para averiguar la IP del KDC se puede utilizar este comando:

nslookup -type=any _kerberos._tcp.NombreRealm

Por ejemplo:

  1. system.properties

Se deben agregar las siguientes propiedades para que utilice los archivos de configuración necesarios:

java.security.krb5.conf=krb5.conf
java.security.auth.login.config=jaas.conf

Se recomienda usar rutas absolutas, porque si se inicia JMeter desde un acceso directo el directorio de trabajo puede no ser /bin y las rutas relativas apuntarían a otro lado.

  1. jaas.conf (Opcional)

En este archivo se pueden agregar configuraciones de login, por ejemplo keytabs, si el servidor de Kerberos las utiliza. En nuestro caso no es necesario, así que usaremos el archivo jaas.conf por defecto.

Después de modificar estos archivos se debe reiniciar JMeter para que tome las propiedades que se agregaron.

En el HTTP Authorization Manager seleccionamos el macanismo Kerberos. Se utilizan los mismos campos que en los casos anteriores, pero además se puede especificar un realm. 

Al igual que en el caso anterior, la implementación no puede ser Java ya que este tipo de autenticación no está soportado, como se indica en la documentación.

Kerberos puede estar configurado de dos formas: basado en sesión o basado en pedido.

  • Basado en pedido: solicita y envía un ticket por cada pedido.
  • Basado en sesión: solicita y envía un ticket al principio de la conexión TCP.

En este caso no tenemos que hacer ninguna configuración extra, ya que JMeter lo maneja automáticamente.

Ambiente utilizado 

Para todas las pruebas que hicimos para preparar este post, se levantó un servidor IIS en una máquina virtual con Windows 2008 R2. Si necesitas probar estos tipos de autenticación en este post de Blazemeter explican cómo configurarlos.

Conclusión  

Podemos concluir que aunque actualmente hay algunos issues abiertos, es posible realizar estos tres tipos de autenticación de forma bastante simple si utilizamos la implementación HttpClient4 y el HTTP Authorization Manager. ¿Qué otros tipos de autenticación conoces? ¿Es posible realizarlas con JMeter? Leemos tus comentarios.

Leave a Reply

Your email address will not be published. Required fields are marked *