Domanda

Devo sapere come implementare la sicurezza generale per un'applicazione C #. Quali opzioni ho a questo proposito? Preferirei utilizzare un framework esistente se soddisfa le mie esigenze: non voglio reinventare la ruota.

Le mie esigenze sono le seguenti:

  • la solita autenticazione nome utente / password
  • gestione degli utenti: assegna le autorizzazioni agli utenti
  • gestione dei ruoli: assegnare gli utenti ai ruoli, assegnare le autorizzazioni ai ruoli
  • autorizzazione degli utenti in base al loro nome utente e ruolo

Sto cercando un framework / libreria gratuito / open-source che è stato a tempo e utilizzato dalla comunità .Net.

La mia applicazione adotta un approccio client / server, con il server in esecuzione come servizio Windows, connettendosi 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 a ruoli o utenti specifici per visualizzare / aggiornare / eliminare 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 aggiorna solo i dettagli dei clienti Microsoft, Yahoo e Google e può eliminare solo Yahoo.

È stato utile?

Soluzione

Per la sicurezza a grana grossa, potresti trovare utile il codice principale integrato; l'oggetto utente (e i loro ruoli) sono controllati in .NET da "principal", ma utilmente il runtime stesso può farcela.

L'implementazione di un'entità può essere definita e l'implementazione può essere di propria iniziativa; ad esempio in WCF .

Per visualizzare il runtime che impone l'accesso approssimativo (ovvero a quale funzionalità è possibile accedere, ma non limitato a quali dati specifici:

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, ciò non aiuta con l'accesso a grana fine (vale a dire "Fred può accedere al cliente A ma non al cliente B").


Ulteriori; Ovviamente, per i dettagli, puoi semplicemente controllare i ruoli richiesti in fase di esecuzione, selezionando IsInRole sull'entità:

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;
}

Puoi anche scrivere i tuoi oggetti principali / identità che eseguono test pigri / memorizzazione nella cache dei ruoli, anziché doverli conoscere tutti in anticipo:

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
    }
}

Altri suggerimenti

Cerca Provider di appartenenze ASP.NET . Non credo che SQLMembershipProvider funzioni correttamente nel tuo caso, ma è abbastanza facile implementare il tuo provider.

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

SE la risposta è sì, allora questi sono i passaggi che vorrei fornire:

1) Crea gruppi globali per la tua applicazione, nel mio caso, avevo un gruppo APPUSER e un gruppo APPADMIN.

2) Avere accesso a SQL Server in modalità AUTENTICAZIONE MISTA, quindi assegnare i gruppi APPUSER come LOGIN SERVER SQL al proprio database con i diritti CRUD appropriati per i propri DB e assicurarsi che di accedere a SQL SERVER con Trusted Connection = True nella stringa di connessione.

A questo punto, il tuo negozio AD sarà responsabile per l'autenticazione. Dal momento che stai accedendo all'applicazione tramite un TRUSTED CONNECTION, passerà l'identità di qualunque account stia eseguendo l'applicazione a SQL Server.

Ora, per AUTORIZZAZIONE (vale a dire dire alla tua applicazione cosa è autorizzato a fare l'utente che ha effettuato l'accesso) è una semplice questione di interrogare AD per un elenco di gruppi di cui l'utente che ha effettuato l'accesso è membro. Quindi controlla i nomi dei gruppi appropriati e costruisci la tua interfaccia utente in base all'appartenenza in questo modo.

Il modo in cui funzionano le mie applicazioni è quindi:

  1. Avvio dell'applicazione, le credenziali si basano sull'utente che ha effettuato l'accesso, questo è l'aspetto principale dell'autenticazione (vale a dire che possono accedere quindi esistono)
  2. Ricevo tutti i gruppi per l'identità di Windows in questione
  3. Controllo il gruppo USER standard: se questo gruppo non esiste per l'identità di Windows in questione, si tratta di un FAIL di autenticazione
  4. Controllo il gruppo utenti ADMIN - Con questo esistente nei gruppi dell'utente, modifico l'interfaccia utente per consentire l'accesso ai componenti di amministrazione
  5. Visualizza l'interfaccia utente

Ho quindi un oggetto PRINCIPIO con i diritti / etc determinati su di esso, oppure utilizzo le variabili GLOBAL a cui posso accedere per determinare l'interfaccia utente appropriata durante la creazione dei miei moduli (cioè se il mio utente non è un membro del gruppo ADMIN , quindi nasconderei tutti i pulsanti CANC.).

Perché lo consiglio?

È una questione di distribuzione.

È stata la mia esperienza che la maggior parte delle applicazioni aziendali sono distribuite dagli ingegneri di rete piuttosto che dai programmatori, pertanto avere autenticazione / autorizzazione come responsabilità di AD ha senso, poiché è qui che vanno i ragazzi della rete quando discutono di 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ù propenso a ricordare di eseguire incarichi di gruppo mentre sono in ANNUNCIO rispetto al fatto che devono andare in una dozzina di domande per analizzare le assegnazioni di autorizzazione.

Ciò aiuta nel labirinto di autorizzazioni e diritti che devono essere concessi a nuovi assunti o quelli che lasciano l'azienda devono essere negati e mantiene l'autenticazione e l'autorizzazione nel repository centrale a cui appartiene (cioè in AD @ il controller di dominio livello).

Penso che tu stia esaminando alcuni problemi separati qui - non è un caso che la maggior parte dei sistemi di sicurezza separino l'autenticazione e l'autorizzazione.

Per l'autenticazione, la domanda più grande è logistica. Oppure, esiste un luogo logico in cui questi utenti possono vivere, sia localmente nell'applicazione, in Active Directory, in qualche altro negozio LDAP o anche in qualche altra applicazione. Esattamente dove è piuttosto irrilevante - dobbiamo solo essere in grado di identificare in modo solido gli utenti e preferibilmente fare questo compito il problema di qualcun altro. Alla fine della giornata hai davvero solo bisogno di un identificatore univoco e della comodità che Bob di Accounting è in realtà Bob di Accounting.

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

Vorrei usare il termine "RBAC" (sistema di controllo degli accessi in base al ruolo) come soluzione per tutte le vostre esigenze.

Non vorrei andare nei dettagli per spiegare "RBAC" qui, piuttosto lo descriverei brevemente come:

In pratica contiene 3 funzionalità.

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

2) Autorizzazione: definisce cosa l'utente può fare e cosa non può fare in un'applicazione. Ex. "L'ordine di modifica" è consentito ma "la creazione di un nuovo ordine" non è consentita.

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

puoi controllare RBAC sul wiki qui.

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

Ora, per quanto riguarda la risposta ai tuoi requisiti, una delle possibili soluzioni è quella di estendere l'appartenenza ASP.NET secondo le tue esigenze.

E per quanto riguarda alcuni framework pronti all'uso, consiglierei VisualGuard per il quale lavoro, dovresti verificarlo, fa tutto ciò di cui hai bisogno molto facilmente, e la cosa più importante è, gestisce tutti i tuoi utenti, ruoli, autorizzazioni e applicazioni tramite Central Administration Console e per definire le autorizzazioni , gli amministratori non richiedono conoscenze dello sviluppatore, ovvero possono creare restrizioni sulle attività tramite l'interfaccia utente.

puoi anche consultare questo articolo per avere una maggiore comprensione delle autorizzazioni e del sistema basato sui ruoli.

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

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