===== Integración mediante servicios web ===== Siette dispone de un conjunto de servicios web para establecer mediante un protocolo seguro una relación de confianza con otro sistema web. La idea general es que Siette actúe como servidor y el sistema externo como cliente y que el sistema externo pueda pedir a Siette que realice una evaluación de un usuario y le devuelva los resultados. Para ello lo primero de todo es establecer entre Siette y el sistema externo un mecanismo de autenticación mediante un par de claves pública y privada. El sistema externo mantiene la clave privada y Siette solamente necesita la clave pública. Siette debe dar de alta al nuevo sistema incluyéndolo como una nueva [[es:manual:usuarios:procedencias|procedencia]] en su base de datos, asignándole un identificador (alfanumérico) que debe ser tambien conocido por el sistema externo. (''systemIdentifier''). Esta tarea que debe realizar exclusivamente el [[es:qgadmin|administrador]]. Una vez establecida la relación de confianza entre ambos sistemas, Siette juega el rol de //servidor// al que el otro sistema le envía mensajes a los que Siette responde. En general el sistema externo tendrá sus propios usuarios, y lo primero que debe hacer es llamar a Siette y decirle que cree un usuario en Siette que estará en correspondencia con el usuario del sistema externo. Para ello invocará el servicio web ''registerUser'' pasando a Siette una información mínima. De entre todos los campos que debe comunicar a Siette sólo es imprescindible el nombre y apellidos del usuario, todos los demás campos pueden dejarse en blanco, incluyendo la contraseña. Los usuarios creados en Siette a través de un sistema externo se identifican mediante el nombre de usuario (''userName'') y la procedencia (''systemIdentifier''), y solo pueden acceder a Siette a través del sistema externo, ya que el entorno principal de Siette no admite el acceso directo de estos usuarios. Una vez creados los usuarios, el siguiente paso consiste en establecer la conexión mediante el servicio ''authenticateUser'', servicio al que se le pasan también como parámetros el nombre de usuario y el identificador del sistema. Como medida de seguridad todas las conexiones entre el sistema externo y Siette que impliquen acceso a Siette deben estar //firmadas//. La firma consiste en la codificación mediante [[wp>RSA_(cryptosystem)|RSA]] [[wp>SHA-1|SHA-1]] usando la clave privatda de la cadena que se obtiene concatenando el nombre de usuario y la procedencia. El sistema externo debe ser capaz de realizar esta codificación, que se añade como parámetro en la llamada al servicio web. Una vez establecida la conexión de un usuario, Siette devuelve un token temporal o //credencial// (''credentialIdentifier''), que puede ser usada en cualquier URL que llame a Siette, ya sea para iniciar un test o para solicitar una pregunta, o los resultados de una sesión. Al recibir este parámetro Siette reconoce la //credencial// y la asocia al usuario que la solicito, de manera que no es necesario repetir la autenticación mientras la //credencial// no haya expirado. Para simplificar la implementación de los clientes de los servicios web se han implementado clases auxiliares en [[es:manual:integracion:java|JSP]] y en [[es:manual:integracion:php|PHP]], y se han desarrollado aplicaciones de ejemplo que muestran paso a paso el proceso de conexión, autenticación y realización de un test. Un caso particular del uso de los servicios web en PHP es la [[es:manual:integracion:moodle|integración con Moodle]] que se ha llevado a cabo mediante la implementación de un plugin que usa los servicios web. En esta página se describen los servicios web para que pueda implementarse un cliente en cualquier otro lenguaje. ==== Generación de las claves pública y privada ==== Para generar la pareja de claves pública y privada puede usarse cualquier sistema de cifrado. A continuación se indican las instrucciones necesarias utilizando la utilidad [[wp>openssl|OpenSSL]] Generar una clave privada con RSA en un archivo con formato PEM openssl genrsa -out /ruta/archivo_priv.pem [-des] Generar una clave publica a partir de una privada, con RSA en un archivo openssl rsa -in /ruta/archivo_priv.pem -pubout -out /ruta/archivo_pub.pem Consultar la clave generada en un archivo con formato PEM: openssl rsa -in /ruta/archivo.pem -inform PEM -text [-pubin] Firmar archivo: openssl rsautl -sign -inkey /ruta/archivo_priv.pem -in /ruta/archivo_a_firmar.txt -out /ruta/archivo_firma.txt Verificar un archivo firmado: openssl rsautl -verify -pubin -inkey /ruta/archivo_pub.pem -in /ruta/archivo_firma.txt Ejemplo: openssl genrsa -out priv_key.pem openssl rsa -in priv_key.pem -pubout -out pub_key.pem openssl rsa -in priv_key.pem -inform PEM -text openssl rsa -in pub_key.pem -inform PEM -text -pubin ==== Conexión a los servicios web ==== Una vez definidas las claves, dependiendo del lenguaje de programación que se vaya a utilizar se implementará el cliente de los sevicios web. Para aplicaciones basadas en JSP y en PHP se han implementado ya algunas clases para facilitar la construcción del cliente. La direccion de os servicios es ''/services/External'', y servicios web disponibles son los siguientes: === Servicios === ^Nombre ^Parámetros ^Función ^ |echo | | Sirve para comprobar que el mecanismo de comunicación mediante servicios web funciona| |getNumberOfUsers|''systemIdentifier''|Devuelve un entero con el numero de usuarios de esa procedencia registrados actualmente en Siette| |authenticateUser| ''userName'', \\ ''systemIdentifier'',\\ ''rsaSha1Signature'' | Crea un registro del usuario en Siette asignandole un token o credencial que puede usar temporalmente para acceder sin necesidad de volver a conectarse. | |authenticateExternalUser | ''user'',\\ ''systemIdentifier'',\\ ''rsaSha1Signature'' | Igual al anterior, pero usando un //bean// ''user'' como parámetro, en vez de solo nombre de usuario. Si el usuario no está creado en Siette lo crea. | |authenticateSystem | ''string'',\\ ''systemIdentifier'',\\ ''rsaSha1Signature'' | Es un método que sirve solamente para comprobar que el mecanismo de comunicación entre ambos sistemas esta funcionando. El primer parametro es una cadena cualquier a codificar. Devuelve ''true'' si el proceso ha tenido exito. | |registerUser | ''userData'',\\ ''rsaSha1Signature'' | Crea un usuario en Siette correspondiente a un uusario remoto en el sistema externo. Devuelve ''true'' si el proceso se completa satisfactoriamente. | |existsExternalUser | ''userName'',\\ ''systemIdentifier'' | Devuelve ''true'' si el usuario del sistema externo está ya registrado en Siette.| |getTestListTeacher | ''userName'',\\ ''systemIdentifier'',\\ ''language'' | Devuelve la lista de asignaturas y de test accesibles por el profesor en el idioma selecionado | |getTestListStudent | ''userName'',\\ ''systemIdentifier'',\\ ''language'' | Devuelve la lista de asignaturas a las que puede acceder el alumno en el idioma selecionado | |getSubjectListTeacher | ''userName'',\\ ''systemIdentifier'',\\ ''language'' | Devuelve la lista de asignaturas del profesor en el idioma selecionado | |getSubjectListStudent | ''userName'', ''systemIdentifier'', ''language'' | Devuelve la lista de asignaturas a las que puede acceder el alumno en el idioma selecionado | |getTestQuestions |''idTest'',\\ ''colaborative'',\\ ''hostAdress'',\\ ''userName'',\\ ''systemIdentifier'',\\ ''rsaSha1Signature'' | Devuelve un documento XML en formato SQTI que contiene la lista de todas las posibles preguntas que podrían aparecer en un determinado test. ESte método esta pensado para transmitir a un sistema externo de una sola vez un conjunto de preguntas de Siette, por ejemplo a un dispositivo móvil | |beginTestSession |''idTest'',\\ ''colaborative'',\\ ''hostAdress'',\\ ''userName'',\\ ''systemIdentifier'',\\ ''rsaSha1Signature'' | Este método crea una sesión de un test en Siette para un determinado alumno, y devuelve el identificador de la sesión. Una vez creada la sesión, el test puede realizarse mediante llamadas HTTP directamente a la pagina web de comienzo del test, por ejemplo "https://www.siette.org/siette?idsesion=SSS&idioma=III&xml=X&token=TTT&urlBack=BBB" en donde SSS representa el identificador de la sesión, obtenido al invocar al servicio web ''beginTestSession''; III el códigpo de idioma; X indica si Siette debe devolver las preguntas compuestas en HTML con la interfaz normal, o bien solo un esquema de la pregunta en XML; TTT el token obtenido anteriormente mediante el servicio web ''authenticateUser'' o ''authenticateExternalUser''; y BBB la url a la que Siette invocará una vez concluido el test para enviar los resultados. | |getSessionScore | ''idsession'' | Devuelve en forma de cadena de caracteres la calificación final obtenida en la sesion cuyo identificador se pasa como parámetro. | |hasExpiredSIETTESession | ''credentialIdentifier'' | Devuelve ''true'' si la credencial que se obtuvo ha expirado. | === Parámetros === Los parámetros de estas servicios son los siguientes: ^Parámetro ^Tipo ^Contenido ^ | ''userName'' | ''string'' | Cadena alfanumérica de menos de 16 caracteres que contiene el identificador del usuario | | ''systemIdentifier'' | ''string'' | Identificador para Siette del sistema externo. | | ''rsaSha1Signature'' | ''string'' | Cadena de caracteres correspondiente al cifrado (usando la clave privada del sistema) mediante RSA SHA-1 de la cadena de caracteres obtenida con la concatenacion de ''userName@rsaSha1Signature''. Siette descifrará este mensaje mediante la clave pública y validará que corresponde al usuario que realiza la petición| |''language'' | ''string'' | Cadena de idioma, puede ser ''en'' (Español); ''en'' (Inglés); ''de'' (Alemán); o ''fr'' (Francés). | |''user'' \\ ''userData'' | { string firstName; string lastName; string userName; string email; string userPassword; string systemIdentifier; boolean isTeacher; } | Bean que contiene los datos del usuario para registrar en Siette | |''idTest'' | ''int'' | Id del test que se va a realizar. | |''colaborative'' | ''boolean'' | ''true'' si el test a realizar se hace en modo colaborativo | |''hostAdress'' | ''string'' | Direccion del servidor | |''idsession'' | ''int'' | Identificador de la sesion del alumno. | |''credentialIdentifier'' | ''string'' | Secuencia de caracteres que da acceso a Siette a un usuario externo. | === Conexión === La conexión a los servicios se realiza a través de [[wp>SOAP]], es decir, usando el protocolo HTTPS mediante llamadas GET o POST. Por ejemplo, el servicio ''echo'' esta pensado para probar que inicialmente la comunicación funciona: [[https://www.siette.org/siette/services/External?method=echo]] debe devolver: En el siguiente enlace se muestra el fichero [[wp>WSDL]] que describe todos los servicios web disponible en Siette, y los parámetros necesarios para la llamada: [[https://www.siette.org/siette/services/External?wsdl]] ==== Ejecución de un test desde un sistema externo ==== === Acceso al test === Los servicios web proporcionan un mecanismo de autenticación basado en la confianza entre dos sistemas, de manera que Siette confía en que los datos que solicita un sistema externo son correctos. Por ejemplo, Siette no cuestiona si el usuario que le pasa el sistema externo ha entrado en el sistema correctamente (por ejemplo utilizando una contraseña válida), o si el usuario esta autorizado o no a acceder a ese test en concreto (siempre y cuando este test pueda accederse desde éste sistema externo), simplemente confía en que el sistema externo ha hecho su trabajo y garantiza que los datos son correctos. Por ejemplo, si un test de una asignatura está disponible para acceso desde un sistema externo basado en Moodle, desde el punto de vista de Siette, a este test tendrán acceso todos los alumnos dados de alta en el sistema Moodle. Es responabilidad de Moodle gestionar a qué alumnos proporciona el enlace correspondiente para que puedan acceder a Siette. Sin embargo, hay algunos controles de acceso que Siette sigue aplicando, como la contraseña de acceso, el intervalo temporal de acceso, etc. Estas comprobaciones pueden estar duplicadas con el sistema externo (por ejemplo Moodle las duplica). Es responsabilidad del usuario configurarlas en uno u otro sistema. === Ejecución === Para iniciar el test debe obtenerse una URL de inicio, para lo cual hacen falta (1) el token obtenido previamente con el servicio ''authenticateUser'' o ''authenticateExternalUser'' y el identificador de la sesión obtenido al invocar al servicio web ''beginTestSession''. Con estos dos valores se compone una URL que llama a Siette pasándole éstos y otros valores como parámetros mediante el método GET, por ejemplo: ''https://www.siette.org/siette?idsesion=SSS&idioma=III&xml=X&token=TTT&urlBack=BBB'' en donde: ^Parámetro ^Posibles valores ^Caracter ^Comentarios ^ |token | Número entero | necesario | Se debe obtener previamente mediante el servicio ''authenticateUser'' o ''authenticateExternalUser'' | |idsesion | Número entero | necesario | Se debe obtener previamente mediante el servicio ''beginTestSession'' | |idioma| "es, "en", "fr" ... | opcional | Indica el idioma del interfaz | | xml | "true", "false", "1", "0" | opcional | Indica si Siette debe devolver una página HTML o bien simplemente una descripción en formato XML | | urlBack | URL | opcional | Servicio o página a la cual se le pasaran como parametros los resultados del test cuando éste concluya. | En la integración mediante Java, para componer esta URL basta con llamar al método getStartTestURL de la clase [[es:manual:integracion:siette.external.integrationhelper|IntegrationHelper]] * En caso de no usar el parámetro XML, la pagina de inicio del test obtenida en el paso anterior se mostrará en una página o en un **iframe** del navegador. La propia URL contiene los botones de navegación del test al igual que si el test se realizara desde el propio entorno de Siette, por lo que la navegación de preguntas y respuestas se va encadenando de forma natural. * En el caso en el que las preguntas se requieran en formado XML, añadiendo este parámetro en la primera llamada, Siette devuelve como resultado inicialmente la descripción del test descrito mediante [[es:manual:sqti|SQTI]]. Esta descripción incluye el valor de la sesión Java del servidor de Siette, es decir el valor del parámetro ''jsessionid'' que resultará ser muy importante para poder continuar la sesión Java establecida con el servidor de Siette. A partir de aquí es responsabilidad del cliente externo realizar las siguientes tareas: * Extraer del formato XML los datos necesarios. Para ello debe analizarse el formato XML. La integracion mediante Java proporciona métodos auxiliares para ello. * Mostrar los datos al usuario de alguna forma. ("Renderizar" la pregunta) * Recoger la respuesta del usuario mediante algún tipo de interacción. * Enviar los resultados a Siette y/o solicitar una nueva pregunta. Para ello se realizarán llamadas alternativamente a los servlets ''Pregunta'' y ''Respuesta'', simulando el comportamiento de la interfaz de Siette, hasta el final del test. Si las llamadas se hacen de forma independiente habrá que incluir en la URL el identificador ''jsessionid'' que sirve para recuperar el resto de los valores de la sesión a través del mecanismo de persistencia de las aplicaciones Java. ((En el caso en el que se haya instalado un distribuidor de carga con varias instancias de Siette corriendo sobre distintos servidores, recuerde que es necesario incluir la cookie ''siette.user'' para poder determinar el servidor que mantiene activa la sesión.)) Por ejemplo, para obtener la siguiente pregunta de un test deberá llamarse a la URL: ''https://www.siette.org/siette/generador/Pregunta;jsessionid=JJJJJJJJJJJJJJJJJJ'' Una vez planteada la pregunta y obtenida la respuesta del alumno, el sistema externo deberá enviársela a Siette para que éste sepa que la pregunta ya ha sido contestada y pueda proceder a mostrar la corrección o a seleccionar una nueva pregunta, según proceda. Esta operación se implementa mediante la llamada a la URL: ''https://www.siette.org/siette/generador/Respuesta;jsessionid=JJJJJJJJJJJJJJJJJJ?idrespuesta=0000&idrespuesta1=11111''