Introduction to Spring Security ACL

I just announced the newSpring Security 5 modules (primarily focused on OAuth2) in the course:

1. Introduction

Access Control List (ACL) is a list of permissions attached to an object. An ACL specifies which identities are granted which operations on a given object.

Spring Security Access Control Listis a Spring component which supports Domain Object Security. Simply put, Spring ACL helps in defining permissions for specific user/role on a single domain object – instead of across the board, at the typical per-operation level.

For example, a user with the role Admin can see (READ) and edit (WRITE) all messages on a Central Notice Box, but the normal user only can see messages, relate to them and cannot edit. Meanwhile, others user with the role Editor can see and edit some specific messages.

Hence, different user/role has different permission for each specific object. In this case, Spring ACL is capable of achieving the task. We’ll explore how to set up basic permission checking with Spring ACL in this article.

2. Configuration

2.1. ACL Database

To use Spring Security ACL, we need to create four mandatory tables in our database.

The first table is ACL_CLASS, which store class name of the domain object, columns include:

ID

CLASS: the class name of secured domain objects, for example:org.baeldung.acl.persistence.entity.NoticeMessage

Secondly, we need the ACL_SID table which allows us to universally identify any principle or authority in the system. The table needs:

ID

SID: which is the username or role name. SID stands for Security Identity

PRINCIPAL: 0 or 1, to indicate that the corresponding SID is a principal (user, such as mary, mike, jack…) or an authority (role, such as ROLE_ADMIN, ROLE_USER, ROLE_EDITOR…)

Next table is ACL_OBJECT_IDENTITY, which stores information for each unique domain object:

Hence, we assign AclPermissionEvaluator to the DefaultMethodSecurityExpressionHandler. The evaluator needs a MutableAclService to load permission settings and domain object’s definitions from the database.

As its name, the JdbcMutableAclService uses JDBCTemplate to simplify database access. It needs a DataSource (for JDBCTemplate), LookupStrategy (provides an optimized lookup when querying the database), and an AclCache (caching ACLEntries and Object Identity).

Again, for simplicity, we use provided BasicLookupStrategy and EhCacheBasedAclCache.

After the execution of findAll() method, @PostFilter will be triggered. The required rule hasPermission(filterObject, ‘READ’), means returning only those NoticeMessage which current user has READ permission on.

Similarly, @PostAuthorize is triggered after the execution of findById() method, make sure only return the NoticeMessageobject if the current user has READ permission on it. If not, the system will throw an AccessDeniedException.

On the other side, the system triggers the @PreAuthorize annotation before invoking the save() method. It will decide where the corresponding method is allowed to execute or not. If not, AccessDeniedException will be thrown.

4. In Action

Now we gonna test all those configurations using JUnit. We’ll use H2 database to keep configuration as simple as possible.

Initially, we grant READ and WRITE permissions on the first object (id =1) to the user manager. Meanwhile, any user with ROLE_EDITOR will have READ permission on all three objects but only possess WRITE permission on the third object (id=3). Besides, user hr will have only READ permission on the second object.

Here, because we use default Spring ACLBasePermission class for permission checking, the mask value of the READ permission will be 1, and the mask value of WRITE permission will be 2. Our data in acl_entry will be:

5. Conclusion

We’ve gone through basic configuration and usage of Spring ACL in this article.

As we know, Spring ACL required specific tables for managing object, principle/authority, and permission setting. All interactions with those tables, especially updating action, must go through AclService. We’ll explore this service for basic CRUD actions in a future article.

By default, we are restricted to predefined permission in BasePermission class.

Finally, the implementation of this tutorial can be found over on Github.

I just announced the new Spring Security 5 modules (primarily focused on OAuth2) in the course: