使用PostSharp AOP授权方法使用

时间:2016-12-12 15:20:44

标签: c# aop postsharp

我正在使用基于声明的自定义授权,以便根据用户访问权限创建具有功能的面板。用户声明存储在缓存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的实现。

1 个答案:

答案 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()
    {
    }
}