2010-08-31 17 views
7

Sommario: Devo autorizzare le pagine in base ai dati presenti nella stringa di query di un url, non solo il nome della pagina.Autorizzazione basata su dati in ASP.NET


Background:

Diciamo che sto costruendo un sistema di inventario della libreria. Gli utenti possono essere creati e assegnati a una singola libreria in un ruolo di amministratore o utente. Esistono centinaia di librerie concorrenti nello stesso database, quindi è importante garantire che gli utenti di una libreria non possano visualizzare l'inventario da un'altra libreria.

In questo momento sto utilizzando una configurazione ASP.NET piuttosto standard: Autenticazione moduli tramite SqlMembershipProvider. Autorizzazione che utilizza SqlRoleProvider, configurato tramite le sezioni <authorization> nel web.config. Taglio di sicurezza con il provider di SiteMap per nascondere pagine non autorizzate.

Per controllare le informazioni di inventario da perdite, sto verificando manualmente l'ID di libreria associato di un utente con ogni query di inventario. Funziona, ma è noioso e soggetto a errori. Ci deve essere un modo migliore.

Domanda:

Ora gli utenti hanno la possibilità di creare "collezioni" arbitrari all'interno di una libreria. (Ad esempio, la raccolta A contiene Libri 1, 2, & 3). Gli amministratori desiderano poter concedere l'accesso Amministratore/Utente alle singole raccolte, non solo all'intera libreria.

Quindi, se un utente passa a www.com/Book.aspx?BookId=1, il sistema deve assicurarsi che l'utente disponga delle autorizzazioni per la raccolta di "Libro 1" prima di mostrare la pagina. Se visitano www.com/Reviews.aspx?ReviewId=23, devo assicurarmi che la recensione riguardi un libro che si trova in una raccolta che hanno il permesso di visualizzare.

1) Come posso implementarlo nel modo più standard possibile con ASP.NET?
Controllo manuale all'interno di una pagina di base?
Un HttpModule personalizzato?
Un fornitore di ruolo personalizzato?
Non sono interessato a come memorizzare le autorizzazioni di amministratore/utente, ma piuttosto come/dove autorizzare in base a tali autorizzazioni. (esempi su come implementare una di queste sono apprezzati)

2) a complicare ulteriormente, mi piace ancora per motivi di sicurezza per verificare se l'utente dispone di diritti di amministratore su qualsiasi raccolta o libreria e nascondere l'amministratore pagine se non lo fa.

+0

+1 per formattare la tua domanda così incredibilmente bene! – user279521

+0

@ user279521: Grazie :) – Greg

risposta

2

Non lo gestivo in alcun modo vicino al livello dell'interfaccia utente (ASP.NET) ma piuttosto all'interno dei servizi dell'applicazione. Qualcosa di simile:

  1. servizi Corporatura che prendono un IPrincipal (o il vostro oggetto utente personalizzato) come parametro del costruttore.
  2. Quando si richiede un libro/revisione/qualsiasi altra cosa, il servizio è responsabile per cercare di verificare se l'utente ha accesso alla risorsa .
  3. Se l'utente non ha accesso, fare una cosa predeterminata (passare un messaggio , lanciare un'eccezione, restituire null).

Questo sarà molto più verificabile e utilizzabile a lungo termine, quindi ci si preoccuperà dal lato dell'interfaccia utente di ASP.NET.

Se si dispone di gestire la cosa dal lato ASP.NET, mi piacerebbe considerare l'utilizzo di un costume IPrincipal e personalizzati RoleProvider per avvolgere ogni libreria come un ruolo per l'accesso, allora si potrebbe utilizzare la maggior parte del LoginView, etc. controlli.

+0

+1 Questi sono ottimi punti. Se lancia un'eccezione e dimentico di gestirlo nell'interfaccia utente, nella peggiore delle ipotesi si bloccherà invece di perdere dati sensibili (che è una buona cosa). – Greg

1

Normalmente questo tipo di cose viene gestito a livello di dati. Ha poco a che fare con ASP.NET, a parte l'ultimo è necessario un id utente (che proviene dall'abbonamento). Quello che fai è trovare una parte della tua entità su cui vuoi controllare l'accesso, poi crei tutte le tue query per filtrarla.

Ad esempio, se si effettua l'accesso a livello Libreria, è necessario aggiungere un'associazione tra l'utente e la libreria. Questo può essere un 1: 1, 1: molti, molti: molti, qualunque sia il modello di dati richiesto. La chiave è che l'adesione a questo livello non restituirà mai alcun record, quindi l'intera query non restituirà alcun record.

Esempio, supponendo che un utente possa appartenere a una sola libreria.

La tabella utente ha LibraryID, la tabella di libri ha LibraryID, Ciò rende un effettivo join molti a molti tra utenti e libri. Quindi ti unisci Utente e Libreria su LibraryID e accedi a Libreria e Libri su LibraryID, quindi solo i libri che appartengono a una libreria a cui l'utente è associato verranno restituiti dalla query.

In questo modo, diventa impossibile per un utente interrogare qualsiasi cosa a cui non sono direttamente associati. La sicurezza è interamente nel database e non è richiesta alcuna logica di business.

Problemi correlati