Daten schützen und Benutzer verwalten mit Access 2010/2013 und Format ACCDB

22. November 2013

Wir beschränken uns hier auf folgende Situation, die für unsere Access-Projekte immer dann zutrifft, wenn die Daten nicht auf einem SQL-Server liegen: 

  • Es wird das Dateiformat ACCDB verwendet.
  • Es gibt eine Datei mit Daten (DATEN.ACCDB) und eine Datei mit Formularen, Berichten und Programmcode (CODE.ACCDB).
  • Die Benutzer sollen die Daten nur über die Formulare einsehen und bearbeiten können.
  • Niemand außer den Entwicklern soll den VBA Code sowie die Entwurfsansicht von Formularen und Berichten ansehen können.

User Group Account Manager

Für die altbekannten Funktionen zur Bearbeitung der Benutzerberechtigungen gibt es in Access 2010 bei Verwendung des Dateiformats ACCDB keine Menü-Einträge mehr. Abhilfe schafft hier das Add-In » UGAM - User Group Account Manager für Access 2007/2010 von Jean Pierre Allain, über welches man diese Funktionen weiterhin nutzen kann.

Den User Group Account Manager installiert man in Access im Ribbon "Datenbanktools" über das Menü "Add-Ins" / "Add-In-Manager...". Danach erreicht man ihn über "Add-Ins" / "User and group...".

Access: Add-In User Group Account Manager

Projektbezogene Arbeitsgruppendatei anlegen

Im ersten Schritt wird mit Hilfe von UGAM eine projektspezifische Arbeitsgruppendatei erstellt. Dazu wird in UGAM der Button "Workgroup Administrator" verwendet. Die Arbeitsgruppendatei muss nicht unbedingt system.mdw heißen, sie muss lediglich die Extension MDW haben.

Achtung: Bevor man eine neue Arbeitsgruppendatei (MDW) erstellt, muss man sich unbedingt die aktuelle verwendete Arbeitsgruppendatei merken und Access nach dem Erstellen der neuen MDW wieder mit der gemerkten Arbeitsgruppendatei verbinden. Sonst arbeitet Access standardmäßig mit dieser neuen Arbeitsgruppendatei, also auch in anderen Projekten, was man meisten ja nicht gewünscht ist. Also einfach noch einmal auf "Workgroup Administrator" klicken und der alten MDW "Beitreten…".

Falls man diese Warnung zu spät liest: Die alte Arbeitsgruppendatei steht noch im Feld "Workspace", solange man das Fenster von "User and Group Management" noch nicht wieder geschlossen hat.

Starten von Access mit der spezifischen Arbeitsgruppendatei

Nun wird Access beendet und mit einem neu angelegten Link so gestartet, dass es mit der korrekten MDW verbunden ist. Der Startlink muss dazu den Parameter /wrkgrp system.mdw enthalten, er könnte also zum Beispiel so aussehen:

"C:\Program Files (x86)\mso2010\Office14\MSACCESS.EXE" /wrkgrp i:\myproject\myproject.mdw

Einen eigenen Administrator und Benutzer anlegen

Über den Button "User and group accounts" in UGAM gelangt man in den Dialog "Benutzer- und Gruppenkonten".

Hier werden zwei Aktionen durchgeführt:

  • Unter dem Reiter "Anmeldungskennwort ändern" wird für den Standard-Administrator "Admin" ein Passwort gesetzt. Das Feld "Altes Kennwort" bleibt leer.
  • Es wird ein neuer Account für den (selbstbenannten) Admin des Projekts angelegt, der später alle Rechte bekommt und auch der Besitzer der Datenbanken sein sollte. Achtung: Dem neuen Administrator muss unbedingt die Gruppe "Administratoren" zugewiesen werden.
Daten schützen mit Access 2010 und ACCDB

Nun wird Access wieder beendet und erneut mit dem projekt­be­zogenen Start-Link geöffnet. Beim Öffnen bzw. Anlegen einer Daten­bank wird nun der Benutzer erfragt - hier wird der Name des neuen Administrators eingegeben. Für die eigene Arbeit mit der Datenbank kann man den Start-Link auch um den Parameter /user ‹myadmin› erweitern, dann muss man den Namen nicht mehr in das Login-Fenster eintippen.

Über den Button "User and group accounts" in UGAM, Reiter "Anmeldungskennwort ändern" trägt man nun ein neues Kennwort für den neuen Admin-Zugang ein. Auch dieses Passwort kann man im Link angeben - hierzu gibt es den Parameter /pwd.

Außerdem können nun auch die Accounts für die zukünftigen Benutzer angelegt werden. Die Benutzer können sich zunächst ohne Passwort einloggen und sich dann selbst ein Passwort zuweisen. Dazu muss man ihnen wiederum Zugang zu UGAM geben.

Gesicherte Datenbank-Dateien erstellen

