Acceso restringido para múltiples usuarios con ASP y base de datos

  • Por
Realizamos una mejora al sistema de autentificación con ASP para que puedan acceder múltiples usuarios, cada uno con unos datos de acceso distintos.
Vamos a ver las páginas ASP que necesitaríamos para realizar un acceso restringido por clave y contraseña para múltiples usuarios, donde cada uno tenga unos datos de acceso propios.

Nota:Este artículo viene a complementar el manual Sistema Autentificación en ASP. De hecho, en este artículo sólo vamos a tratar la página que recoge los datos del usuario (su nombre y contraseña) y comprueba si son correctos, redireccionando a la aplicación segura (si los datos se corresponden con algún usuario de la base de datos), o a la página de entrada (si los datos no correspondían con ningún usuario registrado).

Lo primero es recordar el esquema de páginas del sistema de autentificación propuesto. Lo podemos ver en el artículo Funcionamiento del sistema de autentificación en ASP. Nosotros vamos a tratar de colocar aquí un código para la página "compruebo datos"

La base de datos

La base de datos que vamos a utilizar contendrá una tabla para los usuarios, donde cada uno dispondrá, al menos, de dos campos: un nombre de usuario y una contraseña, los dos de tipo texto.

Tabla usuario
Nombre del campo Tipo del campo
nombre_usuario Texto
clave_usuario Texto

En una base de datos de usuarios, el nombre de usuario debería ser un valor único, irrepetible para otro usuario, es decir, no podremos tener dos usuarios con el mismo nombre. Por esta razón, el campo nombre_usuario podría ser la clave principal de la tabla, aunque también podríamos haber creado un campo adicional, llamado por ejemplo id_usuario, de tipo autonimérico y colocarlo como clave principal.

Para conseguir no insertar dos usuarios con el mismo nombre de usuario, a la hora de insertarlos en la tabla, comprobaremos que no haya ningún usuario ya introducido con el nombre de usuario que se pretende insertar. Este paso, aunque importante, no lo vamos a ver, pues sólo nos vamos a centrar en decidir si un usuario puede entrar o no en la aplicación, suponiendo que los usuarios se encuentran ya insertados en la base de datos.

En el ejemplo suponemos que utilizamos una base de datos Access, sin embargo, cualquier tipo de base de datos podrá servir para unos objetivos como los que nos proponemos. Para sistemas Microsoft, las bases de datos más habituales son la mencionada Access (recomendable si el sitio web tiene pocas consutas al mismo tiempo) y SQL Server, que ofrece potencia suficiente para los entornos más exigentes.

Referencia: En nuestro Manual de ASP hablamos con más detenimiento sobre el trabajo con bases de datos.

El funcionamiento del script

El script que se utilizará para decidir si un usuario puede o no entrar en la aplicación es muy sencillo. Simplemente hace una llamada a la base de datos para comprobar si los datos de autentificación escritos por el visitante (usuario y contraseña) corresponden con los de algún usuario. En caso de que así sea, se permite la entrada y de no ser así, se deniega.

Nota: Este script fue comentado en una versión simplificada en el artículo Control de los datos de autentificación en ASP, englobado dentro del manual Sistema de autentificación PHP

Lo primero sería abrir una conexión con la base de datos, seleccionar la base con la que hemos de trabajar y ejecutar una sentencia de selección del usuario que corresponda con los datos de autentificación introducidos.

' miro a ver si la autentificacione es correcta
'creo una sentencia SQL con los datos recibidos
ssql = "select * from usuarios_autentificacion where nombre_usuario='" & request.form("usuario") & "' and clave_usuario='" & request.form("contrasena") & "'"
'conecto y extraigo de la base de datos
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "base_autentificacion"
set RS = Conn.Execute(sSQL)


Si esa sentencia SELECT responde con algún registro encontrado, sabremos que existe un usuario donde sus datos de autentificación corresponden perfectamente con los introducidos. En ese caso podremos realizar las acciones encaminadas a permitir el acceso. Por el contrario, si la sentencia SELECT no encuentra ningún registro, sabremos que no existe un usuario con los datos de autentificación introducidos y por lo tanto, deberemos realizar las acciones encaminadas a restringir el acceso.

if (not RS.eof) then
    'Como se ha localizado un registro es que ese usuario existe y su contraseña es correcta
    'coloco las variables de sesion
    session("autentificado") = "si"
    'redirecciono a la página de la aplicación
    response.redirect "aplicacion.asp"
else
    response.redirect "index.asp?errorusuario=si"
end if

'cierro la conexion con base de datos
Conn.Close


