我正在使用基于声明的自定义授权,以便根据用户访问权限创建具有功能的面板。用户声明存储在缓存ICashClient
中。
特定菜单只是指某些控制器方法。
问题是: 只需输入指向特定方法的直接链接,就可以利用因缺少访问权限而无法使用的方法。
我的想法是创建一个方面,以便可以标记这些特定方法,以防止它们被允许执行。
我想再次使用OnEntry
方法进行授权。
以下示例允许检查对servcer的请求是否为Ajax
类型。
public override void OnEntry(MethodExecutionArgs args)
{
var controller = args.Instance as MyController;
if (controller != null)
{
if (!controller.Request.IsAjaxRequest())
throw new Exception ($"{args.Method.Name} invalid AJAX request");
}
base.OnEntry(args);
}
我在这个OnEntry
方法的上下文中有什么可能来查询现金中的现有数据?
我怎样才能从这里获得现金?
修改
我的控制器使用(使用依赖注入)一个所谓的QueryProcessor
来检索所请求的数据,该数据具有以下方法:
public TResult ExecuteWithCache<TResult>(ICustomQuery<TResult> query)
{
try
{
//class for creating fingerprint of query
var customQueryHash = (ICustomQueryHash<TResult>)query;
//fingerprint of the query
var queryString = customQueryHash.GetQueryHash();
//cash which might holds data
var cachedResult = _cacheClient.Get<TResult>(queryString);
...
}
catch(){}
}
_cashClient
是扩展ICashClient的实现。
答案 0 :(得分:0)
我知道您需要访问自定义方面类中的依赖项,并且通常使用依赖项注入来解决此依赖项。在这种特殊情况下,您希望访问QueryProcessor
。
方面的依赖关系不能通过依赖注入框架自动解决,因为框架不能控制方面构造和生命周期。然而,有许多方法可用于消耗方面内的依赖关系。它们在本文档部分中进行了描述:http://doc.postsharp.net/consuming-dependencies
以下是从方面消耗依赖关系的一些方法的简短描述。您可以根据项目和您正在使用的依赖框架选择最佳方法。
Global service locator. DI框架通常提供一种查询特定实例的当前对象图的方法(例如context.GetInstance<T>()
)。
public override void OnEntry(MethodExecutionArgs args)
{
var queryProcessor = ServiceLocator.GetInstance<IQueryProcessor>();
}
Global composition container。一些DI框架还允许您在构建初始图之后满足新对象的依赖。您可以覆盖方面中的RuntimeInitialize
方法,以在初始化方面实例时导入依赖项。
[PSerializable]
public class MyAspect : OnMethodBoundaryAspect
{
[Import]
public IQueryProcessor QueryProcessor { get; set; }
public override void RuntimeInitialize(MethodBase method)
{
ServiceInjector.BuildObject(this);
}
}
Import dependencies from the target object。当依赖项存储在目标对象的属性或字段中时,可以使用[ImportMember]
建议导入它们。在这种情况下,您的方面必须实施IInstanceScopedAspect
。
[PSerializable]
public class MyAspect : OnMethodBoundaryAspect, IInstanceScopedAspect
{
[ImportMember("QueryProcessor", IsRequired = true)]
public Property<IQueryProcessor> QueryProcessor;
public override void OnEntry(MethodExecutionArgs args)
{
this.QueryProcessor.Get().ExecuteWithCache(/* ... */);
}
object IInstanceScopedAspect.CreateInstance(AdviceArgs adviceArgs)
{
return this.MemberwiseClone();
}
void IInstanceScopedAspect.RuntimeInitializeInstance()
{
}
}