2011-12-17 13 views
7

Cercando di gestire l'accesso a un sito web che ho creato alcune entità necessarie enter image description hereÈ sicuro utilizzare la riflessione e le enumerazioni per il controllo logico dell'accesso alle applicazioni MVC?

L'obiettivo è quello di utilizzare un attributo personalizzato per il permesso metodo di azione alcuni del controller della mia applicazione MVC.

[Permissions(PermissionType.SomePermissionName, CrudType.CanDelete)] 
public ActionResult SomeAction() 
{ 
} 

Per questa operazione ho due enumerazioni

[Flags] 
public enum CrudType 
{ 
    CanCreate = 0x1, 
    CanRead = 0x2, 
    CanUpdate = 0x4, 
    CanDelete = 0x8, 
} 

[Flags] 
public enum PermissionType 
{ 
    SomePermissionName = 0x1, 
    //... 
} 

ora voglio il metodo seguito per controllare i permessi

public static bool CanAccess(RolePermissions rp, CrudType crudType) 
{ 
    var pInfo = rp.GetType().GetProperties(); 
    var res = pInfo.FirstOrDefault(x => x.Name == crudType.ToString()); 
    if(res != null) 
    { 
     return Convert.ToBoolean(res.GetValue(rp, null)); 
    } 
    return false; 
} 

Funziona bene ma è sicuro da usare riflessione qui? È un buon stile?
Un'altra domanda riguarda tale pezzo di codice

var permission = PermissionService.GetByName(permissionType.ToString()); 

Qui sto cercando di ottenere il permesso di un oggetto da un database utilizzando alcuni denominato costante dal PermissionType enum.
In entrambi i casi il lavoro corretto dipende dalle relazioni tra enumerazione e alcuni campi o record di tabella. Dall'altro lato ho un buon meccanismo di controllo della logica (come mi sembra). È un buon modo?

+0

Non è disponibile in ASP.NET Membership APi? –

+1

Non mi piace davvero l'iscrizione.Inoltre mi piacerebbe usare le mie classi, le proprie tabelle, il proprio controllo, ecc. – Shymep

+0

Qualsiasi motivo non ti piace, oltre alle proprie classi, alle proprie tabelle, ai propri controlli? Mentre stavo pensando di passare a Membership APi :( –

risposta

3

ALTRO EDIT
Nel tuo caso avrebbe senso creare una proprietà di sola lettura ExistingPermissions per la classe RolePermissions, e fare la fusione delle quattro booleani in una CrudType all'interno di tale getter proprietà. Quindi puoi semplicemente fare rp.ExistingPermissions.HasFlag(permissionToCheck).

CURA

Grazie a @DevDelivery per sottolineare il problema - buona pesca. Sfortunatamente la soluzione fissa non è carina come speravo, quindi in questo caso potrebbe aver senso seguire l'approccio di @DevDelivery.

Dal momento che avete i vostri CrudType come "campi di bit", è possibile utilizzare un approccio più pulito (meno codice e una migliore leggibilità):

public static bool CanAccess(RolePermissions rp, CrudType permissionToCheck) 
{ 
    CrudType existingPermissions = 
           SetPermissionFlag(CrudType.CanCreate, rp.CanCreate) | 
           SetPermissionFlag(CrudType.CanRead, rp.CanRead) | 
           SetPermissionFlag(CrudType.CanUpdate, rp.CanUpdate) | 
           SetPermissionFlag(CrudType.CanDelete, rp.CanDelete); 

    return existingPermissions.HasFlag(permissionToCheck); 
} 

public static CrudType SetPermissionFlag(CrudType crudType, bool permission) 
{ 
    return (CrudType)((int)crudType * Convert.ToInt32(permission)); 
} 

Lo svantaggio rispetto alla soluzione è che si dovrà modificare questo metodo nel caso si aggiungano più operazioni (allo esistente CanRead, ecc.).

+1

È fantastico !!! – Shymep

+0

Il problema qui è che le proprietà di RolePermission sono booleane. Oppure un gruppo di booleani ti darà un altro booleano. – DevDelivery

+0

@DevDelivery - buona cattura, non funzionerebbe davvero. Sembra che la soluzione non sia poi così carina dopo la correzione. – Yakimych

1

L'uso della riflessione ha un impatto sulle prestazioni e l'associazione tardiva significa che la modifica del nome di una enum o della proprietà non verrà rilevata dal compilatore.

Inoltre, questo codice è molto difficile da comprendere, quindi difficile da mantenere.

Qui ci sono solo 4 opzioni da controllare. Una semplice istruzione switch è più semplice, veloce e pulita.

L'uso della riflessione avrebbe senso se si tentasse di consentire modifiche al database o che i componenti di terze parti introducessero nuove autorizzazioni.

Problemi correlati