Gestion itinérante de droits, la méthode du trousseau de clés
Par Pascal Cambier
Download
Téléchargez le classeur Excel de calcul des trousseaux et la base .mdb
d'exemple.
Lisez Lisez-moi.txt
Fichier ZIP de 61 Ko
Préliminaires
Si cette méthode a d’abord été pensée pour une application Access (dans
presque toutes ses versions), elle peut être adaptée en Excel, en VB
et en d’autres langages.
Elle nécessite des prérequis et/ou une volonté d'approndir par une
recherche personnelle sur le Web.
Google peut être votre ami.
Liminaires
Dans une application multi utilisateurs, les droits ne sont pas
nécessairement identiques pour tout le monde.
Certains utilisateurs ont accès à des fonctionnalités mais pas à
d’autres et vice-versa.
« Dupont » peut éditer certaines données que
« Durand » ne peut que
consulter, et en partie seulement. Ce dernier peut aussi éditer
d’autres données que le premier ne pourra consulter, etc.
La gestion de sécurité intégrée d’Access ne répond pas à ces besoins.
Mauvaise idée
Écrire dans des tables qui peut faire quoi, ou quoi peut être fait
par qui n’est pas une sinécure, est source d’erreurs et est lourd à
gérer lors de la venue d’un nouvel utilisateur, par exemple.
La bonne idée…
… est, lors d’un login, de munir l’utilisateur d’un trousseau de clés
(en fait un entier long) lui permettant d’accéder ou pas aux
fonctionnalités barrées par une porte.
Il faut comprendre que c’est la clef qui ouvre et pas l’utilisateur.
Cela permet de cloisonner par clé et non pas par utilisateur et donc
d’avoir une programmation souple : il suffit d’indiquer la clé pour
chaque action.
Attention !
Pour que cette protection soit efficace, l’utilisateur ne doit pas
pouvoir la contourner.
L’application doit donc être aboutie pour pouvoir être exécutée en mode
RUNTIME.
Introduction
La clé sera un donc un nombre de type entier long, soit 32 bits signés
et donc 31 utilisables (le 32ème bit servant au signe).
Pour plus d’informations sur le binaire et l’algèbre de Boole allez
voir cette petite introduction http://www.cambier.eu/pascal/notes/initiation/ini02.html
- Le bit 0 vaut 2^0, 1
- Le bit 1 vaut 2^1, 2
- Le bit 8, 256
- Le bit 16, 65.536
Etc.
Pour calculer le trousseau
des clés une et seize, il suffit de sommer 65536 et 2,
soit 65538 dont la représentation binaire est : 00000000000000010000000000000010.
Bien entendu, vous pouvez avoir plusieurs portes avec la même clé.
Si vous n’avez pas assez de 31 clés, vous pouvez munir vos utilisateurs
d’un deuxième trousseau. Vous avez alors trois possibilités :
- C’est le trousseau 1 OR le trousseau 2, soit 31 + 31 clés.
- C’est le trousseau 1 ET le trousseau 2, soit 31 x 31 clés.
(une porte du trousseau 1 donne sur des portes du trousseau 2)
- Un mix des deux ci-dessus, toujours pour 961 clés, et si ce
n’est toujours pas assez, un 3ème trousseau pour 29.791 clés ;-)
Préparation des trousseaux
Un classeur Excel va vous faciliter le travail. Il suffit d’énumérer
les différentes actions / fonctionnalités, en n’oubliant pas qu’il peut
y avoir plusieurs portes avec la même clé. Puis les différents
utilisateurs et enfin mettre un « 1 » en regard des uns et des autres,
là où il le faut !
Download.
Mise en œuvre, fonctionnalités de base
- Il faut donc une table reprenant les caractéristiques des
utilisateurs.
- Un formulaire de login
- Une fonction qui teste si la clé demandée est dans le
trousseau
Table des utilisateurs
Formulaire de LOGIN
Dans un module standard
Option Compare Database
Option Explicit
'variables globales
Public sGlb_User_Id As String
Public lGLb_User_Trousseau As Long
Public sGlb_User_Nom As String
Public sTitre As String
Frm_901_Login
Option Compare Database
Option Explicit
Private Sub Cmd_Commencer_Click()
Dim Rst As ADODB.Recordset
Set Rst = New ADODB.Recordset
Dim CN As ADODB.Connection
Set CN = CurrentProject.Connection
Dim sSql As String
Dim sCrit As String
Dim sPass As String
Rst.Open "Tbl_L_Users", CN,
adOpenStatic, adLockOptimistic
'user ID
If IsNull(Txt_user_id) Then
MsgBox "Veuillez choisir un identificateur", vbCritical + vbOKOnly
Txt_user_id.SetFocus
GoTo SubExit
End If
If IsNull(Txt_pass) Then
MsgBox "Veuillez taper un mot de passe", vbCritical + vbOKOnly
Txt_pass.SetFocus
GoTo SubExit
End If
sCrit = "[user_id] = '" &
Txt_user_id & "'"
Rst.Find sCrit
If Rst.EOF Then
MsgBox "Identificateur ou mot de passe incorrect", vbCritical +
vbOKOnly, sTitre
Txt_user_id.SetFocus
GoTo SubExit
End If
'mot de passe
sPass = Rst("user_pass")
If sPass <> Txt_pass Or
IsNull(sPass) Then
MsgBox "Identificateur ou mot de passe incorrect", vbCritical +
vbOKOnly, sTitre
Txt_user_id.SetFocus
GoTo SubExit
End If
If Not IsNull(Txt_N1) Or Not
IsNull(Txt_N2) Then 'nouveau mot de passe
If Txt_N1 = Txt_N2 Then 'Okay
Rst("user_pass") = Txt_N2
Rst.Update
sPass = Txt_N2
Else
MsgBox "Les deux lignes du nouveau mot de passe ne sont pas
identiques", vbCritical + vbOKOnly, sTitre
Me.Txt_N1.SetFocus
GoTo SubExit
End If
End If
If LCase$(sPass) = LCase$(sGlb_User_Id)
Then
MsgBox "Le mot de passe ne peut pas être vos initiales.
Obligation de changer. Merci.", vbCritical + vbOKOnly, sTitre
Me.Txt_N1.SetFocus
GoTo SubExit
End If
'TROUSSEAU
sGlb_User_Id = Txt_user_id
sGlb_User_Nom = Rst("user_nom")
lGLb_User_Trousseau =
Rst("user_trousseau")
Rst.Close
Set Rst = Nothing
Set CN = Nothing
DoCmd.Close acForm, Me.Name, acSaveYes
Exit Sub
SubExit:
Rst.Close
Set Rst = Nothing
Set CN = Nothing
End Sub
Private Sub CmdAnnuler_Click()
On Error GoTo Err_CmdAnnuler_Click
DoCmd.Close
Exit_CmdAnnuler_Click:
Application.Quit acQuitSaveAll
'Annuler = quitter l'application
Exit Sub
Err_CmdAnnuler_Click:
MsgBox Err.Description
Resume Exit_CmdAnnuler_Click
End Sub
Private Sub Form_Load()
'initialise la variable globale avec le titre / nom de l'application
sTitre = "°Trousseaux°"
End Sub
Private Sub Txt_N2_LostFocus()
Me.Cmd_Commencer.SetFocus
End Sub
Les fonctions à utiliser
Public Function PositionBit(Nombre As Long, Position As
Byte) As Boolean
'Regarde dans Nombre si le bit à la
position est à 1
PositionBit = (Nombre And 2 ^ Position)
<> 0
End Function
Public Function IsCle(Cle As Byte) As Boolean
'Vérifie si la clef est bien dans le
trousseau "lGLb_User_Trousseau", _
Variable publique initialisé lors du
Login
Dim Okay As Boolean
Okay = False
If IsLogin Then
Okay = PositionBit(lGLb_User_Trousseau, Cle)
End If
If Not Okay Then
MsgBox "Désolé, vous n'avez pas les droits nécessaires pour accéder à
cette fonctionnalité", , sTitre
End If
IsCle = Okay
End Function
Public Function IsLogin() As Boolean
If IsNull(sGlb_User_Id) Or sGlb_User_Id
= "" Then
'pas logué. ouvre le formulaire de login en dialogue. _
Dans le login on ne peut que s'identifier ou quitter l'application
DoCmd.OpenForm "Frm_901_login", acNormal, , , , acDialog
End If
IsLogin = True
End Function
Mise en œuvre, le menu général
Le menu général existe depuis longtemps en Access, certainement au
moins depuis la version 97.
Il est très facile à mettre en œuvre et à modifier. Le code a une
syntaxe un peu vieillotte, mais rien ne vous empêche de le moderniser.
Créer le menu général
2000 à 2003
2007
Dans le menu outils (ou le ruban outils de bases de données), chercher
le menu général (ou Switchboard Manager)
Yes !
Menu général créé
Un formulaire « Menu général » a été créé.
Une table « Switchboard Items » a été créée.
Ajoutez un champ « Cle »
comme ci-dessus.
Mettez à jour la colonne « Cle ».
Notez que vous pouvez modifier le contenu de la table sans passer par
l’assistant.
Par exemple, j’ai moi-même modifié l’emplacement (ItemNumber) des «
retour au menu général » en 8, dernière position possible.
Modifiez le code du menu général comme suit :
Private Function HandleButtonClick(intBtn As Integer)
.
.
.
' If no item matches, report the error and exit the function.
If (rs.EOF) Then
MsgBox "Une erreur s'est produite lors de la lecture de la table
d'élément du Menu général."
rs.Close
Set rs = Nothing
Set con = Nothing
Exit Function
End If
'---------- Trousseau de clé
If Not IsCle(rs("Cle")) Then Exit
Function
'----------- fin de trousseau
Select Case rs![Command]
' Go to another switchboard.
Case conCmdGotoSwitchboard
.
.
.
Essayez !
La touche finale : le verrouillage
Contrôler le démarrage
D’abord, faire en sorte que le menu général soit affiché
automatiquement au démarrage.
2007
2000 à 2003
Runtime
Utilisez le mode Runtime, ou mieux, carrément le runtime, disponible à
l’adresse
http://www.microsoft.com/downloads/details.aspx?FamilyID=d9ae78d9-9dc6-4b38-9fa6-2c745a175aed&displaylang=fr
Pour le mode runtime, utilisez la ligne de commande (dans un .bat)
C:\Program Files\Microsoft Office\OfficeXX\MSACCESS.EXE
/runtime X:\dossier\dataBase.mdb
Où OfficeXX
est 10, 11 ou 12 pour
respectivement XP, 2003 et 2007
Vous pouvez aussi utiliser un script VBS. Par exemple :
option explicit
Dim Fso
Dim WshShell
Dim Dossier_Local
Dim Nom_Base
Dim Nom_Complet
Dossier_Local = "x:\dossier"
Nom_Base = "database.mdb"
Set Fso = CreateObject("Scripting.FileSystemObject")Set WshShell =
WScript.CreateObject("WScript.Shell")
Nom_Complet = CHR(34) & "C:\Program Files\Microsoft
Office\OfficeXX\MSACCESS.EXE"
Nom_Complet = Nom_Complet & chr(34) & " /runtime "
& Fso.BuildPath(Dossier_Local,Nom_Base)
WshShell.Run Nom_Complet
, 3
Désactiver la touche Shift (Maj)
Beaucoup de personnes savent que l’on peut inhiber les options de
démarrage d’une application en maintenant la touche shift appuyée
durant son démarrage.
Le code suivant désactive la touche Shift
Attention, il faut que le code soit au moins exécuté une fois pour que
cela fonctionne (sa simple présence ne suffit pas).
Public Sub Shift_Desactive()
On Error GoTo errProperty
Dim dbDAO As DAO.Database
Dim prtDAO As DAO.Property
Set dbDAO = CurrentDb()
dbDAO.Properties("AllowByPassKey") =
False
okProperty:
'ferme les objets proprement
Set prtDAO = Nothing
dbDAO.Close
Set dbDAO = Nothing
Exit Sub
errProperty:
'à la première utilisation, il faut
créer la propriété !
Set prtDAO =
dbDAO.CreateProperty("AllowByPassKey", 1, False)
dbDAO.Properties.Append prtDAO
Resume okProperty
End Sub
Modifiez le code du menu général comme suit pour exécuter le code au
démarrage de l’application.
Private Sub Form_Open(Cancel As Integer)
' Minimize the
database window and initialize the form.
' Move to the switchboard page that is marked as the default.
Me.Filter = "[ItemNumber] = 0 AND [Argument] = 'Par défaut' "
Me.FilterOn = True
'----- Début Trousseau
Shift_Desactive 'désactive la touche
SHIFT
'----- Fin trousseau
End Su
b
Le code suivant réactive la touche shift. Et bien oui, il y a une
parade :-(
Public Sub Shift_Reactive()
Dim dbDAO As DAO.Database
Dim prtDAO As DAO.Property
Set dbDAO =
DBEngine.OpenDatabase("X:\Dossier\base")
dbDAO.Properties("AllowBypassKey") = True
MsgBox dbDAO.Name & " est de
nouveau accessible."
Set prtDAO = Nothing
dbDAO.Close
Set dbDAO = Nothing
End Sub
Contrôler l’accès en mode « Non Runtime »
Si l’utilisateur a Access complet, il peut accéder directement à la
base sans passer par le script ou batch de démarrage.
Un petit formulaire et un peu de code va résoudre le problème.
Option Compare Database
Option Explicit
Private Sub Cmd_Annuler_Click()
Application.Quit
End Sub
Private Sub Cmd_Ok_Click()
If Me.TxtInput <>
"password" Then Application.Quit
DoCmd.Close
End Sub
Comme vous pouvez le voir, le mot de passe est en clair dans le code.
Ce n’est pas trop grave parce que la dernière étape sera de rendre le
code inaccessible.
Modifiez une dernière fois le code du menu général comme suit:
Private Sub Form_Open(Cancel As Integer)
' Minimize the database window
and initialize the form.
' Move to the switchboard page
that is marked as the default.
Me.Filter =
"[ItemNumber] = 0 AND [Argument] = 'Par défaut' "
Me.FilterOn
= True
'----- Début Trousseau
Shift_Desactive 'désactive la
touche SHIFT
If SysCmd(acSysCmdRuntime) = 0
Then 'mode runtime
DoCmd.OpenForm
"Frm_902_No_Runtime", acNormal, , , , acDialog
End If
'----- Fin trousseau
End Sub
Faire un MDE, ADE ou ACCDE
Commencez par compiler le code VBA, corrigez les éventuelles erreurs.
Temps qu’il restera une erreur, vous ne pourrez pas fabriquer le .MDE
Vous trouverez beaucoup d’explications ici
http://office.microsoft.com/fr-fr/access-help/fichiers-mde-et-ade-HP001051112.aspx
Conclusion
Nous espérons que cela vous aura apporté des solutions.
Vous pouvez renforcer la sécurité en utilisant en concomitance celle
offerte par Access.