Nota importante: Este código es mejorable y en concreto tiene problemas de seguridad por permitir la Inyección SQL, por favor, lee los comentarios de la comunidad y verás las soluciones propuestas para mejorarlo. Gracias.

Las acciones para restringir o permitir el acceso son exatamente iguales a las que veníamos utilizando en el script de control sin utilizar la base de datos. Así que no vamos a comentarlas más, sino que os referimos al artículo donde las explicamos.

El código completo del ejemplo sería el siguiente.

<%
' miro a ver si la autentificacione es correcta
'creo una sentencia SQL con los datos recibidos
ssql = "select * from usuarios_autentificacion where nombre_usuario='" & request.form("usuario") & "' and clave_usuario='" & request.form("contrasena") & "'"
'conecto y extraigo de la base de datos
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "base_autentificacion"
set RS = Conn.Execute(sSQL)

if (not RS.eof) then
    'Como se ha localizado un registro es que ese usuario existe y su contraseña es correcta
    'coloco las variables de sesion
    session("autentificado") = "si"
    'redirecciono a la página de la aplicación
    response.redirect "aplicacion.asp"
else
    response.redirect "index.asp?errorusuario=si"
end if

'cierro la conexion con base de datos
Conn.Close
%>


Nota: Es importante destacar que esta página no debería contener ningún tipo de texto antes de la apertura de código ASP, ni tan siquiera saltos de línea. Esto es debido a que al final se realiza una redirección y este tipo de instrucciones solamente se puede ejecutar si no se ha escrito todavía ningún carácter en el cuerpo.

No obstante, en la mayoría de las versiones de ASP no encontraremos ese error porque la página no se envía al navegador hasta que no se termina de ejecutar en el servidor, y así, si se hace un redirect habiendo escrito texto antes, no se llegaría a mandar ningún texto sino que se mandaría la orden de redirección.

Todo esto está contado con más detalle en el artículo Redirigir al navegador a una URL con ASP al detalle.

Se puede descargar este sistema de autentificación, junto con la base de datos utilizada, en un fichero comprimido. No obstante, recordar que para ponerlo en marcha no basta solo con descomprimirlo, sino que habrá que colocarlo en el directorio de publicación de nuestro servidor web preparado para ASP y crear el DSN de la base de datos en el panel de control del servidor. Todo esto se explica con detalle en nuestro Manual de ASP.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Alberto

09/7/2003
Hola Miguel Ángel:

Me ha parecido bueno el artículo, sobre todo para la gente que está empezando, pero el script mostrado presenta un agujero de seguridad bastante grave.

En concreto, permite la realización de Inyección de SQL (SQL Injection) con el consiguiente riesgo que eso plantea:

La consulta que se utiliza:

"select *
from usuarios_autentificacion
where nombre_usuario='" & request.form("usuario") & "'
and clave_usuario='" & request.form("contrasena") & "'"

se transformaría en la siguiente:

"select *
from usuarios_autentificacion
where nombre_usuario='1'
and clave_usuario='0' OR true OR ''=''"

si el usuario introduce como nombre_usuario un ``1" y como contraseña el string ``0' OR true OR ''='".

Sobre los datos, si la BDD es ACCESS el peligro no es mucho, pero si la BDD estuviese en un servidor MS SQL Server podrían hacerse auténticas barbaridades con el mismo. Y en cuanto al acceso a la web, el usuario malicioso conseguiría colarse en el área "privada".

Os animo a crear una versión 1.1 del artículo ;-)

Un saludo,

Alberto

Eduardo Antón

04/2/2004
Holas, el articulo me ha parecido muy interesante.
Respecto al SQL Injection, las soluciones pasan por:
1- Evitar que el usuario inserte directamente datos en la sentencia SQL, para ello podemos programar una función que limpie las cadenas introducidas, eliminado comillas por ejemplo.
2- Uso de procedimientos almacenados en SQL-SERVER, con lo cual se delimita totalmente las variables de la sentencia SQL.

Saludos. :o)

Gaizko

26/4/2004
Para evitar el SQL injection en la autenticación de usuarios de la base de datos, los datos a comprobar solo son el usuario y la contraseña, a mi me parece que lo más sencillo es abrir la tabla con el objeto recordset, recorrerte todos los registros y comprobar si existe un usuario con una contraseña iguales a los parametros recibidos. Lo he probado con una tabla de 100.000 usuarios y no tarda mucho en validar. Eso si, hay que evitar bloquear la tabla para evitar problemas de concurrencia.

Quedaría algo así como:
set rs = Server.CreateObject("ADODB.RECORDSET")
rs.Open "tabla", cn,adOpenForwardOnly, adLockReadOnly
do until rs.EOF
If rs("user") = Request.Form("usuario") And rs("pass") = Request.Form("clave") Then
session("validado") = true
exit do
End if
loop
rs.Close
set rs = Nothing

