Identificar el usuario y el equipo desde el que se conecta a la base de datos
Antes de empezar con el artículo sobre sistemas de identificación de usuarios, me gustaría comentar algo sobre las conexiones a la base de datos. El artículo sobre dividir el proyecto Acces en BE (Backend) y FE (FrontEnd) está basado en la forma de conectar con nuestro BE de una manera más segura que simplemente vinculando de nuevo las tablas pero no entra en asegurar el propio BE. En este artículo quiero profundizar un poco más en este tema y además introducir 2 conceptos nuevos, las variables de entorno y las API de Windows.
Antes de comenzar, recordaros el artículo sobre Encriptar base de datos Access en el que comentamos la manera más segura de proteger nuestro BE contra posibles accesos directos. Con esto evitamos nuestros usuarios accedan directamente a los datos aunque tengan permisos de acceso mediante nuestra aplicación (además de tener nuestros datos encriptados cumpliendo la LOPD para datos de nivel alto).
Una vez asegurados nuestros datos, tenemos que dar acceso a nuestros usuarios a la carpeta del servidor donde se encontrará el BE . Contactad con vuestro administrador de sistemas para este paso, que hará que ningún usuario externo al grupo de usuarios de nuestra base de datos pueda acceder ni directa ni indirectamente (mediante el FE) a la base de datos.
En principio si seguimos estos pasos, nuestro BE debería ser seguro (siempre que nuestro sistema lo sea, dependiendo esto más de nuestro administrador de sistemas que de nosotros). Pero nunca está de más introducir capas extra a nuestro sistema de seguridad.
Para ello comprobaremos el usuario de Windows y el equipo desde el que conecta. Esto nos permitirá restringir a cada usuario los equipos de conexión, comprobar si coinciden el usuario de Windows con el de base de datos y registrar las conexiones (que nos ayudará en artículos posteriores a crear el registro de accesos que nos exige la LOPD para datos de nivel alto). Todo ello utilizando 2 herramientas muy interesantes, las variables de entorno y 2 APIs de Windows, apiGetUserName (de la librería advapi32.dll) y apiGetComputerName (de la librería kernel32).
Variables de entorno en Visual Basic
Para manejar las variables de entorno en Visual Basic utilizaremos la Función Environ()
que nos devolverá el valor de la variable de entorno que le pasemos. Existen muchas variables de entorno pero en nuestro caso nos interesan username
y computername
. La primera nos devolverá el nombre de usuario de Windows y la segunda el equipo desde que se conecta nuestro usuario. La llamada es muy sencilla, por ejemplo podemos guardar en una tabla local (Usuario_Activo
que más adelante utilizaremos para el registro de accesos) los valores de ambas variables al iniciar la base de datos :
Public Sub guardar_variables () Dim MiBD As DAO.Database Dim LogAccesos As DAO.Recordset Set MiBD = CurrentDb On Error GoTo mal Set Accesos = MiBD.OpenRecordset("SELECT * from Usuario_Activo") Accesos.AddNew Accesos.AddNew Accesos("UsuarioWindows") = Environ("username") Accesos("Equipo") = Environ("computername") Accesos.Update Accesos.Close Exit Sub mal: MsgBox ("Error al conectar"), vbCritical, Error End Sub
Una vez almacenados estos valores, podríamos realizar varias comprobaciones. Una manera sencilla de implementar una medida de seguridad adicional sería tener una tabla de Usuarios en nuestro BE en la que cada usuario de nuestra base de datos tuviera asociado un usuario de Windows y uno o varios Pcs permitidos para sus conexiones. Como tenemos ambos valores almacenados en local para cada usuario, podríamos comprobarlos e informar de un acceso no autorizado a nuestro sistema.
Esta es la manera más sencilla de comprobar y almacenar tanto el usuario de Windows como el equipo de conexión, pero por lo que comentan los expertos de sistemas, es bastante sencillo modificar estos valores, por lo que explicaré una manera más complicada pero supuestamente más segura de averiguarlos, las APIs de Windows.
APIs de Windows
Como vemos en la web de Microsoft:
Las API de Windows son bibliotecas de vínculos dinámicos (DLL) que forman parte del sistema operativo Windows. Se utilizan para realizar tareas cuando resulta difícil escribir procedimientos equivalentes.
En nuestro caso utilizaremos apiGetUserName (de la librería advapi32.dll) y apiGetComputerName (de la librería kernel32).
Lo primero que tenemos que hacer para utilizarlas es declararlas. Voy a utilizar 2 funciones de la propia web de Microsoft y que manejan estas 2 APIs. Empecemos con la declaración:
Private Declare Function apiGetUserName Lib "advapi32.dll" Alias _ "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long Private Declare Function apiGetComputerName Lib "kernel32" Alias _ "GetComputerNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Y seguimos con las funciones:
Function GetLogonName() As String On Error GoTo mal ' Dimension variables Dim lpBuff As String * 255 Dim ret As Long ' Get the user name minus any trailing spaces found in the name. ret = apiGetUserName(lpBuff, 255) If ret > 0 Then GetLogonName = Left(lpBuff, InStr(lpBuff, Chr(0)) - 1) Else GetLogonName = vbNullString End If Exit Function mal: MsgBox ("Error al comprobar el nombre de usuario"), vbCritical, "Error" End Function Function GetCompName() As String On Error GoTo mal 'Variables Dim buff As String Dim ret As Long buff = String$(16, 0) ret = apiGetComputerName(buff, 16) If ret > 0 Then GetCompName = Left$(buff, 16) Else GetCompName = vbNullString End If Exit Function mal: MsgBox ("Error al comprobar el nombre de equipo"), vbCritical, "Error" End Function
Y ahora podemos modificar nuestra función que guarda el usuario de Windows y el equipo de conexión para que en vez de utilizar variables de entorno, utilice las APIs.
Public Sub guardar_variables () Dim MiBD As DAO.Database Dim LogAccesos As DAO.Recordset Set MiBD = CurrentDb On Error GoTo mal Set Accesos = MiBD.OpenRecordset("SELECT * from Usuario_Activo") Accesos.AddNew Accesos.AddNew Accesos("UsuarioWindows") = GetLogonName() Accesos("Equipo") = GetCompName() Accesos.Update Accesos.Close Exit Sub mal: MsgBox ("Error al conectar"), vbCritical, Error End Sub
Incluso podíamos comprobar que los valores fueran iguales utilizando variables de entorno y APIs. Si no son iguales, ya sabemos que algo raro ocurre, o que nuestro usuario intenta camuflar su verdadera identidad.
Arkaitz Arteaga
Latest posts by Arkaitz Arteaga (see all)
- Access: Encriptar contraseñas con SHA-256 utilizando biblioteca de clases .NET con C# - 4 mayo, 2014
- Rendimiento de Access contra backend Access en servidor de archivos remoto. Cuarta parte. - 27 abril, 2014
- Rendimiento de Access contra backend Access en servidor de archivos remoto. Aclaración. - 21 abril, 2014
- Utilizar biblioteca de clases .NET en Access. Tercera aproximación a la Interoperabilidad COM - 14 abril, 2014
- Vincular tablas en Access con Visual Basic - 11 abril, 2014