3

I need a gear for custom authorization in business logic classes. It has to be permissions based system, but I can not decide how to apply authorization rules to methods.

My first thought was to apply custom attributes to method

[NeedPermission("Users", PermissionLevel.Read)]
public IList<User> GetAllUsers()
{
     // some code goes here
}

My business logic class has interface, so I can use, for example, Unity Interception behavior and check in runtime if current user has required permissions. And throw an exception if he has not.

But now I'm concerned about reliability of this method.

Usually the reference to business logic class injected by unity container. So there is no problem because it is configured to apply interface interception mechanism.

But what if some developer will instantiate my business logic class directly? Then no interception will be applied and he will be able to call any method even if current user has not permissions to make some actions or even he is not authenticated.

Also somebody can change unity container configuration, turn off Interception extension completly. Again my authorization system will not work.


I saw ASP .NET MVC is using similar mechanism for authorization. Authorization rule is applied only when request came by standard way (IController.Execute). I think this is not a problem in this case because end user of controller (web user) has no way to access controller class directly.

In my case end user of business logic is a programmer who develops front end and he can intentionally or unintentionally screw things - create instance of business logic class and call any methods.

What can you suggest me? How do you deal with this kind of problems?

Thank you.

Tom Kris
  • 1,227
  • 1
  • 8
  • 15

2 Answers2

1

The .NET Framework supports a mechanism for declarative permission verifications that does not depend on Unity interception or other "external" AOP. In order to take advantage of this, your attribute must inherit from System.Security.Permissions.CodeAccessSecurityAttribute. The System.Security.Permissions.PrincipalPermissionAttribute that is included in the BCL is an example of using this mechanism to evaluate user permissions. If it does not suit your needs, there's nothing stopping you from creating your own attribute that does.

Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49
  • Thanks Nicole. This is interesting feature i never heard about. As I understand, I'll also need to create custom IPrincipal implementation which holds not only user name and roles list, but also list of user's permissions. And initialize Thread.CurrentPrincipal somewhere at the top of the stack. – Tom Kris Sep 02 '11 at 03:09
  • I found here http://stackoverflow.com/questions/3585081/custom-codeaccesssecurityattribute that "CAS is deprecated in 4.0". Is it still OK to use CodeAccessSecurityAttribute in 4.0? – Tom Kris Sep 02 '11 at 03:23
  • 1
    The CLR no longer enforces CAS policy for stand-alone applications in .NET 4.0. However, this does not mean that CAS is deprecated. However, even if it were, CodeAccessSecurityAttribute is used as a base class for non-CAS permissions like PrincipalPermission, and would continue to be useable. (Ideally, the CLR should have recognized all SecurityAttribute subclasses for this mechanism, which would avoid the confusion when creating attributes for non-CAS permissions, but we've got to live with what we've got...) – Nicole Calinoiu Sep 02 '11 at 11:31
  • 1
    You don't _have_ to create a custom IPrincipal or assign it to Thread.CurrentPrincipal if the permission created by your attribute can use some alternate mechanism for identifying the current user and/or determining whether the user is permitted a particular permission. That said, sticking to the pattern established in the BCL for PrincipalPermission may help facilitate understanding of the mechanism by maintenance developers. – Nicole Calinoiu Sep 02 '11 at 11:36
  • Yeah, looked for PrincipalPermission implementstion.They had a bit different situation - they can get all information from IPrincipal interface (username and roles list). I think this is better to use custom IPrincipal which holds permissions list in my case. Because otherwise i'll need to somehow inject my PermissionsSource into the Principal object. I don't think this is good idea. – Tom Kris Sep 02 '11 at 17:56
  • In my latest implementation of something similar, I use the IPrincipal for identity only. The custom authorization permission uses a custom authorization provider to determine whether the current user is authorized to perform any given operation. It works well for our target scenario, but ymmv... – Nicole Calinoiu Sep 02 '11 at 19:02
  • @ArtyomKrivokrisenko Are you guys sure that reflection invoking still could run your methods? – AgentFire Oct 16 '12 at 04:30
  • Methods still may be called via reflection. But even in this case security checking is not avoided so everything is fine. – Tom Kris Oct 16 '12 at 04:44
1

If your constructors are internal and your objects instantiated from a factory, a developper won't be able to bypass your security by error.

If someone really, really wants to create your objets without the security, he could still do it using reflection, but this would have be pretty intentional to do so.

Martin
  • 5,954
  • 5
  • 30
  • 46
  • I thought about that. But i'm afraid it will complicate unity container configuration – Tom Kris Sep 02 '11 at 03:17
  • 1
    Looking at: http://www.pnpguidance.net/post/RegisteringFactoryMethodCreateObjectsUnityStaticFactoryExtension.aspx, it might be relaively easy to setup unity with internal constructors. – Martin Sep 02 '11 at 12:33
  • Anyway this is still hard to configure :) – Tom Kris Sep 02 '11 at 17:56