Nun wird Access wieder mit dem Start-Link und dem Account des Projekt-Administrators gestartet und es werden zwei neue Datenbanken angelegt - eine für das Frontend (CODE.ACCDB) und eine für die Daten (DATEN.ACCDB). Der Projekt-Administrator ist nun Besitzer der beiden Datenbanken.

Falls es bereits eine Vorgänger-Version der Applikation gibt, werden sämtliche Objekte aus dem Frontend bzw. Backend jeweils in die entsprechende neue Datenbank importiert. Ansonsten können nun die benötigten Objekte angelegt werden.

Tabellen in der DATEN.ACCDB schützen

Als nächstes werden die Tabellen in der DATEN.ACCDB geschützt. Dazu wird sie wieder mit dem Account des Projekt-Administrators geöffnet.

Für eine Access-Datei im Format ACCDB gilt, dass die Berechtigungen für Tabellen nur dann berücksichtigt werden, wenn sie als Systemtabellen deklariert wurden (Attribut dbsystemobject). Über den Button "Check table attributes" in UGAM wird das Attribut für alle Tabellen gesetzt.

Über den Button "User and group permissions" öffnet sich das gewohnte Fenster zum Setzen der Berechtigungen:

Access: Benutzer-Berechtigungen setzen

Berechtigungen werden für ACCDB-Dateien nur noch für Tabellen berücksichtigt (und auch nur, wie bereits erwähnt, für Systemtabellen), deshalb werden auch nur für die Tabellen Berechtigungen gesetzt. 

  • Die Gruppen bekommen sämtliche Rechte entzogen.
  • Der Benutzer "Administrator" (also der Standard-Administrator von Access) bekommt ebenfalls sämtliche Rechte entzogen.
  • Der Projekt-Administrator bekommt alle Rechte.
  • Die Benutzer bekommen die Rechte, die sie zum Bearbeiten der Daten benötigen: "Entwurf lesen", "Daten lesen", "Daten aktualisieren", "Daten einfügen", "Daten löschen".

Achtung: Neue Tabellen sind nicht automatisch Systemtabellen. Es ist deshalb nicht damit getan, die gewünschten Rechte auch für "<Neue Tabellen/Abfragen>" zu setzen.

Übrigens kann selbst der Administrator in der DATEN.ACCDB die Daten in den Tabellen zwar lesen, aber nicht bearbeiten. Möchte man Daten direkt in der DATEN.ACCDB bearbeiten, geht dies über eine Abfrage oder ein Formular. In der Regel ist es ja aber ausreichend, die Daten in der CODE.ACCDB zu bearbeiten.

ACCDB gegen Öffnen durch nicht autorisierte Benutzer schützen

Da die Berechtigungen nur für die Tabellen berücksichtigt werden, wird nun noch ein Mechanismus gebraucht, um die Datenbank dagegen zu schützen, dass sie von einem anderen Benutzer als dem Projekt-Administrator geöffnet werden kann.

Wir erreichen das durch zwei Maßnahmen: 

  • Eine Autoexec-Funktion schließt die Datenbank sofort wieder, wenn der aktuelle Benutzer nicht der Admin ist.
  • Die Shift-Taste wird deaktiviert.

Die Funktion, welche vom Autoexec-Makro ausgeführt wird, lautet zum Beispiel:

Function AutoExec_Funktion()
Dim Admin As String
  Admin = "chanja"
  If Not (CurrentUser() = ADMIN) Then
    DoCmd.Quit acQuitSaveNone
  End If  
  Exit Function
End Function

Nun wird die Shift-Taste deaktiviert. Zuvor sollte man eine Sicherungskopie der Datei anlegen, denn nach diesem Schritt ist man selbst ausgesperrt, wenn man einen Fehler in der Autoexec-Funktion gemacht hat!

Folgender Code wird in der DATEN.ACCDB hinterlegt und einmal ausgeführt (!):

Public Sub ShiftKeyDisable()  
Dim Prp As DAO.Property  
  On Error Resume Next
  CurrentDb().Properties!AllowBypassKey = False
  If Err > 0 Then
    If Err = 3270 Then
      Set Prp = CurrentDb().CreateProperty("AllowBypassKey", dbBoolean, False)
      CurrentDb().Properties.Append Prp
      Set Prp = Nothing
    Else
      MsgBox Error
    End If
  End If
End Sub

Daten bearbeiten in der CODE.ACCDB

Die Tabellen aus der DATEN.ACCDB können nun ohne Kenntnis des Administrator-Accounts nicht mehr geöffnet und auch nicht in eine andere Datenbank importiert oder eingebunden werden.

Damit der Benutzer die Daten nun über die Formulare in der CODE.ACCDB bearbeiten kann, werden nun 

  • die Tabellen dort mit den Rechten des Administrators eingebunden und 
  • die Daten über Views WITH OWNERACCESS OPTION bearbeitet.

Die Tabellen kann man zum Beispiel so einbinden:

Public Function Tables_Attach() As Boolean

