Sto costruendo un semplice CMS in cui i ruoli sono impostati dinamicamente nel pannello di amministrazione. Il modo esistente di autorizzare un metodo di controllo, ad esempio [Authorize(Roles="admin")]
, non è più sufficiente. La relazione ruolo-azione deve essere memorizzata nel database, in modo che gli utenti finali possano facilmente dare/prendere le autorizzazioni a/da altri nel pannello di amministrazione. Come posso implementarlo?ASP.NET MVC - Autorizzazione dinamica
risposta
Questo è esattamente ciò che fanno le cose ASP.NET/profilo per te. E funziona con l'attributo Authorize.
Se si desidera eseguire il rollover, è possibile creare un filtro di azioni personalizzato che riproduca il comportamento del filtro di azione Autorizza standard. Pseudo codice qui sotto.
public MyAuthorizeAttribute : ActionFilterAttribute
{
public string MyRole { get; set; }
public void OnActionExecuting(ControllerContext context)
{
if (!(bool)Session["userIsAuthenticated"])
{
throw new AuthenticationException("Must log in.");
}
if (!Session["userRoles"].Contains(MyRole))
{
throw new AuthenticationException("Must have role " + MyRole);
}
}
}
Il ruolo - rapporto azione deve essere memorizzato nel database
Si dovrà verificare la sicurezza all'interno del metodo di controllo, a meno che non si desidera sottoclasse AuthorizeAttribute
modo che si guarda in alto i ruoli dal database per te.
Se si desidera assumere il controllo del processo di autorizzazione, è necessario creare sottoclasse AuthorizeAttribute e sovrascrivere il metodo AuthorizeCore. Quindi semplicemente decorare i controller con il tuo CmsAuthorizeAttribute
invece del valore predefinito.
public class CmsAuthorizeAttribute : AuthorizeAttribute
{
public override virtual bool AuthorizeCore(HttpContextBase httpContext)
{
IPrincipal user = httpContext.User;
IIdentity identity = user.Identity;
if (!identity.IsAuthenticated) {
return false;
}
bool isAuthorized = true;
// TODO: perform custom authorization against the CMS
return isAuthorized;
}
}
L'aspetto negativo di questo è che non si avrà accesso a ctor-iniettato CIO, quindi dovrete richiedere eventuali dipendenze dal contenitore direttamente.
qual è lo svantaggio di ottenere direttamente le dipendenze dal container? Ho dovuto fare questo per la mia implementazione di RoleProvider ... – Haroon
@Haroon - Il lato negativo è quello del design. In genere, è consigliabile che il codice rimanga all'oscuro del contenitore IoC al fine di ridurre le dipendenze su di esso (ad esempio, è possibile che si desideri riutilizzare il codice su WP7 in cui un contenitore basato su reflection viene generalmente evitato per motivi di prestazioni). –
@Haroon - Dopo aver detto ciò, MVC 3 supporta l'attribuzione del filtro per l'iniezione tramite proprietà attribuite. Richiede ancora la conoscenza del contenitore, ma è più facilmente deriso. –
Sono abbastanza nuovo per quella roba, ma ho visto un esempio in cui il ruolo è stato specificamente assegnato nel codice, e NON lo voglio. ad esempio, alcuni client potrebbero avere un gruppo di utenti chiamato "Ingegnere" con privilegi specifici. Voglio che sia in grado di configurarli dal pannello di amministrazione, senza toccare alcun pezzo di codice. In questo momento, non riesco a vedere come puoi usare l'attributo Authorize standard per quello – xantrus
Grazie, lo verificherò – xantrus
Bene, allora dovresti aggiungere le ricerche nel tuo database a un certo punto, magari abbinare l'utente e il controller/nomi di azioni con una regola di accesso che hai nel DB. O qualcosa di simile. – rmac