9

Are there any classes (free, open source or commercial) that perform access control similar to what Java's AccessController does? I want to create a dynamic set of policies that can be changed at runtime.

But, I want to avoid having to code

if Allowed( ... ) then

all over the place. I know that I probably need to adjust my program class hierarchy, but I prefer that instead of manually adding guards all over the place.

If there are is no ready-to-use code, what would be a sensible approach? RTTI?

Edit: Here's an example from the Security Annotations and Authorization in GlassFish and the Java EE 5 SDK article. Since somebody mentioned annotations in a comment, I think this would be ideal:

@Stateless
@RolesAllowed("javaee")
public class HelloEJB implements Hello {
    @PermitAll
    public String hello(String msg) {
        return "Hello, " + msg;
    }

    public String bye(String msg) {
        return "Bye, " + msg;
    }
}

From the article:

In this example, the hello() method is accessible by everyone, and the bye() method is accessible by users of role javaee.

Edit: Well, it appears that the general consensus is that this can't be done in Delphi. Others think it is a bad approach.

Me, I still think this would be great. My experience with Annotations in Java (as a code monkey way down in the totem pole) is positive. You add a new method, you add some form of annotation (not exactly the same as Java Security Annotations) and you are done. An administrator can later go to the admin panel and add grant access to this new handler to a group or individual users. It just works.

These are my current alternatives:

  1. The TMS Security System - this appears like a complete solution, with several tools. Worth looking into. I'm accepting this as an answer even if I'm probably not going for it.
  2. This is something that looks promising: Delphi virtual method interception. It only works on virtual methods, but I don't think that's too difficult to comply. This and annotations could make an interesting system (it appears that this was originally designed for DataSnap authentication)
  3. Having only one ActionManager in your application, and make sure that all actions can be only initiated from there. This way you can use the action manager OnExecute method; I pretend to use the TAction.Name property as the permission name ("handler"), reading a list of allowed actions from a table. I can use the action list from the action manager to display the whole list in the admin UI.
Leonardo Herrera
  • 8,388
  • 5
  • 36
  • 66
  • 1
    I think you can achieve similar functionality by using attributes(don't crucify me if I'm wrong...) here are a couple of links: http://robstechcorner.blogspot.com/2009/09/so-what-is-rtti-rtti-is-acronym-for-run.html http://delphi.about.com/od/oopindelphi/a/delphi-attributes-understanding-using-attributes-in-delphi.htm http://stackoverflow.com/questions/2657502/practical-usage-for-delphis-new-rtti-attributes-values –  Feb 14 '12 at 04:52
  • @DorinDuminica - Can annotations be collected and be put in a list so I can assign them to a specific role? – Leonardo Herrera Feb 16 '12 at 20:54
  • Can you provide a bit of sample code on how the Delphi code should look like? You say you don't want to do `if Allowed(...) then`, but the first Java sample in the linked documentation does `inheritedContext.checkPermission(permission);` - that's about the same in my book. – Cosmin Prund Feb 20 '12 at 06:54
  • @CosminPrund - I've edited my question with an example. – Leonardo Herrera Feb 20 '12 at 14:06

2 Answers2

2

There is no such framework for Delphi yet, nor a concept like EJBs that would fit with it. DELPHI does support class annotations, and a framework like this could be designed, perhaps in conjunction with TAction, to provide security on an action level, but I doubt that this could be extended to blocking specific method calls. Delphi code does not ever ask permission to invoke a virtual method. Anything that injected itself into EVERY virtual method call in Delphi, adding a checkPermission call behind the scenes would (in my opinion) be evil. It would be Slow, and worse than writing such checks in by hand.

However, the same techniques that are used to Mock delphi classes could perhaps be used to create some auto-security wrapper object in the future.

I am guessing that the if the Java library in question used Aspects (essentially "injection" implemented via a technique like code-hooking) then it would not require "CheckAllowed" calls everywhere. If you didn't mind changing all your method invocations to implementing an interface, and then providing a wrapper that did the method invocations, and used some kind of auto-generated mock-security-wrapper around it, you could avoid calls to CheckAllowed.

So a guarded No, with a "limited framework possible in future" clause.

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • I think that manual CheckPermission calls are going to be necessary. If you think about it, TAction.Enable has to be set enabled or disabled, anyways, right? Typically acSaveFile.Enabled would be set to "FileOpen and FileModified and PermissionToSave". So a permission framework that works "automagically" is going to suck hard, in the real world. A 99% solution with a huge overhead. – Warren P Feb 20 '12 at 14:19
  • Probably overloading `SetEnable` would suffice for most cases. My application can go `if FileModified then acSave.Enabled := true` but the permissions manager still can decide not to enable the action. That would be good enough for a while, at least. – Leonardo Herrera Feb 20 '12 at 14:25
  • 1
    I've been down that road before, and in my opinion, explicit calls are better. Cleverness is a rookie solution. Go for explicit calls. – Warren P Feb 20 '12 at 14:31
  • Maybe you are right. But security annotations in Java do work (I'm currently involved in a big project with lots of developers scattered around the globe, and this has proven a brilliant approach.) – Leonardo Herrera Feb 20 '12 at 14:38
  • +1, especially for Warren's comment `"Cleverness is a rookie solution. Go for explicit calls."`. I've implemented similar types of security in my own applications: My protected methods usually have something like this as the first line: `if not SecurityAllowes(Value) then Exit;`. Once you start typing those in, it's no big deal. You probably don't have that many methods to protect, and the protection doesn't need to be all that complicated. – Cosmin Prund Feb 20 '12 at 15:35
  • Yes, I see your point. But I disagree that this is cleverness for cleverness' sake - the Java solution is a really good and practical one. But if it can't be done in Delphi, well, I'll made lemonade or something. – Leonardo Herrera Feb 21 '12 at 14:05
  • Does the Java solution avoid calls in all cases, or just inside the "Work" functions? For example, what about menu item enable/disable logic? Is it magic there too, or you have to write calls to SecurityAllows(Something)? – Warren P Feb 21 '12 at 17:30
  • @WarrenP - in this particular case they are intercepted only at call time. But you can get a list of all security handlers so it should be possible to code a solution to enable/disable UI components at run time. – Leonardo Herrera Mar 12 '12 at 18:47
1

Yes, there is a Delphi Access Control Library (lkacl) (OpenSource), JCL (OpenSource) which offers a pretty comprehensive security features, and finally if your demands would be really high the most popular commercial solution is TMS Security System.

  • This is a "Let Me Google That For You" answer. The first linked project hasn't published any files yet, the `features` you linked mostly specify functions to work with WINDOWS security tokens. The last link (TMS Security System) looks nice, have you used it? – Cosmin Prund Feb 20 '12 at 07:02
  • I guess I wasn't clear in this regard. I'm not looking for ACL wrappers; I don't want my users to need Administrator privileges just to view a sales reports in my application, for example. – Leonardo Herrera Feb 20 '12 at 14:11
  • I actually think that the TMS link is a pretty good answer. It's not using the Fancy Flavor Java Injection pattern, but it's probably better than trying to solve the problem with "Magic". +1. – Warren P Feb 20 '12 at 14:32
  • and jwscl seems to be separate JediAPI-related project rather than oart of JCL :-) – Arioch 'The Aug 22 '12 at 10:56