Dim DB As Database
Dim PathCode As String       ' vollständiger Dateiname für CODE.ACCDE
Dim PathData As String       ' vollständiger Dateiname für DATEN.ACCDB
Dim WSA As Workspace         ' Handle für Workspace (Admin-Rechte)
Dim DBCodeA As Database      ' Handle für CODE.ACCDE (Admin-Rechte)
Dim DBDataA As Database      ' Handle für DATEN.ACCDB (Admin-Rechte)
Dim SourceTD As TableDef, CodeTD As TableDef
Dim Msg As String

Const ERR_ElementNotFound = 3265   ' Element nicht in Aufzählung

  On Error GoTo Err_Tables_Attach
  
  ' Handles für WS und DBs
  Set DB = CurrentDb
  PathCode = DB.Name
  DB.Close: Set DB = Nothing
  Set WSA = DBEngine.CreateWorkspace("X", ADMINISTRATOR, PASSWORT)
  Set DBCodeA = WSA.OpenDatabase(PathCode)
  PathData = DirName(PathCode) & "/backend.accdb"
  Set DBDataA = WSA.OpenDatabase(PathData)
  
  DBCodeA.TableDefs.Refresh
  
  For Each SourceTD In DBDataA.TableDefs
    If Left$(SourceTD.Name, 4) <> "MSys" And Left$(SourceTD.Name, 1) <> "~" Then
      If Len(SourceTD.Connect) = 0 Then
        On Error Resume Next
        Set CodeTD = DBCodeA.TableDefs(SourceTD.Name)
        
        Select Case Err
          Case 0 ' Tabelle existiert bereits in Code-MDB: ggf. neu einbinden
            On Error GoTo Err_Tables_Attach
            If Len(CodeTD.Connect) = 0 Then
              Msg = "Eine Tabelle " & CodeTD.Name & " existiert bereits in der PROFI.ACCDE. Tabelle kann nicht eingebunden werden."
              GoTo Err_Tables_Attach
            End If
            ' Tabelle löschen und neu einbinden
            DBCodeA.TableDefs.Delete SourceTD.Name ' Tabelle in Code-MDB löschen
            Set CodeTD = DBCodeA.CreateTableDef(SourceTD.Name)
            CodeTD.SourceTableName = SourceTD.Name
            CodeTD.Connect = ";DATABASE=" & DBDataA.Name
            DBCodeA.TableDefs.Append CodeTD
          
          Case ERR_ElementNotFound ' Tabelle existiert nicht in Code-MDB
            On Error GoTo Err_Tables_Attach
            Set CodeTD = DBCodeA.CreateTableDef(SourceTD.Name)
            CodeTD.SourceTableName = SourceTD.Name
            CodeTD.Connect = ";DATABASE=" & DBDataA.Name
            DBCodeA.TableDefs.Append CodeTD
            
          Case Else ' anderer Fehler
            GoTo Err_Tables_Attach
        End Select
      End If
    End If
  Next SourceTD
  Set CodeTD = Nothing: Set SourceTD = Nothing
  
  Set WSA = Nothing
  Set DBCodeA = Nothing
  Set DBDataA = Nothing
  
  Tables_Attach = True
  Exit Function
  
Err_Tables_Attach:
  MsgBox "Fehler beim Einbinden der Tabellen:" & vbCrLf & Error
  Tables_Attach = False
  Exit Function

End Function

Für jede Tabelle, deren Daten vom Benutzer bearbeitet werden sollen, wird nun eine Abfrage ‹MeineTabelle›_VIEW angelegt mit folgendem SQL-Statement:

SELECT * FROM MeineTabelle WITH OWNERACCESS OPTION;

Daten aus Abfragen bzw. SQL-Statements, die auf solchen Views basieren, kann der Benutzer ohne Probleme bearbeiten. Tabellen, Abfragen und SQL-Statements können in VBA natürlich auch über einen Workspace mit Admin-Rechten bearbeitet werden - damit hat man dann ebenfalls volle Berechtigung.

Für das Frontend eine ACCDE verwenden

Die CODE.ACCDB schließlich schützen wir, indem wir eine CODE.ACCDE ausliefern, welche von einem normalen Benutzer nur in der Runtime-Umgebung geöffnet werden kann. Dies erreichen wir etwa durch folgende Autoexec-Funktion:

Function Autoexec_Funktion()
  If Not SysCmd(acSysCmdRuntime) Then
    If Not (CurrentUser() = ADMIN) Then
      DoCmd.Quit acQuitSaveNone
    End If
  End If
  Exit Function
End Function

Und auch in der CODE.ACCDE muss die Shift-Taste per ShiftKeyDisable() deaktiviert werden.

Der normale Benutzer kann Tabellen und Abfragen aus der CODE.ACCDE zwar in eine eigene Datenbank importieren, kann aber nicht auf die Daten zugreifen.

User Group Account Manager

Jean Pierre Allain von der ABISS GmbH hat nicht nur ein sehr hilfreiches Add-In für Access 2010 entwickelt, sondern mich netterweise beim Schreiben dieses Beitrags konstruktiv unterstützt.