Berechtigungsmanagement

13. Januar 2021 16:26

Hallo an alle,

ich habe die Herausforderung das die Rechnungswesenabteilung nicht möchte das geb. Einkaufsrechnungen mit der Rechnungsart "Buchungsbeleg" sieht, außer die Abteilung selbst.

Bei Profilen die man nicht anpassen kann hätte ich einfach ein Profil erstellt welches einen Vordefinierten Filter nutzt.

Aber das ist bei den Profil nicht möglich / nicht gewollt.

Wie kann man die Anforderung umsetzen?

Danke schon mal vorab für eure Mühe.

Re: Berechtigungsmanagement

13. Januar 2021 16:48

Hi,

sollte mit Sicherheitsfilter möglich sein
https://docs.microsoft.com/en-us/dynamics-nav/how-to--set-security-filters

Re: Berechtigungsmanagement

13. Januar 2021 16:56

Wir haben bei uns auch die unterschiedlichsten Anforderungen an sichtbare bzw. nicht sichtbare Datensätze je nach Abteilung, so dass wir uns hierfür ein kleines Modul gebaut haben, über welches man pro Tabelle, Benutzerrolle/UserID einen frei definierbaren Filter definieren kann.

Screenshot.png


Nachdem man dort die Tabellenfilter definiert hat, wird über eine Action im Menüband eine Codeunit (im Textformat) erstellt, welche für alle Pages der beteiligten Tabellen einen Event-Subscriber erstellt, um darüber die Filter anzuwenden.
(Da wir den Object Manager Advanced bei uns einsetzen kann die Action die erstellte Codeunit sogar direkt importieren und kompilieren, ansonsten müsste man den Schritt halt von Hand machen.)

Man könnte darüber also für verschiedene Benutzerrollen unterschiedliche Filter für die Tabellen 38, 122 und 124 definieren und alle Pages, welche eine dieser Tabellen als SourceTable hat, würden diese Filter direkt beim Öffnen in der angegebenen Filtergruppe anwenden.

Anstelle der Action, welche die Codeunit mit den Event-Subscribern erstellt, könnte man auch händisch für alle gewünschten Pages einen Event-Subscriber in einer Codeunit anlegen, aber Programmierer sind von Natur aus faule Leute (deswegen nennt man sie ja auch E-D-Fauler :twisted: ) und hassen sich ständig wiederholende Arbeiten.
Darüber hinaus ist durch diese Action sichergestellt, dass auch wirklich bei allen Pages zu einer der enthaltenen Tabellen entsprechende Event-Subscribers existieren.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: Berechtigungsmanagement

13. Januar 2021 17:01

sweikelt hat geschrieben:sollte mit Sicherheitsfilter möglich sein

Der Nachteil bei Einsatz von Sicherheitsfiltern ist jedoch, dass dann die Datensätze auch vor NAV versteckt werden.

Beispiel:
Eine bestimmte Personengruppe darf zwar grundsätzlich die Posten sehen, jedoch sollen bestimmte Posten (z. B. von Lohn-/Gehalts-Konten) vor ihnen versteckt werden.
Wenn diese Personengruppe jetzt einen Beleg buchen möchte und zufällig der letzte (tatsächlich vorhandene) Posten ein versteckter Posten ist, dann würde NAV eine bereits vergebene "Lfd. Nr." als nächste "Lfd. Nr." ermitteln.
Ergebnis: Buchen ist nicht mehr möglich.

Daher verzichten wir bei uns auf die Sicherheitsfilter, da wir nicht vorhersagen können, wer sich wo für wen welche Filter wünscht.
Stattdessen haben wir unser Tool geschrieben, da dieses die Datensätze nur vor dem Anwender versteckt, nicht jedoch vor dem System.

Re: Berechtigungsmanagement

13. Januar 2021 17:13

Timo Lässer hat geschrieben:Wenn diese Personengruppe jetzt einen Beleg buchen möchte und zufällig der letzte (tatsächlich vorhandene) Posten ein versteckter Posten ist, dann würde NAV eine bereits vergebene "Lfd. Nr." als nächste "Lfd. Nr." ermitteln.
Ergebnis: Buchen ist nicht mehr möglich.


tolles Beispiel! - wusste ich noch nicht. vielen Dank, werde ich zukünftig definitiv bedenken

