Domanda

Mi imbatto spesso nel seguente scenario in cui devo offrire molti tipi diversi di autorizzazioni.Utilizzo principalmente ASP.NET / VB.NET con SQL Server 2000.

Scenario

Voglio offrire un sistema di autorizzazione dinamico che possa funzionare su diversi parametri.Diciamo che voglio dare a un dipartimento o solo a una persona specifica l'accesso a un'applicazione.E facciamo finta di avere un numero di applicazioni in continua crescita.

In passato, ho scelto uno dei due modi seguenti che conosco per farlo.

  1. Utilizzare una singola tabella di autorizzazione con colonne speciali utilizzate per determinare un modo per applicare i parametri.Le colonne speciali in questo esempio sono TypeID e TypeAuxid.L'SQL assomigliarà a questo.

    SELECT COUNT(PermissionID)
    FROM application_permissions
    WHERE
    (TypeID = 1 AND TypeAuxID = @UserID) OR
    (TypeID = 2 AND TypeAuxID = @DepartmentID)
    AND ApplicationID = 1
    
  2. Usa una tabella di mappatura per ogni tipo di autorizzazione, quindi unendoli tutti insieme.

    SELECT COUNT(perm.PermissionID)
    FROM application_permissions perm
    LEFT JOIN application_UserPermissions emp
    ON perm.ApplicationID = emp.ApplicationID
    LEFT JOIN application_DepartmentPermissions dept
    ON perm.ApplicationID = dept.ApplicationID
    WHERE q.SectionID=@SectionID
      AND (emp.UserID=@UserID OR dept.DeptID=@DeptID OR
     (emp.UserID IS NULL AND dept.DeptID IS NULL)) AND ApplicationID = 1
    ORDER BY q.QID ASC
    

I miei pensieri

Spero che gli esempi abbiano senso.Li ho messi insieme.

Il primo esempio richiede meno lavoro, ma nessuno dei due sembra la risposta migliore.Esiste un modo migliore per gestire questa situazione?

È stato utile?

Soluzione

Sono d'accordo con John Downey.

Personalmente, a volte utilizzo un'enumerazione contrassegnata di autorizzazioni.In questo modo puoi utilizzare operazioni AND, OR, NOT e XOR bit a bit sugli elementi dell'enumerazione.

"[Flags]
public enum Permission
{
    VIEWUSERS = 1, // 2^0 // 0000 0001
    EDITUSERS = 2, // 2^1 // 0000 0010
    VIEWPRODUCTS = 4, // 2^2 // 0000 0100
    EDITPRODUCTS = 8, // 2^3 // 0000 1000
    VIEWCLIENTS = 16, // 2^4 // 0001 0000
    EDITCLIENTS = 32, // 2^5 // 0010 0000
    DELETECLIENTS = 64, // 2^6 // 0100 0000
}"

Quindi, puoi combinare diverse autorizzazioni utilizzando l'operatore AND bit a bit.

Ad esempio, se un utente può visualizzare e modificare gli utenti, il risultato binario dell'operazione è 0000 0011 che convertito in decimale è 3.
Puoi quindi memorizzare i permessi di un utente in una singola colonna del tuo DataBase (nel nostro caso sarebbe 3).

All'interno della tua applicazione, hai solo bisogno di un'altra operazione bit a bit (OR) per verificare se un utente ha un permesso particolare o meno.

Altri suggerimenti

Il modo in cui in genere procedo con la codifica dei sistemi di autorizzazione è avere 6 tabelle.

  • Utenti: è piuttosto semplice, è la tipica tabella degli utenti
  • Gruppi: questo sarebbe sinonimo dei tuoi dipartimenti
  • Ruoli: questa è una tabella con tutte le autorizzazioni che generalmente include anche un nome leggibile e una descrizione
  • Users_have_Groups: questa è una tabella molti-a-molti dei gruppi a cui appartiene un utente
  • Users_have_Roles: un'altra tabella molti-a-molti dei ruoli assegnati a un singolo utente
  • Groups_have_Roles: la tabella finale molti-a-molti dei ruoli di ciascun gruppo

All'inizio di una sessione utente eseguiresti una logica che estrae ogni ruolo assegnato, sia nella directory che attraverso un gruppo.Quindi codifichi tali ruoli come autorizzazioni di sicurezza.

Come ho detto, questo è quello che faccio di solito, ma la tua quantità può variare.

Oltre alle soluzioni di John Downey e jdecuyper, ho anche aggiunto un bit "Explicit Deny" alla fine/inizio del bitfield, in modo da poter eseguire autorizzazioni aggiuntive per gruppo, appartenenza al ruolo e quindi sottrarre autorizzazioni in base alla negazione esplicita voci, proprio come funziona NTFS, dal punto di vista dei permessi.

Onestamente le funzionalità di appartenenza/ruoli ASP.NET funzionerebbero perfettamente per lo scenario che hai descritto.Scrivere le tue tabelle/proc/classi è un ottimo esercizio e puoi ottenere un ottimo controllo sui minimi dettagli, ma dopo averlo fatto io stesso ho concluso che è meglio usare semplicemente il materiale .NET integrato.Gran parte del codice esistente è progettato per aggirare questo problema, il che è carino.Scrivere da zero mi ha richiesto circa 2 settimane e non era neanche lontanamente robusto come .NET.Devi codificare così tante schifezze (recupero della password, blocco automatico, crittografia, ruoli, un'interfaccia di autorizzazione, tonnellate di procedure, ecc.) E il tempo potrebbe essere speso meglio altrove.

Scusa se non ho risposto alla tua domanda, sono come il ragazzo che dice di imparare il C# quando qualcuno fa una domanda in VB.

Un approccio che ho utilizzato in varie applicazioni consiste nell'avere una classe PermissionToken generica con una proprietà Value modificabile.Quindi interroghi l'applicazione richiesta, ti dice quali PermissionToken sono necessari per usarla.

Ad esempio, l'applicazione Spedizione potrebbe dirti che ha bisogno di:

new PermissionToken()
{
    Target = PermissionTokenTarget.Application,
    Action = PermissionTokenAction.View,
    Value = "ShippingApp"
};

Questo può ovviamente essere esteso a Crea, Modifica, Elimina ecc. e, grazie alla proprietà Valore personalizzata, qualsiasi applicazione, modulo o widget può definire le proprie autorizzazioni richieste.YMMV, ma questo è sempre stato un metodo efficiente per me e ho scoperto che si adatta bene.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top