0

This answer says

"They [attributes] are baked into the assembly at compile-time which has very serious implications of how you could set their properties. Only constant (known at compile time) values are accepted."

...so I'm not sure this is possible:

I want to decorate several methods in my code with attributes that check the role of the current user and only allow execution if the role meets a required minimum.

My attribute so far looks like this:

[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public class PermissionCheckAttribute : Attribute
{
    public PermissionsEnum MinRole { get; set; }
}

I plan to use it like so:

[PermissionCheck(MinRole=PermissionsEnum.Manager)]
public string Foo() 
{
    return "OK"
}

The roles look like this:

public enum PermissionsEnum
{
    Employee: 5
    Manager: 20
    Director: 50
}

My code has a method that always allows me to check the current user and role:

var userRole = GetCurrentUser().Role  // returns Employee[5]

My question is WHERE do I put the code to compare the userRole to the MinRole passed into my Attribute?

Ideally, the return "OK" does not happen if the MinRole is not reached... but do I have to throw in the role comparison code? How do you handle two different code paths conditionally with Attributes?

JacobIRR
  • 8,545
  • 8
  • 39
  • 68
  • Strange question. Obviously, you would need to check the role and the attribute before executing the code to which the role grants permission. Am I missing something? – John Wu Jun 22 '18 at 23:19
  • @JohnWu Do you do that in the method itself? If so, doesn't that just defeat the entire point of using an attribute? If not, where? – JacobIRR Jun 22 '18 at 23:21
  • 1
    Is this in the context of asp.net? If so, you should take a look at using an [authorization filter](https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.1#authorization-filters). – Chris Jun 22 '18 at 23:37
  • The problem is that *nothing* in the current code will ever create an instance of `PermissionCheck` so no code inside `PermissionCheck` will be ever run. You may want to read how to use custom attributes [here](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/accessing-attributes-by-using-reflection). Of course, as @Chris mentioned, in the context of ASP.NET there are special attributes you can use for this purpose – Camilo Terevinto Jun 22 '18 at 23:39
  • 1
    @JacobIRR. For an example, consider the MVC framework, which uses a route map to determine which controller to instantiate and which method to call, all at run time. Before calling the method, the framework will also check for an authorization filter attribute and check it if it exists. So the controller method itself doesn't do the check; the framework does. This is a helpful way to do it in a pluggable architecture like MVC. If you were to instantiate and call a controller directly, it would bypass the check entirely, because the attribute has no effect unless used by code. – John Wu Jun 23 '18 at 01:45
  • @Chris - that's exactly what I needed, thanks. – JacobIRR Jun 25 '18 at 16:59

0 Answers0