Para evitar sql injection de otras formas, haría falta más código, pero para eso hay otros manuales.

ludvin

11/3/2005
he tratado de colocar en mi pagina el codigo pero al parecer al entrar en la clave me envia a una pagina llamada control.asp pero no aplica la autenticacion que podria ser

achigore

01/6/2005
Esta muy bien el articulo, pero he encontrado otro fallo. una vez que el usuario se ha autenficado correctamente las descargas quedarían en el historial del navegador, con lo que otra persona poniendo la url entera
http://www.pagina.com/fichero/descarga.zip
¿Se podría arreglar esto?

Zebenzui

05/7/2005
Alguien podria ayudarme y decirme como modificar este ejemplo para evitar la inyeccion sql. Algo asi como poder cambiar las comillas ' por comillas " en caso de que el usuario meta dicho caracter. Muchas gracias de antemano.

flako

18/5/2006
El script permite hacer sql injection.

Ernesto

07/1/2007
Ok, he leido el articulo, y lo he estudiado como mil veces, pero sigo sin entender porque me sigue saliendo este error:

Microsoft OLE DB Provider for ODBC Drivers (0x80004005)
[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
/direcciondemimaquina/control.asp, line 7

Hasta en la base del conocimiento de Microsoft he venido a parar para saber el origen de mi problema pero al parecer, ya todas las soluciones posibles estan aplicadas.

Ah!! y claro! eso del SQL Inyection me preocupa... podrian modificar ese articulo? o si existe algun alma caritativa enviarmelo corregido a mi correo por favor!

Estoy aprendiendo asp apenas y sigo sin entender muchas cosas!

Gracias
Correo: eflames.gmail.com

Eddy Pérez Cobas

20/1/2007
Creo que valdría la pena comentar que estos scripts son verdaderamente interesantes y se le pudieran hacerle modificaciones para C#. Veo muchos ejemplos con Visual Basic. Creare algunos ejemplos con C# para colaborar.

joe

06/7/2007
como puedo yo hacer para que en la pagina aplicacion.asp me aparezcan los datos que tengo en mi case de datos mostrando asi el nombre del usuario que entro en ese momento?

Paula

12/7/2007
Hola, me he bajado los archivos de vuestro manual de autentificación y he intentado probarlos en mi ordenador (Windows XP HOME) con Dreamweaver y Baby Web Server. La pagina INDEX con el formulario de entrada se ve bien pero no se conecta con la base de datos y crea un error después de entrar qualquier dato.
ERROR EN EXPLORER:
Script error detected at line 6.
Source line: Conn.Open "base_autentificacion"
Description: [Microsoft][Administrador de controladores ODBC] No se encuentra el nombre del origen de datos y no se especificó ningún controlador predeterminado

A ver si alguien me puede ayudar a resolverlo. He hecho todos los pasos de configuración de controladores ODBC de vuestro manual y no hay manera.

Paula

17/7/2007
Hola. Soy la que escribí antes. Ahora ya me funciona. Al final vi que no se conectaba porque en el archivo control.asp no estaba bien escrito el nombre de la base. Donde decía:
Conn.Open "base_autentificacion"
Tenía que decir:
Conn.Open "base"
Haciendo esto me ha funcionado. Lo explico por si a alguien le sirve.

Otra pregunta: ¿Cómo se puede hacer para que cada usuario que se identifique vaya a parar a una página o aplicación distinta? ¿Es decir que la página dónde vaya a parar cada usuario sea restringida exclusivamente para él? ¿Podría ser conectándose a un FTP distinto para cada uno? ¿Alguien sabe qué código habría que añadir?

Gracias por contestar.

citrix

24/7/2007
hola buenas,soy nuevo en esto de los scrip y no se conmo funcionan ni se configuran he creado una pagina web y me gustaria acer usuarios restringidos alguien me podria ayudar porfavor.ales_626791@hotmail.com

07/3/2008
Un gran manual. De mucha ayuda

ernesto_ar

18/5/2009
Sistema de autentificación en ASP
Amigos, por supuesto que hay que realizar mejoras en este código, para evitar la inyección y alguna que otra cosa mas, pero lo cierto es que yo he incorporado en mis páginas web la técnica desarrollada aquí (yo la implementé hace 5 años mas o menos, hoy estamos en 5/2009) y puedo decir que funciona muy bien, además, yo diría que no se ha modificado en nada esta publicación. Desde aquí mis agradecimientos a sus generosos autores y un saludo cordial para todos. Ernesto.