Page tree
Skip to end of metadata
Go to start of metadata

Conexión del IdP con fuentes de datos PDO

Para que el IdP pueda autenticar usuarios contra una base de datos a traves de PDO hay que editar el archivo simpleSAMLphp/config/authsources.php (se proporciona el path relativo a la instalación del IdP de referencia). Si has usado el instalador de RedIRIS, este archivo contiene sólo parámetros de configuración del PDO (no contiene otros específicos para autenticar contra otras "fuentes de autorización": LDAP, .htaccess, ...) y tendrá un contenido  similar a éste:

<?php 
$config = array (
 'admin' => array (
      0 => 'core:AdminPassword',
  ),
 'default-sp' => array (
      0 => 'saml:SP',
      'entityID' => NULL,
      'idp' => NULL,
      'discoURL' => NULL,
  ),
 'sql_datasource' => array ( 
      0 => 'sqlauth:SQL',
     'dsn' => 'mysql:host=localhost;dbname=idpdatabase','
     'username' => 'idpuser',
     'password' => 'idppass',
     'query' => '',
  )
?>

Describimos a continuación los atributos previamente incializados por la herramienta de instalación y el parámetro mínimo que hay que cambiar para que el sistema de autenticación funcione correctamente:

  • dsn: El DSN es el Nombre de Origen de Datos. Tiene el siguiente formato: prefijo:host=hostname;port=puerto;dbname=basedatos;charset=conjuntocaracteres. En donde:

    • El prefijo indica el tipo de servidor al que queremos conectar. En nuestro caso será mysql, pero podría ser sqlsrv (SQL Server), o cualquier otro, dependiendo del servidor de bases de datos que utilizamos. Este parámetro es obligatorio.

    • El hostname indica la ruta al servidor de base de datos al que conectamos. Es habitual que sea localhost, pero podría ser un servidor remoto. Este parámetro es obligatorio.

    • El port indica el puerto a través del cual se realiza la conexión con el servidor. Podemos obviar este parámetro siempre que estemos utilizando el puerto por defecto del servicio de bases de datos que estamos utilizando.

    • dbname indica el nombre de la base de datos con la que queremos trabajar. Este parámetro es obligatorio.

    • El parámetro charset indica el conjunto de caracteres que queremos asignar a los datos de nuestra base de datos en tiempo de ejecución. Este parámetro lo podemos obviar para que utilice el conjunto de caracteres configurado en nuestra base de datos.

      Explicados estos parámetros, vemos el dsn que hemos configurado en el ejemplo: mysql:host=localhost;dbname=idpdatabase. En el que accedemos a un servidor MySQL de nuestra propia máquina (localhost) y a la base de datos idpdatabase.

  • username: Debe ser un usuario con el que tengamos acceso a la base de datos.
  • password: La contraseña de acceso para el usuario configurado en el parámetro username.
  • query: Este es el parámetro más importante y el que hay que configurar manualmente, por lo que vamos a verlo en detalle. Este parámetro debe contener una consulta SQL mediante la cual podamos obtener los datos del usuario que se intenta loguear, checkeando el nombre de usuario y contraseña con los parámetros recibidos en la solicitud de acceso. Esta consulta se tendrá que adaptar a la estructura de la tabla en la que estamos almacenando los usuarios y sus atributos. Vamos a ver un ejemplo de lo podría ser la estructura de la tabla:

CREATE TABLE users (
	uid VARCHAR(30) NOT NULL PRIMARY KEY,
	password TEXT NOT NULL,
	salt TEXT NOT NULL,
	givenName TEXT NOT NULL,
	mail TEXT NOT NULL,
	eduPersonPrincipalName TEXT NOT NULL
);

Es importante tener en cuenta la seguridad de la contraseña, por lo que el password es muy recomendable que se almacene cifrado en la base de datos. En este ejemplo, vamos a cifrarlo mediante un salt y el algoritmo SHA2.

A continuación se muestra un ejemplo de como añadir un usuario, con la contraseña cifrada mediante el sistema mencionado, a la tabla users (en nuestro caso vamos a hacerlo bajo un servidor MySQL, pero debería de ser similar en los distintos sistemas gestores de bases de datos basados en SQL):

#En primer lugar creamos una variable salt, a la que le generamos un salt que utilizaremos para el usuario.
mysql> SET @salt = (SELECT MD5(RAND(LAST_INSERT_ID())));
#Posteriormente ejecutamos el INSERT INTO, utilizando el salt generado
mysql> INSERT INTO users(uid, password, salt, givenName, mail, eduPersonPrincipalName) VALUES ("testuser", SHA2(CONCAT(@salt, "testpassword"), 256), @salt, "TestGivenName", "testmail@rediris.es", "TestPrincipalName");

Después de crear la tabla y disponer de algunos usuarios, se puede proceder a configurar el parámetro query para consultar los datos del usuario solicitado. En caso de que el usuario solicitado no exista (o la contraseña no sea correcta), se produce un acceso incorrecto. Siguiendo con el ejemplo, el parámetro query quedaría así:

'query'=>'SELECT uid, givenName, mail, eduPersonPrincipalName
			FROM users
			WHERE uid =:username
				AND PASSWORD = SHA2(
					CONCAT((SELECT salt FROM users WHERE uid =:username),
						:password
					),
				256)',

Con estas configuraciones el IdP ya debería estar listo para funcionar.

Consideración adicional para el uso de SQLite

La configuración anterior se aplica a cualquier servidor de bases de datos basados en SQL, como pueden ser MySQL, SQL Server, PostgreSQL... , pero vamos a ver como hay pequeños matices a tener en cuenta si queremos utilizar SQLite.

Conviene comenzar por explicar la principal diferencia entre un sistema de bases de datos convencional y SQLite. SQLite, a diferencia de sistemas como MySQL, no funcionan mediante el modelo cliente-servidor, sino que SQLite no es un servidor como tal, simplemente una aplicación que se instala en el sistema y gestiona el acceso a los ficheros que contienen la información de las bases de datos.

Las sentencias SQL son similares a las expuestas en el ejemplo anterior, pero la configuración difiere ligeramente:

'sql_datasource' => array(	
	 0 => 'sqlauth:SQL',
	'dsn' => 'sqlite:/path/database',
	'username' => '',
	'password' => '',
	'query'=>'SELECT uid, givenName, email, eduPersonPrincipalName
				FROM users
				WHERE uid =:username
				AND PASSWORD = SHA2(
					CONCAT(
						(SELECT salt FROM users WHERE uid =:username),
						:password
					),
					256
				)',
	),

Podemos apreciar fácilmente las diferencias. 

  1. El dsn tiene el prefijo sqlite y ya no llama a ningún servidor, sino que hace referencia a la ruta absoluta del sistema de archivos donde se encuentra la base de datos, incluyendo el nombre de la base de datos.
  2. El usuario y la contraseña están vacíos. No hay ningún servidor al que acceder, por lo que no tenemos ningún dato de acceso. El control del acceso al fichero de la base de datos debería hacerse mediante la gestión de privilegios de archivos del propio sistema operativo.

Hay que tener en cuenta que, aunque SQLite no sea un servidor, es una aplicación que debemos instalar en el sistema. Así mismo, necesitaremos instalar la extensión de PHP pdo_sqlite y activarla para poder utilizar las bases de datos SQLite creadas en el equipo.

  • No labels