2009-08-03 14 views
28

Devo sapere come implementare la sicurezza generale per un'applicazione C#. Quali opzioni ho a riguardo? Preferirei usare una struttura esistente se soddisfa le mie esigenze - Non voglio re-inventare la ruota.Autenticazione, autorizzazione, gestione utenti e ruoli e sicurezza generale in .NET

I miei requisiti sono i seguenti:

  • il solito nome utente/password di autenticazione
  • manageing di utenti - assegnare autorizzazioni agli utenti
  • gestione dei ruoli - assegnare gli utenti ai ruoli, assegnare le autorizzazioni ai ruoli
  • autorizzazione degli utenti in base al nome utente e al ruolo

Sto cercando f o una struttura/libreria libera/open source che è stata testata e utilizzata dalla comunità .Net.

La mia applicazione richiede un approccio client/server, con il server in esecuzione come servizio Windows, che si connette a un database SQL Server. La comunicazione tra client e server avverrà tramite WCF.

Un'altra cosa importante è che devo essere in grado di assegnare autorizzazioni specifiche per utenti o ruoli a Visualizza/Aggiorna/Elimina un'entità specifica, che si tratti di un cliente o di un prodotto, ecc. Ad es. Jack può visualizzare un determinato 3 di 10 clienti, ma aggiornare solo i dettagli dei clienti Microsoft, Yahoo e Google e può solo eliminare Yahoo.

+2

Vogliono solo assicurarsi di sapere: C# è il linguaggio. Non ha sicurezza. .NET è la piattaforma. È dove è la sicurezza. –

+0

Thnx John - Capisco la differenza. –

+0

O è possibile estendere l'appartenenza a Asp.net o è possibile utilizzare framework pronto per la connessione - VisualGuard - http://www.visual-guard.com/EN/-source_soforum.html –

risposta

29

Per la sicurezza a grana grossa, è possibile trovare utile il codice principale integrato; l'oggetto utente (e i relativi ruoli) sono controllati in .NET dal "principal", ma a sua volta il runtime stesso può applicarlo.

L'implementazione di un principal può essere definita dall'implementazione e di solito è possibile iniettare il proprio; for example in WCF.

Per visualizzare il runtime applicare accesso grossolana (cioè che funzionalità può essere letta, ma non limitati a cui specifico dati):

static class Roles { 
    public const string Administrator = "ADMIN"; 
} 
static class Program { 
    static void Main() { 
     Thread.CurrentPrincipal = new GenericPrincipal(
      new GenericIdentity("Fred"), new string[] { Roles.Administrator }); 
     DeleteDatabase(); // fine 
     Thread.CurrentPrincipal = new GenericPrincipal(
      new GenericIdentity("Barney"), new string[] { }); 
     DeleteDatabase(); // boom 
    } 

    [PrincipalPermission(SecurityAction.Demand, Role = Roles.Administrator)] 
    public static void DeleteDatabase() 
    { 
     Console.WriteLine(
      Thread.CurrentPrincipal.Identity.Name + " has deleted the database..."); 
    } 
} 

Tuttavia, questo non aiuta con la Fine- accesso granuloso (ad es. "Fred può accedere al cliente A ma non al cliente B").


Additional; Naturalmente, per grana fine, si può semplicemente verificare i ruoli richiesti in fase di esecuzione, controllando IsInRole sul principio:

static void EnforceRole(string role) 
{ 
    if (string.IsNullOrEmpty(role)) { return; } // assume anon OK 
    IPrincipal principal = Thread.CurrentPrincipal; 
    if (principal == null || !principal.IsInRole(role)) 
    { 
     throw new SecurityException("Access denied to role: " + role); 
    } 
} 
public static User GetUser(string id) 
{ 
    User user = Repository.GetUser(id); 
    EnforceRole(user.AccessRole); 
    return user; 
} 

potete anche scrivere i propri oggetti principal/identità che fanno pigro test/caching del ruoli, piuttosto che dover conoscere tutti up-front:

