Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Προσθήκη ρόλων σε εφαρμογή

Îåêßíçóå áðü ôï ìÝëïò manosB. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 31-05-2007, 17:21. Υπάρχουν 6 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  31-05-2007, 15:08 32395

    Προσθήκη ρόλων σε εφαρμογή

    Έχεις φτιάξει την εφαρμογή σου. Δουλεύει γρήγορα και  απροβλημάτιστα.
    Έρχεται εκείνη η αποφράδα μέρα που έρχεται η απαίτηση για ρόλους χρηστών που να φτάνει και σε επίπεδο πεδίου!

    Δηλαδή π.χ ένας απλός χρήστης του λογιστηρίου μπορεί να καταχωρεί τιμολόγια αλλά μόνο ο προιστάμενος να μπορεί μπορεί να δει καρτέλα πελάτη. (ρόλος σε επίπεδο φόρμας ή μενού)
    ή ένας χρήστης της αποθήκης να μπορεί να δει συνολικές ποσότητες αλλά για να τις αλλάξει πρέπει μονο εξουσιοδοτημένος χρήστης να μπορεί να τις αλλάξει (ρόλος σε επίπεδο πεδίου)

    Φτιάχνεις ένα απλό πίνακα διακριτών ρόλων και νομίζεις ότι καθάρισες.
    Έλα όμως που στις διεργασίες μιας εταιρίας οι ρόλοι περιπλέκονται (ένας ρόλος είναι υποσύνολο του άλλου) και φυσικά κάθε χρήστης έχει παραπάνω από ένα ρόλο που μπορεί να είναι και άσχετοι μεταξύ τους.

    Για να μην ξαναγράψω από την αρχή την εφαρμογή μου πρέπει να βάλω σε ένα πίνακα όλα τα πεδία και να τα δέσω με συγκεκριμένους ρόλους? Έτσι στο Load κάθε φόρμας θα τρέχει μια ρουτίνα που θα μου κρύβει, εμφανίζει, ενεργοποιεί, απενεργοποιεί πεδία.

    Ποια είναι η γνώμη σας? Πως θα το υλοποιούσατε εσείς κάτι τέτοιο?Hmm







    Manos
  •  31-05-2007, 15:48 32397 σε απάντηση της 32395

    Απ: Προσθήκη ρόλων σε εφαρμογή

    Δυστυχώς, εύκολη λύση δεν υπάρχει σε ένα τέτοιο θέμα. Αν δεν έχεις προβλέψει από την αρχή για ρόλους, δεν προστίθενται εύκολα εκ των υστέρων. Ο λόγος είναι ότι οι ρόλοι επηρεάζουν το UI που βλέπει ο κάθε χρήστης, τις ενέργειες που μπορεί να κάνει, τα δεδομένα που επιτρέπεται να τραβήξει από τη βάση. Και φυσικά, εννοείται ότι υπάρχει και ιεραρχία ρόλων.

    Θα σου περιγράψω καταρχήν μία πλήρη υλοποίηση που είχα φτιάξει στο παρελθόν και μετά τί μπορείς να χρησιμοποιήσεις σε μία ήδη έτοιμη εφαρμογή.

    Οι ρόλοι ήταν ιεραρχικοί με τους ανώτερους ρόλους να περιέχουν τους κατώτερους. Οι ρόλοι αποθηκεύονταν σε ένα πίνακα με ιεραρχική δομή ο οποίος όμως δεν χρησιμοποιούσε το συνηθισμένο πεδίο ParentID, αλλά την τεχνική "Nested Set" η οποία επιτρέπει την ανάκτηση όλων των παιδιών με ένα select αντί για τη χρήση cursors και εκμεταλλεύεται τα indexes. Οι ρόλοι του κάθε χρήστη κρατούνταν σε ένα πίνακα UserRoles από τον οποίο, με το κατάλληλο ιεραρχικό query μπορούσες να τραβήξεις όλους τους ρόλους που είχε ένας χρήστης, είτε άμεσα είτε λόγω ιεραρχίας.

    Τα permissions ορίζονταν σε διάφορα επίπεδα: Ποιές ενέργειες μπορεί να εκτελέσει ο χρήστης, ποιές εγγραφές, ποιές στήλες. Το κάθε είδος permission (action, entity, field) αποθηκευόταν σε διαφορετικό πίνακα με κλειδιά το ρόλο και το user id. Όταν ήθελες να τραβήξεις π.χ. τη λίστα με τα επιτρεπτά actions, ή τις επιτρεπτές εγγραφές απλά περιλάμβανες στο query ένα inner join με τον αντίστοιχο πίνακα και τον πίνακα των ρόλων, γραμμένο έτσι ώστε να επιστρέφει όλους τους ρόλους του χρήστη, και τους υφιστάμενους ρόλους. Έτσι, έπαιρνες τις επιτρεπόμενες εγγραφές. Το πεδίο ρόλου ή χρήστη μπορούσε να έχει συγκεκριμένη τιμή, ή την τιμή All, που σήμαινε ότι ουσιαστικά το πεδίο δεν επηρέαζε το query.
    Με τον τρόπο αυτό εξασφαλίζαμε ότι δεν θα έφευγαν καν από τη βάση δεδομένα για τα οποία ο χρήστης δεν είχε permissions.

    Έχοντας πάρει τις εγγραφές και τα actions μπορούσες εύκολα να δείξεις τα δεδομένα π.χ. σε ένα grid και να ενεργοποιήσεις μόνο τα menu items ή κουμπιά που επιτρέπονταν. Επειδή χρησιμοποιούσαμε δυναμικό UI, το ίδιο εύκολα μπορούσες να εμφανίσεις μόνο τα πεδία που επιτρέπονταν.

    Στην δική σου περίπτωση, τα πράγματα είναι λίγο πιο δύσκολα, καθώς η εφαρμογή δεν έχει ήδη φτιαχτεί με τη λογική των ρόλων. Αυτό που μπορείς να κάνεις είναι να φτιάξεις ένα ιεραρχικό πίνακα με τους ρόλους, τον πίνακα UserRoles και τον πίνακα με τα field permissions, και με ένα join μεταξύ τους θα μπορείς να πάρεις τη λίστα με τα επιτρεπόμενα πεδία. Σημασία έχει πάντως πως θα ορίσεις τα πεδία: Σε επίπεδο object, σε επίπεδο φορμας, σε επίπεδο πίνακα? Αυτό εξαρτάται από το μοντέλο με το οποίο δουλεύει η εφαρμογή σου. Εμείς το είχαμε σε επίπεδο αντικειμένου και φόρμας.
    Το δύσκολο είναι το πως θα κάνεις update το UI. Αν αρχίσεις να κρύβεις controls θα δημιουργηθούν κενά στο UI. Χρησιμοποιώντας κάποια layout panels βέβαια μπορείς να το αντιμετωπίσεις κάπως.

    Πέρα από το nested set υπάρχουν και άλλοι τρόποι να αποθηκεύσεις ιεραρχίες στη βάση. Τα Nested Sets είναι πολύ γρήγορα στο query αλλά φασαριόζικα στο update. Στην περίπτωση των ρόλων βέβαια, αυτό μας ταιριάζει γάντι, αλλά αν θες να δεις και άλλες μεθόδους, κοίτα το άρθρο "Trees in SQL" όπου περιγράφει μία άλλη τεχνική, τα materialized paths καθώς και τα Common Table Expressions του SQL Server 2005. Τα CTE δεν είναι τόσο γρήγορα όσο οι άλλες μέθοδοι, αλλά είναι ένας εύκολος τρόπος να χρησιμοποιήσεις το παλιό καλο ParentID χωρίς cursors.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  31-05-2007, 16:00 32398 σε απάντηση της 32397

    Απ: Προσθήκη ρόλων σε εφαρμογή

    Καταρχήν σε ευχαριστώ για το κόπο σου και για την πληρότητα της απάντησης σου.YesYesYes
        Θα μελετήσω αυτά που αναφέρεις στο post σου και θα επανέλθω .

    Manos
  •  31-05-2007, 16:06 32399 σε απάντηση της 32395

    Απ: Προσθήκη ρόλων σε εφαρμογή

    Role-based security σε windows form application...

    Και απ' ότι βλέπω, σκέφτεσαι κατευθείαν την υλοποίηση ενώ θα πρέπει να σκεφθείς τον σχεδιασμό Smile

    Κατ' αρχήν, πριν αποφασίσεις να κάνεις οτιδήποτε θα πρέπει τουλάχιστον να διαβάσεις τα βασικά περί security στο .NET Framework. Ένα καλό σημείο εκκίνησης είναι το http://msdn2.microsoft.com/en-us/security/aa570406.aspx και ειδικότερα το άρθρο http://msdn2.microsoft.com/en-us/library/aa302369.aspx για να κατανοήσεις τις βασικές έννοιες. Από εκεί και πέρα, υπάρχουν πολλά πράγματα που παίζουν ρόλο και θα πρέπει να σκεφτείς. Για παράδειγμα, πως θα γίνεται το authentication; Με πίνακες στη βάση; Με integration στο Active Directory; Μήπως θα πρέπει να υποστηρίζονται και τα δύο; O έλεγχος θα είναι imperative ή declarative; Κλπ, κλπ.

    Αφού τελειώσεις με τη σχεδίαση, έρχεται η ώρα της υλοποίησης. Εκεί χρειάζεται μεγάλη προσοχή στον κώδικα που θα γράψεις. Υπάρχουν πολλές μικρές λεπτομέρειες που πρέπει να προσέξεις αν δεν έχεις εμπειρία στο security.

    Πάντως, όταν χρειάστηκε να κάνω κάτι παρόμοιο, επέλεξα να μην πονοκεφαλιάσω με την όλη ιστορία και να αφήσω τη βρομοδουλειά στο Security Application Block. Υποθέτω αυτοί που το έγραψαν έχουν πολύ μεγαλύτερη εμπειρία από εμένα Wink. Γενικά, το όλο θέμα του security ακούγεται απλό αλλά μέχρι να αρχίσεις να ασχολείσαι μαζί του. Τότε αρχίζεις να βλέπεις την κάτω μεριά του παγόβουνου!


    Vir prudens non contra ventum mingit
  •  31-05-2007, 17:01 32402 σε απάντηση της 32399

    Απ: Προσθήκη ρόλων σε εφαρμογή

    KelMan αυτό που σκέφτομαι να κάνω είναι να παρακάμψω τελείως τα security features του Framework και ότι υλοποιήσω να προέρχεται από custom διαδικασίες.
    Άλλωστε το authentication έχει υλοποιηθεί ήδη στην εφαρμογή μου με πίνακες στη βάση.
    Για αυτό μελετώ και τη λύση που πρότεινε ο Παναγιώτης.

    Πάντως για το παγόβουνο είσαι απόλυτα σωστός και τώρα αρχίσω να το καταλαβαίνω.Cool

    Υπόσχομαι στο επόμενο τέτοιο Project να υπάρχει μέριμνα από την αρχή για Role-based security...Lightning
     




    Manos
  •  31-05-2007, 17:04 32403 σε απάντηση της 32399

    Απ: Προσθήκη ρόλων σε εφαρμογή

    Ο Μανώλης έχει δίκιο ότι πρώτα πρέπει να σκεφτείς το σχεδιασμό. Η αρχιτεκτονική που περιέγραφα είχε γίνει πριν 7 χρόνια, με στόχο να μπορεί να αλλάξουν οι ρόλοι ακόμα και κατά τη λειτουργία της εφαρμογής. Αν δεν υπάρχει αυτή η απαίτηση και ξέρεις εκ των προτέρων τους ρόλους που απαιτούνται, μπορείς να χρησιμοποιήσεις το Role Security του .NET και declarative security.

    Μερικές από τις βασικές ερωτήσεις που πρέπει να απαντήσει η σχεδίαση είναι:
    • Ποιά στοιχεία χρειάζομαι για τον έλεγχο? Χρήστης και ρόλοι είναι τα συνηθισμένα, μήπως όμως χρειάζομαι και το τμήμα του υπαλλήλου? Τη διαβάθμιση του?
    • Τί θέλω να ελέγξω? Το UI, τα δεδομένα που έρχονται από τη βάση, τις επιτρεπτές ενέργειες, κάτι άλλο?
    • Τί granularity θέλω να έχει ο έλεγχος? Σε επίπεδο φόρμας, αντικειμένου, πεδίου?
    • Πού θα το ελέγξω? Στη βάση, στο server, στο UI?
    • Έχω ιεραρχία ρόλων και πως?
    • Έχω μόνο allow permission ή έχω και deny?
    • Πως θα ελέγξω ότι ο χρήστης έχει την κατάλληλη άδεια (authorization)?
    • Πως θα διαχειριστώ τους χρήστες και τους ρόλους?
    • Πως κάνω expire τους χρήστες? Ένα θέμα που αφορά N-tier ή disconnected εφαρμογές.
    Και μερικά πιο τεχνικά ζητήματα
    • Πως θα αποφύγω το κόστος του συνεχούς authentication? Καλά αν έχω client server εφαρμογή, αν όμως έχω N-Tier ή disconnected εφαρμογή, πως θα αποφύγω το κόστος του authentication σε κάθε κλήση?
    • Τί επίδραση θα έχει στην απόδοση το μοντέλο που χρειάζομαι?
    • Πόσο εύκολο είναι να αλλάξω τη δομή των ρόλων?

    Το Security Application Block καλύπτει το authorization, το expiration και την αποφυγή του συχνού authentication. H μορφή της ιεραρχίας που υποστηρίζει εξαρτάται από τον provider που χρησιμοποιεί. Από τη "μαμά" του περιέχει ένα Rules provider και τον AuthorizationManager provider. Ο Authorization Manager είναι μία υπηρεσία η οποία υπάρχει στα Windows 2004 και μπορεί να εγκατασταθεί στα XP και 2000 και αποθηκεύει τους ρόλους σε XML ή Active Directory. Πολύ ωραίο για distributed εφαρμογές. Δεν έχει όμως database provider, αν και δεν είναι δύσκολο να φτιάξει κανείς ένα provider που θα χρησιμοποιήσει το μηχανισμό που έχει οριστεί στη βάση ή με άλλο τρόπο.

    Το Security Block μπορεί να χρησιμοποιηθεί για έλεγχο permissions στον application server και το UI, όχι όμως στη βάση. Αυτό όμως μπορεί να είναι υπεραρκετό αν δεν θέλεις ασφάλεια επιπέδου C2 (εμείς θέλαμε). Μπορεί όμως να χρησιμοποιηθεί μαζί με ένα custom database provider ο οποίος θα διαβάζει ρόλους και permissions από τη βάση.

    Στο UI ειδικά θα μπορούσες να το συνδυάσεις π.χ. με ένα ExtenderProvider control το οποίο θα το βάλεις στις επίμαχες οθόνες και θα σου επιτρέψει να ορίσεις για κάθε control, σε ποιούς ρόλους επιτρέπεται. Μετά, αφήνεις το ExtenderProvider control να εμφανίσει ή να κρύψει τα controls.


    Υ.Γ. Μάνο, το link που έδωσες είναι για το παλιό Enterprise Library. Το καινούριο βρίσκεται στο http://www.codeplex.com/entlib.
    Υ.Υ.Γ. Είναι πολύ περίεργο που δεν έχει και ένα DbProvider. Ή δεν έψαξα καλά, ή κάποιος σίγουρα θα έχει φτιάξει ένα

    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  31-05-2007, 17:21 32404 σε απάντηση της 32402

    Απ: Προσθήκη ρόλων σε εφαρμογή

    Δεν υπάρχει λόγος να παρακάμψεις το Framework, ακόμα και αν το authentication το κάνεις στη βάση. Μόλις κάνεις το authentication φτιάχνεις ένα GenericPrincipal αντικείμενο για το χρήστη στο οποίο προσθέτεις τους ρόλους του (άμεσους και έμμεσους) και το βάζεις στο CurrentThread.CurrentPrincipal property. Έτσι μπορείς να ελέγξεις σε οποιοδήποτε σημείο αν ο χρήστης ανήκει σε ένα ρόλο καλώντας την μέθοδο IsInRole, ενώ εκτελούνται από το Framework οι declarative ή imperative έλεγχοι που έχεις ορίσει.

    Αυτό μπορείς να το χρησιμοποιήσεις ακόμα και στο UI customization, καθώς μπορείς να ελέγχεις απευθείας τους ρόλους του Principal αντί να τους ξαναφορτώνεις κάθε φορά. Θα πρέπει να έχεις φορτώσει τους απαιτούμενους ρόλους των φορμών σε κάποιο cache βέβαια, γιατί δεν λέει να φορτώσεις με το καλημέρα τα permissions για όλες τις φόρμες, ειδικά αν είναι πολλές.

    Από εκεί και πέρα, ίσως κάποια στιγμή να πρέπει να επιβάλλεις ένα ισχυρό έλεγχο ότι μόνο χρήστες σε ένα ρόλο μπορούν να εκτελέσουν κάποιες ενέργειες, ή να καλέσουν κάποιο admin dll. Σε αυτή την περίπτωση θα χρειαστείς το Security του Framework, κάτι που θα είναι πολύ ευκολότερο αν έχεις ήδη το GenericPrincipal. Δεν χάνεις τίποτε αν το χρησιμοποιήσεις τώρα, μπορεί όμως να αποδειχθεί πολύ χρήσιμο αργότερα.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems