strategy-spring-security-acl Build Status Coverage Status GitHub tag

Extensible strategy-based Spring Security ACL implementation ; available modules are : PermissionEvaluator, JPA Specification and ElasticSearch Filter

How to install : have a look here : Installation

Why ??

 Default [Spring Security ACL][] implementation is database-oriented

[Spring Security ACL][] default implementation uses a persistent model in order to evaluate every permission for any object and SID. Aside performance issues due to a huge ternary table in this model (1 row is 3-tuple { sid ; object weak reference ; permission }), developpers would rather use a more programmatic and object-oriented implementation, without any duplication.

Access Control List is not only a PermissionEvaluator concern

Dealing with Access Control List is not a PermissionEvaluator-only concern. Let's take a CRUD-like standard application :

For read-like methods in JPA and ElasticSearch repositories, Strategy-spring-security-acl provides features able to inject ACL restriction criterias directly inside the repositories.


Strategy-security-acl is an extension of [Spring Security][] which will auto-configure thanks to [Spring Boot][] awesome magic

Extensibility !!

Current bundled features are:

Strategy oriented

  1. ACL strategies are Spring beans
  2. You can create reusable strategies, and apply them to several domain objects, or associate 1 specific strategy for each domain object
  3. Strategies are composite objects wrapping ACL filter implementations dedicated to each supported technology, which are called "feature" :
    • GrantEvaluator, as a typed delegation of [Spring Security][]'s PermissionEvaluator
    • Specification, implementation of [Spring Data JPA][]'s API
    • FilterBuilder, implementation of [Spring Data ElasticSearch][]'s API


Add Github as a maven repository (yes, you can) :


 [Spring Boot][]

Configured beans are automatically loaded by [Spring Boot][]'s magic, as soon jars are in the path. Add required dependencies to your pom (latest version is highest tag created on Github : GitHub tag) :





Then you need very few Spring config:

Now, let's say you have a Customer domain entity in your project, and you need to restrict readable customers, so that only those whose last name is "Smith" can be retrieved.

  1. Define your strategy : let's create an CustomerAclStrategy, which will contain our different ACL features implementations (1 implementation by feature). SimpleAclStrategy implementation is recommended as a start. In your favorite Configuration bean, let's define :
    public SimpleAclStrategy customerStrategy() {
    return new SimpleAclStrategy();
  2. If you are using GrantEvaluator feature, create a CustomerGrantEvaluator bean, and install it inside the CustomerStrategy. Let's add a new bean into Configuration :
    public GrantEvaluator smithFamilyGrantEvaluator(CustomerRepository customerRepository,
      GrantEvaluatorFeature grantEvaluatorFeature) {
    GrantEvaluator smithFamilyGrantEvaluator = new CustomerGrantEvaluator(customerRepository);
    customerStrategy.install(grantEvaluatorFeature, smithFamilyGrantEvaluator);
    return smithFamilyGrantEvaluator;

    And create a dedicated CustomerGrantEvaluator class, it's close to Spring's PermissionEvaluator API :

    import static;

public class CustomerGrantEvaluator extends AbstractGrantEvaluator<Customer, String> {

private CustomerRepository repository;

public CustomerGrantEvaluator(CustomerRepository repository) { super(); this.repository = repository; }

@Override public boolean isGranted(Permission permission, Authentication authentication, Customer domainObject) { return "Smith".equals(domainObject.getLastName()); }

@Override public boolean isGranted(Permission permission, Authentication authentication, String targetId, Class<? extends Customer> targetType) { // thanks to JpaSpecFeature, repository will count only authorized customers ! return repository.count(idEqualTo(targetId)) == 1; } }

3. Add Pre/Post annotations on adequate methods :

@PreAuthorize("hasPermission(#customer, 'SAVE')") ... @PreAuthorize("hasPermission(#customerId, '', 'READ')")

4. If you are using Jpa feature, create a `Specification` bean, and install it inside the `CustomerStrategy`. Let's add this new bean into `Configuration` :

@Bean public Specification smithFamilySpec(JpaSpecFeature jpaSpecFeature) { Specification smithFamilySpec = new Specification() { @Override public Predicate toPredicate(Root root, CriteriaQuery<?> query, CriteriaBuilder cb) { return cb.equal(root.get("lastName"), "Smith"); } }; customerStrategy.install(jpaSpecFeature, smithFamilySpec); return smithFamilySpec; }

5. If you are using ElasticSearch feature, create a `FilterBuilder` bean, and install it inside the `CustomerStrategy`. Let's add this new bean into `Configuration` :

@Bean public TermFilterBuilder smithFamilyFilter(ElasticSearchFeature elasticSearchFeature) { TermFilterBuilder smithFamilyFilter = termFilter("lastName", "Smith"); customerStrategy.install(elasticSearchFeature, smithFamilyFilter); return smithFamilyFilter; }

### Exclude a Spring Data JPA query-method to be filtered with ACL

You just have to put `@NoAcl` annotation on this method in order to avoid the ACL JPA Specification to be injected.

### Override strategies

It may be useful (for tests purpose for example) to disable all domain objects strategies, and use only one (which may be `allowAllStrategy`, so no restriction would be applied). Just add following property in your project's yml/properties file:

strategy-security-acl: override-strategy: allowAllStrategy

### Struggling with integration ?

Have a look at our samples !!

[Spring Boot]:
[Spring Data JPA]:
[Spring Data ElasticSearch]:
[Spring Security]:
[Spring Security ACL]:

### Using JDK 7 ?

Projects using JDK 7 can use artifacts version with suffix "jdk7"