, quindi non sono sicuro se devo essere l'implementazione di un IAuthorizationFilter o l'implementazione di un IActionFilter o anche qualcos'altro.
Si dovrebbe essere l'implementazione di un IAuthorizationFilter
:
public class MyAuthorizeAttribute: FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var key = filterContext.HttpContext.Request.QueryString["param_name"];
if (!IsValid(key))
{
// Unauthorized!
filterContext.Result = new HttpUnauthorizedResult();
}
}
private bool IsValid(string key)
{
// You know what to do here => go hit your RavenDb
// and perform the necessary checks
throw new NotImplementedException();
}
}
E se si voleva utilizzare l'iniezione di dipendenza nella vostra filtro azione personalizzata si potrebbe dare un'occhiata al following article
in cui è possibile implementare un provider di filtro personalizzato (IFilterProvider
). Potresti avere un attributo contrassegnato che puoi utilizzare sulle azioni del controller e poi chiedere a questo fornitore di filtri personalizzati di controllare se l'azione è decorata con questo attributo marker e applicare il filtro di autorizzazione personalizzato.
Ad esempio:
public class MyAuthorizeAttribute: Attribute
{
}
e il filtro di autorizzazione implementerà solo il IAuthorizationFilter
, non sarà un FilterAttribute
:
public class MyAuthorizationFilter: IAuthorizationFilter
{
private readonly ISomeRepository repository;
public class MyAuthorizationFilter(ISomeRepository repository)
{
this.repository = repository;
}
public void OnAuthorization(AuthorizationContext filterContext)
{
var key = filterContext.HttpContext.Request.QueryString["param_name"];
if (!IsValid(key))
{
// Unauthorized!
filterContext.Result = new HttpUnauthorizedResult();
}
}
private bool IsValid(string key)
{
// You know what to do here => go hit your RavenDb
// and perform the necessary checks
throw new NotImplementedException();
}
}
e poi si avrà il provider filtro personalizzato:
public class MyFilterProvider : IFilterProvider
{
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
if (actionDescriptor.GetCustomAttributes(typeof(MyAuthorizeAttribute), true).Any())
{
var filter = DependencyResolver.Current.GetService<MyAuthorizationFilter>();
yield return new Filter(filter, FilterScope.Global);
}
yield break;
}
}
che sarà registrato in voi r Application_Start
:
FilterProviders.Providers.Add(new MyFilterProvider());
fonte
2013-05-23 08:25:35
Grazie al tesoro, Darin! Ho notato che hai usato Property Injection (penso che sia quello che viene chiamato) invece di Constructor Injection - c'è qualche ragione per cui non potrei farlo solo nella classe 'MyAuthorizationFilter' .. e lasciare che' MyAuthorizationFilter' erediti anche il ' FilterAttribute'? Quindi avrei solo 1 lezione, non 2 da fare. –
No, sta usando l'iniezione del costruttore. Questo è ciò che 'DependencyResolver' sta facendo in' MyFilterProvider'.Suppongo che tu non possa usare una singola classe poiché il framework non costruisce attributi usando DependencyResolver e come tale, non puoi decorare le tue azioni con esso perché ha bisogno di un 'Repository' passato al costruttore e tu non ne avrà uno disponibile. C'è un modo migliore per fare l'iniezione del costruttore sugli attributi dato che questa implementazione renderà piuttosto difficile fare cose come '[MyAuthorize (ErrorMessage =" Sad panda ")]'. – ajbeaven
@ajbeaven È possibile impostare l'attributo con i parametri come si desidera, quindi impostarli come proprietà interne e ottenere l'attributo all'interno di authorizationFilter per ottenere l'accesso alle proprietà/campi. Usa 'filterContext.ActionDescriptor.GetCustomAttributes (typeof (YourClass), true) .Cast();' per ottenere l'attributo. L'ambito interno è utile se hai un progetto dedicato per loro; altrimenti, crea semplicemente getter. –