使用 PostSharp AOP 授权方法使用
Authorize method usage using PostSharp AOP
我正在使用基于自定义声明的授权来创建一个面板,该面板的功能取决于用户的访问权限。用户声明存储在缓存 ICashClient
中。
特定菜单仅引用某些控制器方法。
问题是:
只需输入特定方法的直接 link 即可使用由于缺少访问权限而不应使用的方法。
我的想法是创建一个方面,以便可以标记这些特定方法,以防止它们在未经允许的情况下被执行。
我想在OnEntry
方法中再次授权。
以下示例允许检查对服务器的请求是否属于 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 的实现。
我知道您需要在您的自定义方面 class 中访问依赖项,并且此依赖项通常使用依赖项注入来解决。在这种特殊情况下,您想要访问 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. Some DI frameworks also allow you to satisfy new object's dependencies after the initial graph has been constructed. You can override 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. When the dependencies are stored in properties or fields of the target object, you can import them using [ImportMember]
advice. Your aspect has to implement 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()
{
}
}
我正在使用基于自定义声明的授权来创建一个面板,该面板的功能取决于用户的访问权限。用户声明存储在缓存 ICashClient
中。
特定菜单仅引用某些控制器方法。
问题是: 只需输入特定方法的直接 link 即可使用由于缺少访问权限而不应使用的方法。
我的想法是创建一个方面,以便可以标记这些特定方法,以防止它们在未经允许的情况下被执行。
我想在OnEntry
方法中再次授权。
以下示例允许检查对服务器的请求是否属于 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 的实现。
我知道您需要在您的自定义方面 class 中访问依赖项,并且此依赖项通常使用依赖项注入来解决。在这种特殊情况下,您想要访问 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. Some DI frameworks also allow you to satisfy new object's dependencies after the initial graph has been constructed. You can override 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. When the dependencies are stored in properties or fields of the target object, you can import them using [ImportMember]
advice. Your aspect has to implement 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()
{
}
}