Re: Berechtigungsmanagement

15. Januar 2021 13:29

Hallo Timo Lässer,

ehrlich gesagt klingt deine Lösung super! Aber ich habe keine Ahnung was du da gemacht hast. Das liegt sicher auch daran das ich bisher nichts in NAV entwickel. Kann man sich das Thema irgendwie nähern bzw. noch irgendwo nachlesen?
Kannst du hier etwas empfehlen? Die passende Umgebung zum entwickeln hätte ich.

Re: Berechtigungsmanagement

15. Januar 2021 13:54

Die Programmierung basiert (wie fast alle unserer eigenen NAV-Funktionalitäten) auf RecordRefs und dem Event-System:

  • Zuerst habe ich die Tabelle (und die dazu passende Page) angelegt.
  • Dann eine Funktion, welche alle zu einer Tabelle in Frage kommenden Datensätze ermittelt (für den konkreten Benutzer, für die dem Benutzer zugeordneten Benutzerrollen und die Allgemeingültigen).
  • Dann eine Funktion, welche die in Frage kommenden Filter auf einen übergebenen RecordRef anwendet.
  • Dann habe ich eine Codeunit mit zwei beispielhaften Event-Subscribern erstellt und im Text-Format exportiert.
    Diese zieht sich aus dem Rec der Page einen RecordRef und übergibt ihn an die Funktion, welche die Filter anwendet. Den RecordRef übergebe ich dann wieder an den Rec der Page.
  • Diese Textdatei habe ich dann als Vorlage für die Codeunit genommen, welche mir diese Event-Subscriber-Codeunit erstellen soll. (Wann muss wo was in die Textdatei geschrieben werden?)
  • Als i-Tüpfelchen habe ich dann eine Action erstellt, welche die automatisch erstellte Codeunit mittels der Funktionen des Object Manager Advanced über das "Object Import Worksheet" importiert, so dass das auch unsere ERP-Consultants ausführen könnten ohne Zugriff auf den Dev-Client haben zu müssen.

Wenn man den Programmcode sieht, dann ist das kein Hexenwerk, wenn man sich mit RecordRef, Events und dem Aufbau einer NAV-Objekt-Textdatei auskennt.
Die "Genialität" steckt meiner Meinung nach einfach nur in der Idee, auf die man erstmal kommen muss.

Anfangs hatte die "Codeunit-Erstell-Codeunit" für jede Page mit einer SourceTable ein Event erstellt.
Wenn man nur den NAV-Standard einsetzt, dann dürfte das noch funktionieren, jedoch nicht mehr, wenn man eine umfangreiche Branchenlösung und/oder mehrere Add-Ons von Drittanbietern in der Datenbank integriert hat.
Dann gibt es in der erstellten Codeunit zu viele Event-Funktionen, die NAV nicht mehr verwalten kann.
Daher haben wir es nachträglich dahingehend eingeschränkt, dass die Codeunit nur Events für Pages erstellt, dessen SourceTable-ID auch tatsächlich in der Tabelle aufgeführt ist.

Re: Berechtigungsmanagement

18. Januar 2021 17:16

Timo Lässer hat geschrieben:Die Programmierung basiert ... auf RecordRefs und dem Event-System...

Ganz ehrlich? Ich finde diese Lösung echt genial. Und ich habe wahrscheinlich spontan eine Idee, was ich damit mache. Danke dafür.

Re: Berechtigungsmanagement

19. Januar 2021 10:06

m_schneider hat geschrieben:Ganz ehrlich? Ich finde diese Lösung echt genial. [...] Danke dafür.

Gern geschehen, das freut mich sehr.

Ich muss aber auch gestehen, dass ich von 2010 bis 2015 in der glücklichen Situation war, für einen Kunden gearbeitet haben zu dürfen, der auch bereit war für "Jugend forscht" 8-) Zeit und Geld bereitzustellen.
Da konnte ich mir solche (bis dahin eher ungewöhnliche) Techniken ausdenken und in der Praxis anwenden.
Seit 2016 ist er nicht mehr mein Kunde, sondern mein Arbeitgeber und wir haben die Erfahrungen und Techniken noch weiter ausgebaut.
Alle unsere Eigenentwicklungen basieren auf RecordRef und dem Eventsystem, so dass eine Funktionalität automatisch für die Bereiche Verkauf, Einkauf, Service, Umlagerung, Fertigung, Montage und unserer Branchenlösung für Vermietung eingesetzt werden können.