class CustomPrincipal : IPrincipal, IIdentity 
{ 
    private string cn; 
    public CustomPrincipal(string cn) 
    { 
     if (string.IsNullOrEmpty(cn)) throw new ArgumentNullException("cn"); 
     this.cn = cn; 
    } 
    // perhaps not ideal, but serves as an example 
    readonly Dictionary<string, bool> roleCache = 
     new Dictionary<string, bool>(); 
    public override string ToString() { return cn; } 
    bool IIdentity.IsAuthenticated { get { return true; } } 
    string IIdentity.AuthenticationType { get { return "iris scan"; } } 
    string IIdentity.Name { get { return cn; } } 
    IIdentity IPrincipal.Identity { get { return this; } } 

    bool IPrincipal.IsInRole(string role) 
    { 
     if (string.IsNullOrEmpty(role)) return true; // assume anon OK 
     lock (roleCache) 
     { 
      bool value; 
      if (!roleCache.TryGetValue(role, out value)) { 
       value = RoleHasAccess(cn, role); 
       roleCache.Add(role, value); 
      } 
      return value; 
     } 
    } 
    private static bool RoleHasAccess(string cn, string role) 
    { 
     //TODO: talk to your own security store 
    } 
} 
3

Cerca su ASP.NET's Membership Providers. Non credo che SQLMembershipProvider funzioni nel tuo caso, ma è abbastanza semplice eseguire il rollover del tuo provider.

+0

Ho eseguito il rollover per un'app interna che ha già un database con gli utenti impostati. Lo consiglio vivamente. –

2

vorrei dare un'occhiata a qualcosa di simile a CSLA.net: Expert C# 2008 Business Objects

Essa dovrebbe fornire tutto il necessario.

+0

Questa opzione sembra promettente. Sto ricercando ulteriormente. Hai altre informazioni/esempi/tutorial? –

+0

Sul sito di Rocky Lhotka le ultime versioni di CSLA hanno tutte Campioni e progetti di test ... http://www.lhotka.net/cslanet/Download.aspx –

3

la mia risposta è probabilmente dipende dalla risposta a questa domanda: si tratta di un'applicazione enterprise che vive all'interno di una rete con Active Directory?

se la risposta è sì, allora questi sono i passi che avrebbe fornito:

1) Creazione di gruppi globali per la propria applicazione, nel mio caso, ho avuto un gruppo appuser e un gruppo appadmin.

2) È possibile accedere al server SQL in modalità AUTENTICAZIONE MISTA, quindi assegnare i gruppi di APPUSER come LOGIN di SQL SERVER al proprio database con i diritti CRUD appropriati per il/i proprio/i DB, e assicurarsi di accedere a SQL SERVER con Connessione sicura = True nella stringa di connessione.

A questo punto, il tuo negozio AD sarà responsabile dell'autenticazione. Dal momento che stai accedendo all'applicazione tramite una CONNESSIONE ATTENDIBILE, passerà l'identità di qualsiasi account esegua l'applicazione su SQL Server.

Ora, per l'AUTORIZZAZIONE (ovvero comunicare all'applicazione ciò che l'utente connesso è autorizzato a fare) è sufficiente interrogare AD per un elenco di gruppi di cui l'utente connesso è membro. Quindi controlla i nomi dei gruppi appropriati e crea l'interfaccia utente in base all'appartenenza in questo modo.

Il modo mie domande di lavoro sono quindi:

  1. Avvio dell'applicazione, le credenziali si basano sul utente connesso, questo è l'aspetto primario di autenticazione (cioè possono accedere perciò esistono)
  2. I Get tutti i gruppi per la Windows Identity in questione
  3. verifico per il gruppo standard uTENTE - se questo gruppo non esiste per il Windows Identity in questione, allora questo è l'autenticazione FAIL
  4. verifico per utente admin Gruppo - Con questo ex isting in gruppi dell'utente, modifico l'interfaccia utente per consentire l'accesso ai componenti di amministrazione
  5. Mostra l'interfaccia utente

poi ho sia un oggetto PRINCIPIO con i diritti stabiliti/etc su di esso, o utilizzare le variabili globali Posso accedere per determinare l'interfaccia utente appropriata mentre costruisco i miei moduli (es se il mio utente non è un membro del gruppo ADMIN, quindi nasconderei tutti i pulsanti DELETE).

Perché suggerisco questo?

È una questione di distribuzione.

È stata la mia esperienza che la maggior parte delle applicazioni aziendali vengono distribuite dagli ingegneri di rete anziché dai programmatori, quindi avere senso dell'autenticazione/autorizzazione è responsabilità di AD, poiché è lì che vanno i membri della rete quando si discute dell'autenticazione /Autorizzazione.

