Identificar el usuario y el equipo desde el que se conecta a la base de datos

Identificar Usuarios

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.

The following two tabs change content below.
Arkaitz Arteaga
Llevo más de 10 años programando, sobre todo en Visual Basic y con bases de datos Access. Para mí, VBA y Access siguen siendo herramientas muy potentes. He desarrollado varios proyectos con PHP y MySql. Si sumo las webs que he tenido, probablemente pasaría de 100. Ahora prefiero dedicar todo mi esfuerzo a este blog (aunque sigo manteniendo unas cuantas...). Trabajo en la administración pública (si, soy funcionario), pero he trabajado en pequeñas empresas e incluso en una "grande" de las telecomunicaciones. Ultimamente estoy bastante metido en abrirme nuevos horizontes con C# y .NET. Renovarse o morir!

Deja un comentario