Re: Berechtigungsmanagement

19. Januar 2021 12:40

Die beste Idee ist die Verwendung des Eventsystems. Heißt ohne Anpassung der Standards...

Re: Berechtigungsmanagement

22. Januar 2021 10:31

Timo Lässer hat geschrieben:Dann gibt es in der erstellten Codeunit zu viele Event-Funktionen, die NAV nicht mehr verwalten kann.


Wie jetzt? Ist das so?
Scheint mir, dass es an globalen Events mangelt. Z.b: ein OnGlobalOpenPageEvent

Deine Idee und Umsetzung finde ich allerdings mega spitze.

Re: Berechtigungsmanagement

22. Januar 2021 12:13

vandyke hat geschrieben:
Timo Lässer hat geschrieben:...Scheint mir, dass es an globalen Events mangelt. Z.b: ein OnGlobalOpenPageEvent...

Dieses Event halte ich für höchst gefährlich. Zum Thema Performance und so.

Re: Berechtigungsmanagement

22. Januar 2021 13:57

Meinste? Was soll denn das Änderungsprotokoll dazu sagen?
Es könnte ja auch analog zum Änderungsprotokoll gestaltet sein, dass nur beim 1. Öffnen einer Page geprüft wird, ob diese in einer Einrichtungstabelle existiert. ( --> z.B.:OnAfterGetDatabasePageTriggerSetup).

VG

Re: Berechtigungsmanagement

25. Januar 2021 13:32

vandyke hat geschrieben:
Timo Lässer hat geschrieben:Dann gibt es in der erstellten Codeunit zu viele Event-Funktionen, die NAV nicht mehr verwalten kann.
Wie jetzt? Ist das so?
Ja, leider. Ob das in aktuellen CUs und/oder NAV/BC-Versionen noch ein Problem ist weiß ich nicht.
Fakt ist, dass meine "Codeunit-schreibende Codeunit" am Anfang alle Pages mit einer SourceTable-ID abonniert hatte.
Da wir zu dem Zeitpunkt noch ganz am Anfang des Projektes waren und somit noch keine Branchenlösungs-Objekte und Drittanbieter-AddOns drin hatten, funktionierte das hervorragend.
Als wir dann die ganzen AddOns drin hatten und ich die Codeunit neu generieren ließ, konnte ich die erstellte Codeunit zwar noch kompilieren, aber beim ersten Öffnen einer beliebigen Page (mit einer SourceTable) stürzte der NAV-Client mit einer Fehlermeldung der Art "Zu viele Handle definiert" ab.
Daraufhin hatte ich die Codeunit umgeschrieben, so dass sie nur Pages zu den tatsächlich eingetragenen SourceTables abonniert.

vandyke hat geschrieben:Deine Idee und Umsetzung finde ich allerdings mega spitze.
Vielen Dank für das Kompliment!

Re: Berechtigungsmanagement

25. Januar 2021 13:40

m_schneider hat geschrieben:
vandyke hat geschrieben:...Scheint mir, dass es an globalen Events mangelt. Z.b: ein OnGlobalOpenPageEvent...
Dieses Event halte ich für höchst gefährlich. Zum Thema Performance und so.

Globale Events waren schon immer gefährlich, da macht so ein OnGlobalOnOpenPage nicht mehr viel aus.

Ich kann mich daran erinnern, dass mal jemand eine vorhandene Funktion in den OnDatabaseModify-Trigger der Codeunit 1 eingebunden hatte, damit sichergestellt ist, dass die Funktion immer ausgeführt wird.
(Da gab es noch kein Event-System, sondnern nur diese Trigger in der Codeunit 1.)
Leider hatte er/sie nicht bemerkt, dass in der vorhandenen Funktion ein weiterer Funktionsaufruf steckte, welcher einen Commit ausführte - nach jedem Modify!
Was dann bei einem Buchungs-Abbruch als Ergebnis herauskam, könnte ihr euch denken!? :shock:

OnGlobalOnOpenPage, OnGlobalOnReportRun, OnGlobalOnAfterGetRecord, ... wären manchmal schon echt nützlich.