How do YOU test access control of your application?

Many of complex applications put on top of their complexity access control logic for securing data and to limit access to certain functions. No matter if you have fully configurable ACL settings based on rights or role based access you’d probably want to test this part of application too. In order to have proper test coverage you should make it easy for you and your colleagues to test this. I have no doubts that if you ever needed to test this you already have some kind of such test support, but this article describes what kind of it I’ve created for myself. It might be interesting for you to compare it with your solution or inspire you to create one if you haven’t done it already.

In order to test upper mentioned method properly you should test at least following scenarios:

call method as administrator – should be allowed

call method as organization owner – should be allowed

call method as merchant – should throw AccessDeniedException

call method as unauthorized user – should throw AccessDeniedException

You need to login proper user before test run and log him out on tear down. This could look very ugly because for each of such test you need different user to be logged in so you cannot take advantage of @Before or @BeforeClass annotations.

Extend your test execution lifecycle

In Spring test support you can use so called TestExecutionListener that will be called by framework before / after executing each of the test method. Each callback you can override has access to the TestContext object with reference to the reflection object of the test method and other useful things. Having known that, we could create our own listener that would examine annotations on test method and will take care of logging in a new user and safely cleaning after the test. See example of the test:

Now you got the point – as you can see testing access rights in such way is really easy so you can provide sufficient security coverage. I’ve tried this approach on a year long project consisting of 60k+ lines of code and have had really great experience with it. Now how you to achieve this test behaviour:

Define custom annotation …

… that you’d place on test methods and would mark them to be enveloped by the „logging in“ logic:

Finally

Líbilo se ti? Sdílej:

Související články:

Combining custom annotations for securing methods with Spring Security Spring security is really powerful library in its current version and I like it much. You can secure your application on method level several years now (this feature was introduced by Spring Security 2 in 4/2008) but we’ve upgraded from old Acegi Security only recently. When using method access control in larger scale I started […]...

The secret of Groovy script refresh The first thing one should undestand before he tries to integrate scripting support into his application / framework are class loading issues. One of the main reasons (next to the ability to easily switch from Java) why we have chosen Groovy as our primary scripting language is very good support for live refresh of Groovy […]...

Testing Aspect Pointcuts – is there an easy way? Nice thing about Aspect Oriented Programming is that you can easily add piece of logic to several (possibly other way not connected) parts of your application. You’ll only write an Advice (piece of code that should be weaved into original code and executed at exactly specified point of time) and define Pointcut (an expression defining […]...

Had I nice annotations which you mention in your post I would consider not to write integration tests like these at all (assuming that each annotation is tested on its own) as they would not help me write production code or prevent future bugs. Only way to introduce bug is to miss to add annotation or delete one that’s already there – which is unlikely.

Just a comment: You are setting access rights per role, but test users. IMHO it would be better to test roles. I mean that if your method has attribute @AllowedForAdministrator, I would expect to see something like this in the test: @RunAsRole(UserRoles.ADMINISTRATOR). Let the test runner figure out which user it needs to run the test.

Yes, you’re right. I usually have test user accounts named appropriatelly that represent those roles. So I use such accounts – but you are right it could be based directly on roles and it might make it a little more understandable.