Inoltre, durante la creazione di nuovi utenti per la rete, un ingegnere di rete (o chiunque sia responsabile della creazione di nuovi utenti di rete) è più adatto a ricordare di eseguire i compiti di gruppo mentre sono IN AD rispetto al fatto che hanno entrare in una dozzina di applicazioni per analizzare gli incarichi di autorizzazione.

Fare questo aiuta il labirinto di permessi e diritti che i nuovi assunti devono essere concessi o quelli che lasciano la società devono essere negati e mantiene l'autenticazione e l'autorizzazione nel repository centrale a cui appartiene (cioè in AD @ the Domain Livello del controller).

+0

Hey Stephen. L'app che sto sviluppando sarà ospitata su una rete aziendale interna, ma non è impostata su un dominio Windows, quindi non su Active Directory. Tutti i dati, incluse le informazioni su utenti e permessi, saranno archiviati nel database. Solo il servizio Windows WCF può comunicare direttamente con il DB, mentre tutti i client parlano con il servizio WCF. –

0

Penso che si tratti di alcuni problemi separati qui - non è un caso che la maggior parte dei sistemi di sicurezza separi l'autenticazione e l'autorizzazione.

Per l'autenticazione, la domanda più grande è logistica. Oppure, c'è un luogo logico in cui questi utenti possono vivere, sia localmente all'applicazione, in Active Directory, in qualche altro archivio LDAP o persino in qualche altra applicazione. Esattamente dove è piuttosto immateriale - abbiamo solo bisogno di essere in grado di identificare gli utenti in modo solido e preferibilmente di rendere quel compito il problema di qualcun altro. Alla fine della giornata hai davvero bisogno di un identificatore univoco e il conforto che Bob di Accounting è in realtà Bob di Contabilità.

L'autorizzazione è la parte più interessante del problema qui. Penso che, se è veramente a grana fine, vuoi veramente gestirlo interamente all'interno della tua applicazione, indipendentemente da dove provengano gli utenti. Marc Gravell ha davvero trovato un buon modo per modellare almeno parte di questo: utilizzare alcune implementazioni personalizzate di IPrincipal e PrincipalPermission per gestire le cose è un modo molto semplice per iniziare. Oltre a questo, è possibile utilizzare tecniche come this one per prendere decisioni di autorizzazione più complesse in modo abbastanza pulito.

0

Vorrei usare il termine "RBAC" (sistema di controllo degli accessi basato sul ruolo) come soluzione per tutti i vostri requisiti.

Non vorrei entrare nei dettagli per spiegare "RBAC" qui, piuttosto vorrei spiegarlo in seguito.

In pratica contiene 3 funzioni.

1) Autenticazione: conferma l'identità dell'utente. Di solito è fatto tramite account utente e password o credenziali.

2) Autorizzazione: definisce ciò che l'utente può fare e non può fare in un'applicazione. Ex. 'Modifica ordine' è permesso ma 'creazione di nuovo ordine' non è permesso.

3) Controllo delle azioni dell'utente sulle applicazioni. - Tiene traccia delle azioni dell'utente sulle applicazioni, nonché di chi ha concesso quale accesso a quali utenti?

è possibile controllare RBAC su wiki qui.

https://en.wikipedia.org/wiki/Role-based_access_control

ora, per quanto riguarda la risposta alle vostre esigenze - una delle possibili soluzioni è quella di estendere l'appartenenza Asp.Net secondo le esigenze.

E per quanto riguarda, alcuni framework pronti all'uso, vorrei raccomandare VisualGuard per cui lavoro, dovresti controllare questo, fa tutto ciò che ti serve molto facilmente, e ciò che è più importante è, gestisce tutti i tuoi utenti , ruoli, permessi e applicazioni tramite Central Administration Console e per la definizione delle autorizzazioni, gli amministratori non richiedono conoscenze dello sviluppatore, ovvero possono creare restrizioni sulle attività tramite l'interfaccia utente.

puoi anche controllare questo articolo per avere più comprensione sul permesso e sul sistema basato sui ruoli.

http://www.visual-guard.com/EN/net-powerbuilder-application-security-authentication-permission-access-control-rbac-articles/dotnet-security-article-ressources/role-based-access-control-source_soforum.html

Problemi correlati