I'm developping an application within our small company environment. This is our setup in a nutshell:
- Employees log into their PCs via their Active Directory login
- The application I'm developing uses MS Access as the front end and MS SQL Server 2019 as the back end (Windows authentication mode)
I want to be able to authenticate users in the application without the need to entering their AD login, just based on the fact that they are logged into their PC. Then I want to be able to grant users permissions in the application as I see fit.
This is what I came up with:
tblEmployees:
| EmployeeID | EmployeeName | ADLogin |
|---|---|---|
| 1 | John Doe | COMPANY\john.doe |
| 2 | Peter Wilson | COMPANY\peter.wilson |
When any user starts the MS Access application, it will do something like this on start-up:
Private Sub Form_Load()
Dim rsUser As Recordset
Dim intEmployeeID As Integer
Dim strEmployeeName As String
Set rsUser = CurrentDb.OpenRecordset("SELECT * FROM tblEmployees", dbOpenSnapshot, dbReadOnly)
rsUser.FindFirst "ADLogin='" & Environ("USERDOMAIN") & "\" & Environ("USERNAME") & "'"
If rsUser.NoMatch Then
' User does not have access to the application
rsUser.Close
Set rsUser = Nothing
Application.Quit
Else
' User with this AD Login has been found and that means that he does have access
intEmployeeID = rsUser("EmployeeID")
strEmployeeName = rsUser("EmployeeName")
TempVars("EmployeeID") = intEmployeeID
TempVars("EmployeeName") = strEmployeeName
DoCmd.OpenForm "frm_MainMenu"
Forms!frm_MainMenu.Requery
DoCmd.Close acForm, Me.Name, acSaveYes
Forms!frm_MainMenu!txtLoggedUser = TempVars("EmployeeName")
End If
rsUser.Close
Set rsUser = Nothing
End Sub
Then I will use TempVars("EmployeeID") throughout the application to make forms and buttons available and so on.
My question is: Is this a good practice to do? Is it secure? Is there perhaps a better way to do this? Thanks for any tips.
First of all let me start by saying Access is not secure, but it depends on your colleagues knowledge and how far are they willing to go.
In terms of your solution, I believe there's no need to load the entire table to the recordset and then try to find the desired record when you can filter it directly at source. In addition, string concatenation is (most of the times) bad practice, instead create a query (since its usage will be frequent) and pass the inputs as parameters.
See an example:
The query (your fields might be different but you get the idea)
You can also create a temporary query from code.
To call it and check the logged user:
Lastly, I would change the
intEmployeeIDvariable to be of typeLongand add error handling to the method.