0

I'm trying to implement a PostSharp attribute to check whether a user accessing a certain method is authorised to do so. I had implemented a test solution but with hard coded values like so:

[AuthorisationAspect(RolesEnum.Roles.Admin, RolesEnum.Roles.User]

First parameter describes which role the user should have, the second parameter describes the role of the current user. Like I've mentioned this was just a test. What I'm trying to implement now is the same concept with a few differences. Both parameters are now lists because a method could be accessed by multiple roles and a single user could also have multiple roles. Therefore what I'm trying to achieve is comparing these two lists using PostSharp. I've tried a few different ways to solve it but I'm always getting the same error:

"An attribute argument must be a constant expression , typeof expression or array creation expression of an attribute parameter type."

Solutions I've tried:

First I've tried something like the following, but just like the error describes I can't call methods inside an attribute.

[AuthorisationAspect(GetRoles(), GetUserRoles()]

But then I realised that this is not possible as only static/constant values can be passed as parameters in attributes.

I've also tried using something based on this solution. How to set dynamic value in my Attribute but again it did not even compile.

Finally I've also looked at the following solution http://geekswithblogs.net/abhijeetp/archive/2009/01/10/dynamic-attributes-in-c.aspx, but it looks far too complicated when what I'm trying to do is use AOP which should make things simpler.

Basically I'm trying to pass dynamic parameters in an attribute and passed to a PostSharp attribute but I can't achieve it. I don't know if it's possible, maybe there is a better way to solve this issue. Any help would be appreciated.

Note: The simplest solution would be to call methods to access the database straight from the PostSharp aspect. However, I can't access these methods from the aspect because referencing the class library where the aspects reside would result in a circular dependency. (I'm using 3-tier architecture)

Community
  • 1
  • 1
Daniel Grima
  • 2,765
  • 7
  • 34
  • 58

1 Answers1

1

There is no good way to use not compile time constants as attribute parameters.

You can consider to attack the other issue with circular dependency with a third dll that contains an abstraction (interface or base abstract class or a static wrapper for your implementation) and reference this in both assemblies and use implementation of that abstraction in you aspect.

The other way I've solved this problem is by enclosing the calls to your methods in constructor of derived attribute class:

class DerivedAuthorisationAspect:AuthorisationAspect
{
   public DerivedAuthorisationAspect():base(sth.GetRoles(), sth.GetUserRoles()){}
}

this will work if you can figure out the sth. note that attribute instances are special kinds of classes so your methods can be called multiple times per class.

I would advise the first one even if it is more work to do - it is cleaner.

Rafal
  • 12,391
  • 32
  • 54